// FieldIOCPSocket2.cpp: implementation of the CFieldIOCPSocket class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FieldIOCPSocket.h"
#include "FieldIOCP.h"
#include "LogWinSocket.h"
#include "FieldServer.h"
#include "FieldGlobal.h"
#include "MonsterDBAccess.h"
#include "FieldMapProject.h"
#include "AtumLogSender.h"
#include "AtumError.h"
#include "FieldParty.h"
#include "GeneralRequestHandler.h"
#include "RacingDemon.h"
#include "MTAutoCriticalSection.h"
#include "AtumTime.h"
//#include "MallAgentConnect.h"			// 2005-11-29 by cmkwon, #include "MGExtMallAuthDll4CP.h"
#include "CouponManager.h"
#include "HappyHourEventManager.h"
#include "FieldODBC.h"
#include "GuildDamageManager.h"
#include "EXPDivisionManager.h"
#include "CallWarpEventManager.h"		// 2006-07-21 by cmkwon
#include "BazaarManager.h"				// 2006-07-26 by cmkwon
#include "SecurityManager.h"			// 2011-06-22 by hskim, 사설 서버 방지
#include "TriggerMapBuffManager.h"		// 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
#include "MapTriggerManager.h"			// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
#include "TriggerFunction.h"			// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템		
#include "StatisticsManager.h"			// 2012-01-16 by hskim, 통계 - 화패



#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1) || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2009-05-27 by cmkwon, Xigncode SDK 2.0으로 업그레이드 - 헤더파일 아래와 같이 변경됨
//#include "zwave_sdk_server.h"			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
//#include "Security\zwave_sdk_linker.h"		// 2009-05-27 by cmkwon, Xigncode SDK 2.0으로 업그레이드 - 
#include "Security\zwave_sdk_helper.h" // 2012-10-13 by jhahn Xigncode 한국 적용
#endif

///////////////////////////////////////////////////////////////////////////////
// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [서비스-필수] 빌링 라이브러리 헤더파일 추가

// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 
//// 2008-07-21 by cmkwon, WinnerOnline_Tha 에 빌링을 마상 빌링 모듈을 적용 - 
//#if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_THAI_SERVER_1)
//	#include "BillingLib.h"					// 2006-09-13 by cmkwon, 
//#endif // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_1

#ifdef SERVICE_TYPE_KOREAN_SERVER_2
#include "AceOnlineSQL.h"				// 2007-09-13 by cmkwon, 예당 빌링 라이브러리 적용 - 헤더 추가
#endif // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_2

// 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 - 
// #ifdef SERVICE_TYPE_ENGLISH_SERVER_1
// 	#include "BOQBillLib4Cowboy.h"			// 2006-06-01 by cmkwon, America Gala-Net billing Library
// #endif // END - #ifdef SERVICE_TYPE_ENGLISH_SERVER_1

// 2009-06-25 by cmkwon, 베트남 VTC 빌링 시스템 수정 - FieldIOCPSocket.h 로 위치 옮김.
//#ifdef SERVICE_TYPE_VIETNAMESE_SERVER_1
//	#include "VTCQuerySC.h"					// 2006-06-07 by cmkwon, Vietnam VTC-Intecom billing Library
//#endif // END - #ifdef SERVICE_TYPE_VIETNAMESE_SERVER_1

#ifdef SERVICE_TYPE_CHINESE_SERVER_1
#include "Billing_Yetime_Chn.h"			// 2007-08-22 by cmkwon, 중국 Yetime 빌링 라이브러리 적용 - 헤더 추가
#endif // END - #ifdef SERVICE_TYPE_CHINESE_SERVER_1

// 2010-11-29 by shcho, 아르헨티나 외부인증 변경 SOAP 처리
#ifdef SERVICE_TYPE_ARGENTINA_SERVER_1
#include "BillCrux_BillingLib.h"		
#endif // END - #ifdef SERVICE_TYPE_ARGENTINA_SERVER_1	  
// end 2010-11-29 by shcho, 아르헨티나 외부인증 변경 SOAP 처리

#include "AllGuildItemManager.h"		// 2006-09-20 by dhjin
#include "GuildItemManager.h"			// 2006-09-20 by dhjin
#include "PCBangIPManager.h"			// 2007-08-07 by dhjin
#include "md5_lib_src.h"				// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 -

// 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템
//적당한 위치에 컴포넌트를 임포트 한다.
#ifdef S_BPSOFTBILLING_JHSEOL
#import "../../Lib/BPSOFT/BCARTPURCHASE_COM.dll" no_namespace
#include <atlbase.h>
#endif

//형변환 함수 정의
#define BUFFSIZE 1024
#define WTOM(wstr, mstr ) WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)(wstr), -1, (mstr), BUFFSIZE, NULL, NULL )
#define MTOW(mstr, wstr, n ) MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS, (mstr), (n), (wstr), BUFFSIZE/2 )
/********************************************************
BPSoft 빌링시스템 적용 시 에러 해결방법 by jhseol

VS6.0 환경에서 다음과 같은 에러발생시 해결방법

  case.1 --> error C2065: 'CoInitializeEx' : undeclared identifier
	solution : 메뉴-> Project Settings -> C/C++ tab에서 Preprocessor definitions에 _WIN32_DCOM 를 추가 하면 된다.


  case.2 --> error C2065: 'CComPtr' : undeclared identifier
	solution : #include <atlbase.h> 추가


  case.3 --> error C2664: 'WideCharToMultiByte' : cannot convert parameter 3 from 'long' to 'const unsigned short *'
	solution : 기존 매크로 함수에서 캐스팅 지원이 안되는 현상임으로 매크로 수정
			before	- #define WTOM(wstr, mstr ) WideCharToMultiByte( CP_ACP, 0,			 (wstr), -1, (mstr), BUFFSIZE, NULL, NULL )
			after	- #define WTOM(wstr, mstr ) WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)(wstr), -1, (mstr), BUFFSIZE, NULL, NULL )
********************************************************/

#define BPSOFT_MEMBERSHIP_CODE			"MASANG"
#define BPSOFT_CINTENS_NO				1
#define BPSOFT_SITE_NO					1
#define BPSOFT_SITE_NO_MUNPIA			2		// 2014-02-10 by jhseol&bckim, 체널링 - 빌링 연동
#define BPSOFT_METHOD_CALL_NO_ERRER		"0000"
#define BPSOFT_TEST_USER_NO				"321"
#define BPSOFT_TEST_USER_ID				"bey2207"
#define BPSOFT_ITEM_AMOUNT				1		// 캐쉬 아아템은 1게씩만 판매 하고 있다.
// end 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_GET_ITEMINFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize = 0;
	MSG_FC_SHOP_GET_ITEMINFO			*pGetItemInfo = NULL;
	BYTE								SendBuf[SIZE_MAX_PACKET];

	nRecvTypeSize = sizeof(MSG_FC_SHOP_GET_ITEMINFO);

	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_SHOP_GET_ITEMINFO, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14040);
		return RES_RETURN_FALSE;
	}

	pGetItemInfo = (MSG_FC_SHOP_GET_ITEMINFO*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	*(MessageType_t*)SendBuf = T_FC_SHOP_GET_ITEMINFO_OK;
	MSG_FC_SHOP_GET_ITEMINFO_OK *pGetItemInfoOK
		= (MSG_FC_SHOP_GET_ITEMINFO_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
	pGetItemInfoOK->ItemInfo = *(ms_pFieldIOCP->GetItemInfo(pGetItemInfo->ItemNum));

	SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_GET_ITEMINFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_BUY_ITEM,
									MSG_FC_SHOP_BUY_ITEM, pBuyItem);
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}

	if(INVALID_UNIQUE_NUMBER != m_peerTraderCharacterUniqueNumber
		&& 0 != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_BUY_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}

	if(pBuyItem->Amount <= 0)
	{
		
		char szSystemLog[512];
		sprintf(szSystemLog, "[ERROR] Shop Buy Item Error, Char(%15s) ItemNum(%8d) ItemAmoun(%8d)\r\n"
			, m_character.CharacterName, pBuyItem->ItemNum, pBuyItem->Amount);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);

		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0070);
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pBuyItem->Amount);
		return RES_RETURN_FALSE;
	}

	map<UINT, CShopInfo*>::iterator itr
		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(pBuyItem->BuildingIndex);
	if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_RETURN_FALSE;
	}
	CShopInfo *pShop = itr->second;

// 2006-10-20 by cmkwon, 상점 아이템 리스트 컨테이너 변경, 아래와 같이 수정함
//	map<UINT, SHOP_ITEM>::iterator itr_item	= pShop->m_mapShopItem.find(pBuyItem->ItemNum);
//	if (itr_item == pShop->m_mapShopItem.end())
//	{
//		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, pBuyItem->ItemNum);
//		return RES_RETURN_FALSE;
//	}
//	SHOP_ITEM *pShopItem = &itr_item->second;
	SHOP_ITEM *pShopItem = pShop->GetSHOP_ITEMPtr(pBuyItem->ItemNum);
	if (NULL == pShopItem)
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, pBuyItem->ItemNum);
		return RES_RETURN_FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-08 by cmkwon, 세금처리
	float	fTotalTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	int		nTotalTexSPI		= 0;

// 2006-02-08 by cmkwon, 도시점령전 사용하지 않음
//	///////////////////////////////////////////////////////////////////////////////
//	// 도시점령전 세금 처리
//	float	fCityWarTexPercent	= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pBuyItem->BuildingIndex, m_character.GuildUniqueNumber);
//	int		nCityWarTex			= 0;

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);			// lock m_mapItemGeneral, MSG_FC_SHOP_BUY_ITEM
	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(pMoney == NULL)
	{// check:
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
// 2006-10-23 by cmkwon, 아래의 SendErrorMessage()로 수정함 
//		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0070);
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, MONEY_ITEM_NUMBER);
		return RES_BREAK;
	}

	// 아이템 요구 조건 확인, check: 일단은 skill인 경우만 확인함
	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pBuyItem->ItemNum);
	if (pItemInfo == NULL)
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pBuyItem->ItemNum);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_SHOP_BUY_ITEM, 필드창고 이용권 아이템 구매가능여부  체크
	if(pItemInfo->IsExistDesParam(DES_FIELD_STORE)
		&& this->m_ItemManager.IsUseableFieldStore())
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_CANNOT_BUY_ITEM, pItemInfo->ItemNum, this->m_ItemManager.IsUseableFieldStore());
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 최대 개수 확인
	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 인자 변경
	if(IS_COUNTABLE_ITEM(pItemInfo->Kind))
	{// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인

		ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyItem->ItemNum);
		if (NULL == pItemGeneralInven
			&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
		{
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
	}
	else if(IS_GENERAL_ITEM(pItemInfo->Kind))
	{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 아래와 같이 체크 수정

		pBuyItem->Amount = min(pBuyItem->Amount, MAX_ITEM_COUNTS_FOR_BUY);		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 최대 구입 가능 개수 설정.

		if(m_ItemManager.GetInventoryItemCounts() + pBuyItem->Amount > m_ItemManager.GetMaxInventoryCount())
		{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
	}
// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 위와 같이 수정 함.
// 	else if (m_ItemManager.GetInventoryItemCounts() >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))
// 	{// 카운터블이 아닐 경우 최대 개수 확인
// 
// 		if(FALSE == IS_SKILL_ITEM(pItemInfo->Kind))
// 		{// 2007-01-30 by cmkwon, 스킬은 인벤토리 개수를 체크하지 않는다
// 			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()));
// 			return RES_BREAK;
// 		}
// 	}
	

	///////////////////////////////////////////////////////////////////////////////
	// 2005-09-13 by cmkwon, 카운터블 아이템일 경우 최대(20억) 카운트 체크
	if(IS_COUNTABLE_ITEM(pItemInfo->Kind))
	{
		INT64 tmCurrentCount = pBuyItem->Amount;

		ITEM_GENERAL *pMyItem = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyItem->ItemNum);
		if(pMyItem){				tmCurrentCount += pMyItem->CurrentCount;}
		if(tmCurrentCount > MAX_ITEM_COUNTS)
		{
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, 0, 0);
			return RES_BREAK;			
		}
		else if(tmCurrentCount >= MAX_NOTIFY_ITEM_COUNTS)
		{
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER);
		}
	}	

	if (IS_GENERAL_ITEM(pItemInfo->Kind) 
		&& FALSE == IS_SKILL_ITEM(pItemInfo->Kind)			// 2007-01-30 by cmkwon, 스킬은 인벤토리 개수를 체크하지 않는다
		&& FALSE == IS_COUNTABLE_ITEM(pItemInfo->Kind))
	{
		if(timeGetTime()-m_dwLastTickInsertingStoreItem > 5000)
		{
			m_nInsertingStoreItemCounts = 0;
		}

		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 
		//if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))
		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
		if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts + pBuyItem->Amount > m_ItemManager.GetMaxInventoryCount())
		{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, 1);
			return RES_BREAK;
		}		
	}

	if (COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM))
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
//	// 무게 확인
//	if (pItemInfo->Weight > 0.0f)
//	{
//		float fItemWeight = CAtumSJ::GetItemWeight(pItemInfo, pBuyItem->Amount);
//		if (GetCurrentLoadagePercentage(fItemWeight) > 1.0f)
//		{
//			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_ITEM_OVER_WEIGHT,
//								(INT)m_ItemManager.GetCurrentCarryingItemWeight()+fItemWeight,
//								(INT)CAtumSJ::GetTransport(&m_character));
//			return RES_BREAK;
//		}
//	}

	// 최소 거래 단위 확인: MinTradeQuantity의 배수로만 구매 할 수 있음
	if ( pBuyItem->Amount%pItemInfo->MinTradeQuantity != 0)
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pItemInfo->MinTradeQuantity);
		return RES_BREAK;
	}

	// 스킬 구매 시 LinkItem이 필요한 경우, 삭제될 LinkItemNum
	int nDeleteLinkItemNum = 0;

	if (IS_SKILL_ITEM(pItemInfo->Kind))
	{
		Err_t tmpErr = CheckSkillItemRequirements(pItemInfo);
		if (tmpErr != ERR_NO_ERROR)
		{
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, tmpErr);
			return RES_BREAK;
		}

		if(IS_BAZAAR_SKILL(pItemInfo)
			&& COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
		{// 2006-08-08 by cmkwon, 일반세력은 개인상점스킬 구입 불가
			SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
			return RES_BREAK;
		}

		// 이미 해당 스킬을 가진 경우 ERR_PROTOCOL_ALREADY_HAVE_SKILL를 보냄
		// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		ITEM_SKILL *pOldItemSkill = m_ItemManager.GetFirstSkillBySkillBaseNum(pItemInfo->NextSkill);
		if (pOldItemSkill != NULL)
		{
			if (pOldItemSkill->ItemInfo->SkillLevel >= pItemInfo->SkillLevel)
			{
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0071);
				SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED);		// 2006-10-23 by cmkwon
				return RES_BREAK;
			}
		}
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		ITEM_SKILL *pOldItemSkill = m_ItemManager.GetFirstSkillBySkillBaseNum(pItemInfo->ItemNum);
		if (pOldItemSkill != NULL)
		{
			if (SKILL_LEVEL(pOldItemSkill->ItemNum) >= SKILL_LEVEL(pItemInfo->ItemNum))
			{
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0071);
				SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED);		// 2006-10-23 by cmkwon
				return RES_BREAK;
			}
		}
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정

		// 스킬의 LinkItem 확인
		if (pItemInfo->LinkItem != 0)
		{
			ITEM *pTmpLinkItemInfo = ms_pFieldIOCP->GetItemInfo(pItemInfo->LinkItem);
			if (pTmpLinkItemInfo == NULL)
			{
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0072);
				SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED);		// 2006-10-23 by cmkwon
				return RES_BREAK;
			}

			if (m_ItemManager.GetFirstItemGeneralByItemNum(pItemInfo->LinkItem) == NULL)
			{
				SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_DO_NOT_HAVE_LINK_ITEM, pTmpLinkItemInfo->ItemNum, 0, pTmpLinkItemInfo->ItemName);
				return RES_BREAK;
			}

			nDeleteLinkItemNum = pItemInfo->LinkItem;
		}
	}

	// 돈 확인
	if (pMoney == 0)
	{
		// error
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	INT64 n64SumOfPrice	= pShopItem->Price;
	n64SumOfPrice		*= (pBuyItem->Amount/pItemInfo->MinTradeQuantity);

	// 2013-08-12 by bckim, 신규해피아워
	float ftempSPIDiscountRate = 0.0f;	
#ifdef SC_RENEWER_HAPPY_HOUR_BHSOHN_BCKIM		//	Process_FC_SHOP_BUY_ITEM
	ftempSPIDiscountRate = ms_pFieldIOCP->m_gameEventManager.GetSPIDiscountRate(m_character.InfluenceType,this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
#endif
	//nTotalTexSPI		= CAtumSJ::GetItemTexSPI(n64SumOfPrice, fTotalTexPercent);
	//n64SumOfPrice		+= nTotalTexSPI;
	n64SumOfPrice		= CAtumSJ::GetItemSPIPrice(n64SumOfPrice, fTotalTexPercent,ftempSPIDiscountRate);		// 클라이언트에서 만든 함수 사용하기로 함 
	// End. 2013-08-12 by bckim, 신규해피아워

	INT64 n64LogSpend = n64SumOfPrice;	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	if (n64SumOfPrice > pMoney->CurrentCount)
	{
		// error
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	// 소유한 상점인지 확인
	UID32_t ShopOwnerUID = pShop->GetShopOwner();
	if( ShopOwnerUID != 0 && ShopOwnerUID != m_character.CharacterUniqueNumber )
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_NOT_OWNER_SHOP);
		return RES_BREAK;
	}

	// 구입 가능 갯수 확인
	if( FALSE == pShopItem->IsAvailableShopItem(pBuyItem->Amount) )
	{
		SendErrorMessage(T_FC_SHOP_BUY_ITEM, ERR_INSUFFICIENT_NUMBER_SHOP_ITEM);

		return RES_BREAK;
	}
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	if (IS_SKILL_ITEM(pItemInfo->Kind))
	{
		// 스킬 아이템은 무조건 하나씩

		// 아이템 삽입
		m_ItemManager.InsertItemBaseByItemNum(pItemInfo->ItemNum, 1, IUT_SHOP);

		// 돈 삭제
		m_ItemManager.UpdateItemCountByPointer(pMoney, -n64SumOfPrice, IUT_SHOP);

		if (nDeleteLinkItemNum != 0)
		{
			m_ItemManager.DeleteItemFromCharacterByItemNum(nDeleteLinkItemNum, 1, IUT_SHOP);
		}
	}
	else
	{
		// skill 이외의 일반 아이템인 경우

		// 아이템 삽입
		m_ItemManager.InsertItemBaseByItemNum(pItemInfo->ItemNum, pBuyItem->Amount, IUT_SHOP);

		// 돈 삭제
		m_ItemManager.UpdateItemCountByPointer(pMoney, -n64SumOfPrice, IUT_SHOP);

		// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
		if( TRUE == pShopItem->IsLimitedEditionShopItem() )
		{
			pShopItem->RemainCountForLimitedEdition -= pBuyItem->Amount;

			SHOP_ITEM *pShopItemBuffer = pShop->GetSHOP_ITEMPtrFrombuffer(pShopItem->ItemNum);
			if( NULL != pShopItemBuffer )
			{
				pShopItemBuffer->RemainCountForLimitedEdition -= pBuyItem->Amount;
			}

			INIT_MSG_OF_SIZE(MSG_FC_SHOP_BUY_ITEM_UPDATE, T_FC_SHOP_BUY_ITEM_UPDATE, pBuyUpdateInfo, SendBuf);
			pBuyUpdateInfo->BuildingIndex = pBuyItem->BuildingIndex;
			pBuyUpdateInfo->ItemNum = pItemInfo->ItemNum;
			pBuyUpdateInfo->RemainCountForLimitedEdition = pShopItemBuffer->RemainCountForLimitedEdition;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_BUY_ITEM_UPDATE));
		}
		// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	}

	// send log
	ITEM_GENERAL tmpItemForLog(pItemInfo);
	tmpItemForLog.UniqueNumber			= 0;
	tmpItemForLog.AccountUniqueNumber	= m_character.AccountUniqueNumber;
	tmpItemForLog.Possess				= m_character.CharacterUniqueNumber;
	tmpItemForLog.Wear					= WEAR_NOT_ATTACHED;
	tmpItemForLog.CurrentCount			= pBuyItem->Amount;
// 2009-08-25 by cmkwon, 사용하지 않는 필드 제거(td_Store.ScarcityNumber) - 
//	tmpItemForLog.ScarcityNumber		= 0;
	tmpItemForLog.ItemWindowIndex		= POS_INVALID_POSITION;
	tmpItemForLog.PrefixCodeNum			= 0;
	tmpItemForLog.SuffixCodeNum			= 0;
	tmpItemForLog.NumOfEnchants			= 0;
	CAtumLogSender::SendLogMessageITEMBuyITEM(this, &tmpItemForLog, pBuyItem->Amount, pMoney->CurrentCount);

	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	//enum ITEM_BUY_CASH_PRICE_TYPE{BUY_TYPE_SPI=1,BUY_TYPE_WARPOINT,BUY_TYPE_CASH,BUY_TYPE_INFINITY};
	CAtumLogSender::SendLogMessageITEMBuyCashPrice(this, &tmpItemForLog, pBuyItem->Amount, n64LogSpend, FALSE, BUY_TYPE_SPI, NULL); // SPI TYPE : 1
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	igLock.auto_unlock_cancel();

	// 2007-08-27 by dhjin, 판공비 처리
	this->SetExpediencyFundW(m_character.InfluenceType, n64SumOfPrice);

// 2006-02-08 by cmkwon, 도시점령전 사용하지 않음
//	if(nCityWarTex > 0)
//	{
//		m_pCurrentFieldMapChannel->CityWarAddTex(nCityWarTex);
//	}
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_GET_USED_ITEM_PRICE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_GET_USED_ITEM_PRICE,
									MSG_FC_SHOP_GET_USED_ITEM_PRICE, pMsgGetUsedItemPrice);

	
	// lock m_mapItemGeneral, MSG_FC_SHOP_GET_USED_ITEM_PRICE
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pItem = m_ItemManager.GetItemGeneralByUID(pMsgGetUsedItemPrice->ItemUniqueNumber);
	if (pItem == NULL)
	{
		SendErrorMessage(T_FC_SHOP_GET_USED_ITEM_PRICE, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItem->ItemInfo;

	if (pMsgGetUsedItemPrice->Amount%pItemInfo->MinTradeQuantity != 0)
	{
		SendErrorMessage(T_FC_SHOP_GET_USED_ITEM_PRICE, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pItemInfo->MinTradeQuantity);
		return RES_BREAK;
	}

	INIT_MSG_OF_SIZE(MSG_FC_SHOP_GET_USED_ITEM_PRICE_OK, T_FC_SHOP_GET_USED_ITEM_PRICE_OK, pMsgGetUsedItemPriceOK, SendBuf);
	pMsgGetUsedItemPriceOK->ItemUniqueNumber = pItem->UniqueNumber;
	pMsgGetUsedItemPriceOK->Price
		= (UINT)(pItemInfo->Price * CAtumSJ::GetItemSellingPriceRate() * (pMsgGetUsedItemPrice->Amount/pItemInfo->MinTradeQuantity));	// 매입가 계산
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_GET_USED_ITEM_PRICE_OK));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_GET_SHOP_ITEM_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_GET_SHOP_ITEM_LIST,
									MSG_FC_SHOP_GET_SHOP_ITEM_LIST, pMsgGetList);

	if (m_pCurrentBuildingNPC == NULL)
	{
		SendErrorMessage(T_FC_SHOP_GET_SHOP_ITEM_LIST, ERR_PROTOCOL_NO_SUCH_SHOP, pMsgGetList->BuildingIndex);
		return RES_BREAK;
	}

	if (m_pCurrentBuildingNPC != NULL
		&& m_pCurrentBuildingNPC->BuildingIndex != pMsgGetList->BuildingIndex)
	{
		SendErrorMessage(T_FC_SHOP_GET_SHOP_ITEM_LIST, ERR_PROTOCOL_NO_SUCH_SHOP, pMsgGetList->BuildingIndex);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-01-10 by cmkwon, 
	if(BUILDINGKIND_CASH_SHOP == m_pCurrentBuildingNPC->BuildingKind
		&& FALSE == g_pFieldGlobal->m_bCashShopServiceFlag
		&& FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
	{// 2007-01-10 by cmkwon, 유료화 상점 지원 체크 - 관리자/운영자는 상관 없음
		SendErrorMessage(T_FC_SHOP_GET_SHOP_ITEM_LIST, ERR_CASH_CASH_SHOP_NO_SERVICE, 0, 0, NULL, FALSE, FALSE);
		return RES_BREAK;
	}

	ResetCashAuthenticationKey();		// 2013-03-13 by hskim, 웹 캐시 상점

	switch (m_pCurrentBuildingNPC->BuildingKind)
	{
	case BUILDINGKIND_1ST_WEAPONSHOP:
	case BUILDINGKIND_2ND_WEAPONSHOP:
	case BUILDINGKIND_COMPONENTSHOP:
	case BUILDINGKIND_PETSHOP:
	case BUILDINGKIND_ANTIQUESHOP:
	case BUILDINGKIND_PUBLICOFFICE:
	case BUILDINGKIND_ACTIONHOUSE:
	case BUILDINGKIND_RACETRACK:
	case BUILDINGKIND_REFINERY:
	case BUILDINGKIND_MILITARYACADEMY:
	case BUILDINGKIND_SKILL_SHOP:
	case BUILDINGKIND_CASH_SHOP:
	case BUILDINGKIND_WARPOINT_SHOP:
	case BUILDINGKIND_TRIGGER_CRYSTAL:	// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	case BUILDINGKIND_PARTSSHOP:		// 2012-02-29 by hskim, 상점 타이틀 넣기 - 파츠상점
	case BUILDINGKIND_GEARSHOP:			// 2012-02-29 by hskim, 상점 타이틀 넣기 - 기어상점
	case BUILDINGKIND_CARDSHOP:			// 2012-02-29 by hskim, 상점 타이틀 넣기 - 카드상점
		{
			if(BUILDINGKIND_CASH_SHOP == m_pCurrentBuildingNPC->BuildingKind)
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - T_FC_SHOP_GET_SHOP_ITEM_LIST, 한정판매 아이템 리스트 업데이트
				ms_pFieldIOCP->LimitedEUpdateShopItemW(pMsgGetList->BuildingIndex, this->GetCurrentFieldMapProject());				

				// 2013-03-13 by hskim, 웹 캐시 상점
#ifdef S_WEB_CASHSHOP_SERVER_MODULE_HSKIM
				GenCashAuthenticationKey();

				INIT_MSG_OF_SIZE(MSG_FC_SHOP_AUTH_KEY, T_FC_SHOP_AUTH_KEY, pAuthKeyMsg, SendBuf);
				STRNCPY_MEMSET(pAuthKeyMsg->AuthenticationKey, GetCashAuthenticationKey(), sizeof(pAuthKeyMsg->AuthenticationKey));
				pAuthKeyMsg->ServerID = g_pGlobalGameServer->GetMGameServerID();
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_AUTH_KEY));
#endif
				// end 2013-03-13 by hskim, 웹 캐시 상점
			}

			map<UINT, CShopInfo*>::iterator itr
				=  m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(pMsgGetList->BuildingIndex);
			if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
			{
				SendErrorMessage(T_FC_SHOP_GET_SHOP_ITEM_LIST, ERR_PROTOCOL_NO_SUCH_SHOP, pMsgGetList->BuildingIndex);
				return RES_BREAK;
			}

			BYTE *buf = (BYTE*)itr->second->m_buffer.ptr;
			int size = itr->second->m_buffer.size;
			int offset = 0;

			// send MSG_FC_SHOP_PUT_ITEM_HEADER
			SendAddData(buf + offset, MSG_SIZE(MSG_FC_SHOP_PUT_ITEM_HEADER));
			offset +=  MSG_SIZE(MSG_FC_SHOP_PUT_ITEM_HEADER);

			// send MSG_FC_SHOP_PUT_ITEM
			BYTE *msgStartPoint;
			MessageType_t Type;

			while(TRUE)
			{
				msgStartPoint = buf + offset;

				Type = *(MessageType_t*)(buf + offset);
				offset += SIZE_FIELD_TYPE_HEADER;

				if (Type == T_FC_SHOP_PUT_ITEM)
				{
					MSG_FC_SHOP_PUT_ITEM *pPutItem = (MSG_FC_SHOP_PUT_ITEM*)(buf + offset);
					offset += sizeof(MSG_FC_SHOP_PUT_ITEM);
					assert(pPutItem->BytesToRead < SIZE_MAX_PACKET);

					SendAddData(msgStartPoint, MSG_SIZE(MSG_FC_SHOP_PUT_ITEM) + pPutItem->BytesToRead);
					offset += pPutItem->BytesToRead;
				}
				else if (Type == T_FC_SHOP_PUT_ITEM_DONE)
				{
					break;
				}
				else
				{
					ASSERT_NEVER_GET_HERE();
				}
			}

			// send MSG_FC_SHOP_PUT_ITEM_DONE
			assert(Type==T_FC_SHOP_PUT_ITEM_DONE);
			SendAddData(msgStartPoint, MSG_SIZE(MSG_FC_SHOP_PUT_ITEM_DONE));
			offset += sizeof(MSG_FC_SHOP_PUT_ITEM_DONE);

			assert(size== offset);
		}
		break;
	case BUILDINGKIND_CITYWARP:
	case BUILDINGKIND_LABORATORY:
	case BUILDINGKIND_FACTORY:
	case BUILDINGKIND_STORE:
	case BUILDINGKIND_AUCTION:
	case BUILDINGKIND_ARENA:
	case BUILDINGKIND_TUNING_COLOR:		// 2005-11-11 by cmkwon, 추가함
	case BUILDINGKIND_BRIEFING_ROOM:	// 2007-07-16 by dhjin
	case BUILDINGKIND_TUTORIAL:			// 2007-07-16 by dhjin
	case BUILDINGKIND_CITYLEADER_LEADER:		// 2007-08-27 by dhjin
	case BUILDINGKIND_CITYLEADER_OUTPOST:		// 2007-08-27 by dhjin
	case BUILDINGKIND_LUCKY:			// 2008-11-04 by dhjin, 럭키머신
	case BUILDINGKIND_WORLDRANKING:		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	case BUILDINGKIND_INFINITY:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	case BUILDINGKIND_LUCKY_OPTION_MACHINE:			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	case BUILDINGKIND_MYSTERY_SHOP:			// 2012-07-09 by hskim, 미스터리 머신 구현
		{
			// do nothing
		}
		break;
	case BUILDINGKIND_INFINITY_SHOP:	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 상점
		{
			BYTE SendBuf[SIZE_MAX_PACKET];
			int			nSendBytes		= 0;
			*(MessageType_t*)(SendBuf)	= T_FC_SHOP_INFINITY_ITEM_HEADER;
			nSendBytes					= SIZE_FIELD_TYPE_HEADER;
			
			vectorInfinityShopInfo::iterator itrInfinityInfo = this->ms_pFieldIOCP->m_InfinityShopInfoList.begin();
			for (; itrInfinityInfo != this->ms_pFieldIOCP->m_InfinityShopInfoList.end(); itrInfinityInfo++) {
				if(nSendBytes + MSG_SIZE(MSG_FC_SHOP_INFINITY_ITEM) > SIZE_MAX_PACKET) {
					this->SendAddData(SendBuf, nSendBytes);
					nSendBytes					= 0;
				}
				
				*((MessageType_t*)(SendBuf + nSendBytes))	= T_FC_SHOP_INFINITY_ITEM;
				nSendBytes									+= SIZE_FIELD_TYPE_HEADER;
				MSG_FC_SHOP_INFINITY_ITEM *pRMsg			= (MSG_FC_SHOP_INFINITY_ITEM*)(SendBuf + nSendBytes);
				*pRMsg										= *itrInfinityInfo;
				nSendBytes									+= sizeof(MSG_FC_SHOP_INFINITY_ITEM);
			}
			
			if(nSendBytes > 0) {
				this->SendAddData(SendBuf, nSendBytes);
				nSendBytes						= 0;
			}
			
			this->SendAddMessageType(T_FC_SHOP_INFINITY_ITEM_DONE);	
		}
		break;
	case BUILDINGKIND_DISSOLUTION:		// 2010-08-31 by shcho&jskim 아이템용해 시스템 - 
		{
			// do nothing
		}
		break;
	// 2013-05-09 by hskim, 세력 포인트 개선
	case BUILDINGKIND_INFLBUFF_SHOP:
		{
			// do nothing
		}
		break;
	// 2013-05-09 by hskim, 세력 포인트 개선
	default:
		{
			SendErrorMessage (T_FC_EVENT_ENTER_BUILDING, ERR_PROTOCOL_NO_SUCH_SHOP, m_pCurrentBuildingNPC->BuildingKind);
			return RES_BREAK;
		}
		break;
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_SELL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_SELL_ITEM,
									MSG_FC_SHOP_SELL_ITEM, pMsgSellItem);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_SELL_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_SHOP_SELL_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(pMoney == NULL)
	{	// check:
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0073);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemToSell = m_ItemManager.GetItemGeneralByUID(pMsgSellItem->ItemUniqueNumber);
	if (pItemToSell == NULL)
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgSellItem->ItemUniqueNumber);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_SHOP_SELL_ITEM
	if(pItemToSell->Kind != pMsgSellItem->ItemKind
		|| pItemToSell->UniqueNumber != pMsgSellItem->ItemUniqueNumber
		|| pItemToSell->Possess != GetCharacter()->CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d, %d %d\r\n"
			, GetProtocolTypeString(T_FC_SHOP_SELL_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemToSell, string()), pItemToSell->Possess, pMsgSellItem->ItemUniqueNumber, pItemToSell->Kind, pMsgSellItem->ItemKind);
		return RES_BREAK;
	}

	// 2008-02-19 by cmkwon, 장착된 아이템은 상점에 판매 불가 - 
	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - 
	//if(SIZE_MAX_POS > pItemToSell->ItemWindowIndex)
	if(IS_ATTACHABLE_POSITION(pItemToSell->ItemWindowIndex))
	{		
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_CANNOT_UNWEAR_ARMOR, pItemToSell->ItemNum, pItemToSell->ItemWindowIndex);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemToSell->ItemInfo;
	if (pItemToSell->Kind != pMsgSellItem->ItemKind)
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemToSell->Kind, pMsgSellItem->ItemKind);
		return RES_BREAK;
	}

	if (COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER))
	{
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if(ITEMKIND_ACCESSORY_TIMELIMIT == pItemToSell->Kind
		&& pItemToSell->UsingTimeStamp != ITEM_NOT_USING)
	{// 2006-06-16 by cmkwon, 이미 사용 시작된 아이템은 상점에 판매/거래/창고로 이동 불가
		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1, 0);
		return RES_BREAK;
	}


	// check: 나머지는 버림, 20040913, kelovon
//	// 최소 거래 단위 확인: MinTradeQuantity의 배수로만 팔 수 있음
//	if ( pMsgSellItem->Amount%pItemInfo->MinTradeQuantity != 0)
//	{
//		SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pItemInfo->MinTradeQuantity);
//		return RES_BREAK;
//	}

	if (IS_COUNTABLE_ITEM(pItemToSell->Kind))
	{
		if (pItemToSell->CurrentCount < pMsgSellItem->Amount)
		{
			SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
			return RES_BREAK;
		}

		int nIncomingMoney = (int)(pItemInfo->Price * CAtumSJ::GetItemSellingPriceRate())
							* (pMsgSellItem->Amount/pItemInfo->MinTradeQuantity);

		// send log
		CAtumLogSender::SendLogMessageITEMSellITEM(this,
				pItemToSell, pMsgSellItem->Amount,
				pMoney->CurrentCount + nIncomingMoney);	// 아이템 상점에 판매

		m_ItemManager.UpdateItemCountByPointer(pItemToSell, -pMsgSellItem->Amount, IUT_SHOP);
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, nIncomingMoney, IUT_SHOP);
	}
	else
	{
		if (pMsgSellItem->Amount != 1)
		{
			SendErrorMessage(T_FC_SHOP_SELL_ITEM, ERR_PROTOCOL_INVALID_ITEM_COUNT, pMsgSellItem->Amount);
			return RES_BREAK;
		}

		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 상점 판매
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 아이템 상점 판매
		if ( ITEMKIND_DEFENSE == pItemToSell->Kind && SHAPE_STAT_INIT_LEVEL < pItemToSell->FixedTermShape.nStatLevel )
		{
			m_ArmorCollection.ChangeActivedCount(pItemToSell->ShapeItemNum, FALSE);
		}
#endif
		// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 상점 판매

		///////////////////////////////////////////////////////////////////////////////
		// 2007-07-20 by cmkwon, 판매아이템 로그 추가 - 인챈트 리스트 가져오기
		vectENCHANT tmvectEnchant;
		this->PopAllEnchantByItemUID(&tmvectEnchant, pItemToSell->UniqueNumber);

		// send log
		CAtumLogSender::SendLogMessageITEMSellITEM(this,
				pItemToSell, 1,
				pMoney->CurrentCount + pItemInfo->Price * CAtumSJ::GetItemSellingPriceRate(), &tmvectEnchant);	// 2007-07-20 by cmkwon, 판매아이템 로그 추가 - 인챈트 리스트 정보 인자로 넘기기, // 아이템 상점에 판매

		m_ItemManager.DeleteItemFromCharacterByUID(pMsgSellItem->ItemUniqueNumber, IUT_SHOP);
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, pItemInfo->Price * CAtumSJ::GetItemSellingPriceRate(), IUT_SHOP);
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SHOP_REQUEST_REPAIR(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_REQUEST_REPAIR,
									MSG_FC_SHOP_REQUEST_REPAIR, msgRepair);

	if(msgRepair->Count <= 0)
	{
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_INVALID_ITEM_COUNT);
		return RES_RETURN_FALSE;
	}
	if(NULL == m_pCurrentBuildingNPC)
	{
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	if (m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_REFINERY)
	{// BuildKind 체크
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

// 2007-10-02 by cmkwon, 베트남 2차패스워드 수정 - 허가됨
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_REQUEST_REPAIR 요청시 2차패스워드 체크
//	if(FALSE == this->CheckSecondaryPasswordLock())
//	{
//		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_SECPASS_LOCKED);
//		return RES_BREAK;
//	}

	// lock m_mapItemGeneral, MSG_FC_SHOP_REQUEST_REPAIR
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (pMoney == NULL
		|| pMoney->CurrentCount <= 0)
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	int nRequestAmountToRepair		= 0;
	ITEM_GENERAL *pWeaponItemGen	= NULL;
	ITEM *pBulletItem				= NULL;
	switch(msgRepair->DesParam)
	{
	case DES_HP:
		nRequestAmountToRepair = min(msgRepair->Count, (int)m_character.HP - (int)m_character.CurrentHP);
		break;
	case DES_DP:
		nRequestAmountToRepair = min(msgRepair->Count, (int)m_character.DP - (int)m_character.CurrentDP);
		break;
	case DES_EP:
		nRequestAmountToRepair = min(msgRepair->Count, (int)m_character.EP - (int)m_character.CurrentEP);
		break;
	case DES_SP:
		nRequestAmountToRepair = min(msgRepair->Count, (int)m_character.SP - (int)m_character.CurrentSP);
		break;
	case DES_BULLET_01:		// 1형 총알
		{
			pWeaponItemGen	= (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
			if(NULL == pWeaponItemGen)
			{
				SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_DES_PARAM, msgRepair->DesParam);
				return RES_BREAK;
			}
			pBulletItem		= ms_pFieldIOCP->GetBulletItemInfoByCaliber(pWeaponItemGen->ItemInfo->Caliber);
			if(NULL == pBulletItem)
			{
				SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_BULLET_ITEM, pWeaponItemGen->ItemNum, pWeaponItemGen->ItemInfo->Caliber);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
			// 2007-10-06 by cmkwon, 멤버쉽 혜택 수정 - 베트남 총알 두배 제외
			// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 아래와 같이 함수로 처리
			int nMaxChargingCount = pWeaponItemGen->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard() ,IsEffectInWingout()); // 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 -
//			int nMaxChargingCount = pWeaponItemGen->ItemInfo->Charging - pWeaponItemGen->CurrentCount;
//			if(LANGUAGE_TYPE_VIETNAMESE != g_pFieldGlobal->GetLanguageType()
//				&& m_ItemManager.IsExistPremiumCard())
//			{
//				nMaxChargingCount = 2*pWeaponItemGen->ItemInfo->Charging - pWeaponItemGen->CurrentCount;
//			}

			nRequestAmountToRepair	= min(msgRepair->Count, nMaxChargingCount);	// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
		}
		break;
	case DES_BULLET_02:		// 2형 총알
		{
			pWeaponItemGen	= (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
			if(NULL == pWeaponItemGen)
			{
				SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_DES_PARAM, msgRepair->DesParam);
				return RES_BREAK;
			}
			pBulletItem		= ms_pFieldIOCP->GetBulletItemInfoByCaliber(pWeaponItemGen->ItemInfo->Caliber);
			if(NULL == pBulletItem)
			{
				SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_BULLET_ITEM, pWeaponItemGen->ItemNum, pWeaponItemGen->ItemInfo->Caliber);
				return RES_BREAK;
			}
			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
			// 2007-10-06 by cmkwon, 멤버쉽 혜택 수정 - 베트남 총알 두배 제외
			// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 아래와 같이 함수로 처리
			int nMaxChargingCount = pWeaponItemGen->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout());// 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 -
//			int nMaxChargingCount = pWeaponItemGen->ItemInfo->Charging - pWeaponItemGen->CurrentCount;
//			if(LANGUAGE_TYPE_VIETNAMESE != g_pFieldGlobal->GetLanguageType()
//				&& m_ItemManager.IsExistPremiumCard())
//			{
//				nMaxChargingCount = 2*pWeaponItemGen->ItemInfo->Charging - pWeaponItemGen->CurrentCount;
//			}

			nRequestAmountToRepair	= min(msgRepair->Count, nMaxChargingCount);	// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
		}
		break;
	default:
		{
			SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_DES_PARAM, msgRepair->DesParam);
			return RES_BREAK;
		}
	}

	int nRepairCost			= 0;
	int nRealAmountToRepair	= 0;
	if(FALSE == CAtumSJ::GetRepairCost(&nRepairCost, &nRealAmountToRepair, msgRepair->DesParam, nRequestAmountToRepair, pBulletItem))
	{
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NO_SUCH_DES_PARAM, msgRepair->DesParam);
		return RES_BREAK;
	}

	float	fTotalTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);		// 2006-02-08 by cmkwon, 세력분포 세금 적용

	// 2013-08-12 by bckim, 신규해피아워
	float ftempRepairDiscountRate = 0.0f;	
#ifdef SC_RENEWER_HAPPY_HOUR_BHSOHN_BCKIM		//	Process_FC_SHOP_REQUEST_REPAIR
	ftempRepairDiscountRate = ms_pFieldIOCP->m_gameEventManager.GetSPIDiscountRate(m_character.InfluenceType,this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
#endif
	// 	int		nTotalTexSPI		= CAtumSJ::GetItemTexSPI(nRepairCost, fTotalTexPercent);
	// 	nRepairCost					+= nTotalTexSPI;		// 2006-02-08 by cmkwon, 세금을 더한다.
	nRepairCost					= CAtumSJ::GetItemSPIPrice(nRepairCost, fTotalTexPercent,ftempRepairDiscountRate);		// 클라이언트에서 만든 함수 사용하기로 함 
	// End. 2013-08-12 by bckim, 신규해피아워
	
	if(pMoney->CurrentCount < nRepairCost)
	{
		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	switch(msgRepair->DesParam)
	{
	case DES_HP:
		ChangeCurrentHP(nRealAmountToRepair);
		break;
	case DES_DP:
		ChangeCurrentDP(nRealAmountToRepair);
		break;
	case DES_EP:
		ChangeCurrentEP(nRealAmountToRepair);
		break;
	case DES_SP:
		ChangeCurrentSP(nRealAmountToRepair);
		break;
	case DES_BULLET_01:		// 1형 총알
	case DES_BULLET_02:		// 2형 총알
		this->SupplyBullet(pWeaponItemGen, pBulletItem, nRealAmountToRepair);
		break;
	}
	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-27 by cmkwon, SPI 로그 남기기 추가
	CAtumLogSender::SendLogMessageITEMSPI(this, pMoney, IUT_SHOP, -nRepairCost, max(0, pMoney->CurrentCount-nRepairCost));

	m_ItemManager.UpdateItemCountByPointer(pMoney, -nRepairCost, IUT_SHOP);		// update money
	igLock.auto_unlock_cancel();		// 2007-10-05 by cmkwon, 

	INIT_MSG_WITH_BUFFER(MSG_FC_SHOP_REQUEST_REPAIR_OK, T_FC_SHOP_REQUEST_REPAIR_OK, pSRepairOK, SendBuf);
	pSRepairOK->DesParam	= msgRepair->DesParam;
	pSRepairOK->Count		= nRealAmountToRepair;
	pSRepairOK->RepairCost	= nRepairCost;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_REQUEST_REPAIR_OK));

	// 2007-08-27 by dhjin, 판공비 처리
	this->SetExpediencyFundW(m_character.InfluenceType, nRepairCost);

//	int nRepairCost = CAtumSJ::GetRepairCost(msgRepair->DesParam);	// 단위 수리 비용
//	if (nRepairCost == 0)
//	{
//		return RES_BREAK;
//	}
//
//	// lock m_mapItemGeneral, MSG_FC_SHOP_REQUEST_REPAIR
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//
//	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
//	if (pMoney == NULL)
//	{
//		return RES_BREAK;
//	}
//	if (pMoney->CurrentCount <= 0)
//	{
//		SendErrorMessage(T_FC_SHOP_REQUEST_REPAIR, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
//		return RES_BREAK;
//	}
//
//	int nAmountToRepair = 0;
//	int nTotalCost = 0;
//
//	switch (msgRepair->DesParam) {
//	case DES_HP:
//		nAmountToRepair = (int)m_character.HP - (int)m_character.CurrentHP;
//		break;
//	case DES_EP:
//		nAmountToRepair = (int)m_character.EP - (int)m_character.CurrentEP;
//		break;
//	case DES_DP:
//		nAmountToRepair = (int)m_character.DP - (int)m_character.CurrentDP;
//		break;
//	default:
//		nAmountToRepair = 0;
//	}
//
//	if (nAmountToRepair <= 0)
//	{
//		return RES_BREAK;
//	}
//
//	nTotalCost = min(nAmountToRepair*nRepairCost, pMoney->CurrentCount);
//	nAmountToRepair = nTotalCost/nRepairCost;
//
//	// update character
//	if (msgRepair->DesParam == DES_HP)
//	{
//		m_character.CurrentHP = min(m_character.CurrentHP+nAmountToRepair, m_character.HP);
//		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
//	}
//	else if (msgRepair->DesParam == DES_EP)
//	{
//		m_character.CurrentEP = min(m_character.CurrentEP+nAmountToRepair, m_character.EP);
//		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTEP);
//	}
//	else if (msgRepair->DesParam == DES_DP)
//	{
//		m_character.CurrentDP = min(m_character.CurrentDP+nAmountToRepair, m_character.DP);
//		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
//	}
//	else
//	{
//		return RES_BREAK;
//	}
//
//	// update money
//	m_ItemManager.UpdateItemCountByPointer(pMoney, -nTotalCost, IUT_SHOP);

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_BUY_CASH_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	INT64 n64LogSpend = 0;	//	 총 구입비용 
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_BUY_CASH_ITEM,
									MSG_FC_SHOP_BUY_CASH_ITEM, pBuyItem);

	if (FALSE == IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}

	if(INVALID_UNIQUE_NUMBER != m_peerTraderCharacterUniqueNumber
		&& 0 != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_BUY_CASH_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}

	if(pBuyItem->Amount <= 0)
	{		
		char szSystemLog[512];
		sprintf(szSystemLog, "[ERROR] Shop Buy Cash Item Error, Char(%15s) ItemNum(%8d) ItemAmoun(%8d)\r\n"
			, m_character.CharacterName, pBuyItem->ItemNum, pBuyItem->Amount);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);

		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0074);
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pBuyItem->Amount);
		return RES_RETURN_FALSE;
	}

	map<UINT, CShopInfo*>::iterator itr
		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(pBuyItem->BuildingIndex);
	if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_RETURN_FALSE;
	}
	CShopInfo *pShop = itr->second;

// 2006-10-20 by cmkwon, 상점 아이템 리스트 컨테이너 변경, 아래와 같이 수정함
//	map<UINT, SHOP_ITEM>::iterator itr_item	= pShop->m_mapShopItem.find(pBuyItem->ItemNum);
//	if (itr_item == pShop->m_mapShopItem.end())
//	{
//		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, pBuyItem->ItemNum);
//		return RES_RETURN_FALSE;
//	}
//	SHOP_ITEM *pShopItem = &itr_item->second;
	SHOP_ITEM *pShopItem = pShop->GetSHOP_ITEMPtr(pBuyItem->ItemNum);
	if (NULL == pShopItem)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2007-08-10 by cmkwon, 캐쉬상점에 아머 컬러 아이템 판매 구현 추가 - 상점리스트에 없다
		ITEM *pTmItemInfo = ms_pFieldIOCP->GetItemInfo(pBuyItem->ItemNum);
		if(pTmItemInfo
			&& ITEMKIND_COLOR_ITEM == pTmItemInfo->Kind 
			&& CASH_ITEMKIND_COLOR_ITEM == pTmItemInfo->SummonMonster)
		{
			// 처리 필요 없음
		}
		else
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, pBuyItem->ItemNum);
			return RES_RETURN_FALSE;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - T_FC_SHOP_BUY_CASH_ITEM, 매진 체크
	int nRemainCountForLimitedEdition = 0;
	if(pShopItem->IsSoldOutShopItem())
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_SOLD_OUT_SHOP_ITEM, pBuyItem->ItemNum, pShopItem->IsSoldOutShopItem());
		return RES_BREAK;
	}

	// 아이템 요구 조건 확인, check: 일단은 skill인 경우만 확인함
	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pBuyItem->ItemNum);
	if (pItemInfo == NULL
		|| FALSE == COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM))
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pBuyItem->ItemNum);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 체크 추가
	if(IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
	{
		if(m_giveTargetCharacter.CharacterUID0 != pBuyItem->GiveTargetCharacterUID)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVALID_PEER_CHARACTER, pBuyItem->ItemNum);
			return RES_BREAK;
		}
		if(m_giveTargetCharacter.BuyItemNum != pBuyItem->ItemNum)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED, pBuyItem->ItemNum);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-08 by cmkwon, 필드창고 캐쉬 아이템 시스템 보완 - T_FC_SHOP_BUY_CASH_ITEM, 필드창고 아이템은 선물하기 불가
		if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD)		// 2009-10-08 by cmkwon, 프리미엄 아이템 선물하기 불가
			|| pItemInfo->IsExistDesParam(DES_FIELD_STORE))
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_CANNOT_BUY_ITEM, pBuyItem->ItemNum);
			return RES_BREAK;
		}

#ifdef S_CANNOT_DO_GIFT_UNDER_LEVEL_BCKIM	// 2013-07-08 by bckim, 캐나다요청 레벨70 미만은 선물하기 불가
		if( 70 > this->m_character.Level )
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_CANNOT_DO_GIFT_UNDER_LEVEL, this->m_character.CharacterUniqueNumber, this->m_character.Level);
			return RES_BREAK;
		}
#endif

		// 2012-11-12 by hskim, 캐나다 선물하기 기능 삭제
#ifdef S_DELETE_BUY_CASH_GIVE
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_CANNOT_BUY_ITEM, pBuyItem->ItemNum);
		return RES_BREAK;
#endif
		// 2012-11-12 by hskim, 캐나다 선물하기 기능 삭제
	}


	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);									// lock m_mapItemGeneral, MSG_FC_SHOP_BUY_ITEM

	///////////////////////////////////////////////////////////////////////////////
	// 현재 MGameMoney를 가져온다
	int nTotalMoney	= 0;
	int nMCash		= 0;
	int nGiftCard	= 0;
	Err_t nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard);
	if(ERR_NO_ERROR != nRetedErr)
	{
		SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, nRetedErr);
		return RES_BREAK;
	}

	int nBuyBeforeMCash = nMCash;	// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급, 아이템 구입 전 유료 캐쉬 금액

// 2008-10-20 by cmkwon, 멥버쉽 아이템 체크 ItemAttribute 로 처리 - 
//	if(CASH_ITEMKIND_PREMIUM_CARD == pItemInfo->SummonMonster)
	if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
	{// 프리미엄 카드 처리

// 2006-06-14 by cmkwon, 아직은 필요 없다 - 프리미엄 카드가 사용되지 않고 있다
// 		if(0 != m_ItemPet.ItemNum
// 			&& (m_ItemPet.IsExistDesParam(DES_DROP_EXP) || m_ItemPet.IsExistDesParam(DES_DROP_SPI) || m_ItemPet.IsExistDesParam(DES_DROP_ITEM)))
// 		{// 2006-03-30 by cmkwon, 특정 시간제한 액세서리 아이템 사용시 프리미엄카드 구입 불가 
// 			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_CANNOT_BUY_PREMIUM_CARD_USING_SPEC_ITEM);
// 			return RES_BREAK;
// 		}

		INT64 n64SumOfPrice	= pItemInfo->CashPrice * (pBuyItem->Amount/pItemInfo->MinTradeQuantity);
		// 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "   [Check] CFieldIOCPSocket::Process_FC_SHOP_BUY_CASH_ITEM, #1 _ AUID(%d) CUID(%d) ItemNum(%d) [TotalCash(%d) = MainCash(%d) + FreeCash(%d)] [TotalPrice(%I64d) = (BuyAmount(%d) / MinTradeQuantity(%d)) * ItemPrice(%d)]\r\n"
			, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, pItemInfo->ItemNum
			, nTotalMoney, nMCash, nGiftCard
			, n64SumOfPrice, pBuyItem->Amount, pItemInfo->MinTradeQuantity, pItemInfo->CashPrice);
		// end 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
		if (n64SumOfPrice > nTotalMoney)	// 2006-10-24 by cmkwon, nTotalMoney로 비교한다.
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY, n64SumOfPrice, nTotalMoney);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 프리미엄 아이템이 구입가능한지 체크
		nRetedErr = this->m_ItemManager.CashInsertPremiumCard(pItemInfo, TRUE);
		if(ERR_NO_ERROR != nRetedErr)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, nRetedErr, 0);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - T_FC_SHOP_BUY_CASH_ITEM, 한정판매 아이템 구매 체크
		if(pShopItem->IsLimitedEditionShopItem())
		{
			BOOL bSuccessBuy = m_ItemManager.CheckBuyLimitedEditionShopItem(&nRemainCountForLimitedEdition, pShopItem->ItemNum);
			pShopItem->RemainCountForLimitedEdition	= nRemainCountForLimitedEdition;
			
			if(FALSE == bSuccessBuy)
			{
				SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_SOLD_OUT_SHOP_ITEM, pBuyItem->ItemNum, pShopItem->IsSoldOutShopItem());
				return RES_BREAK;
			}
		}

		///////////////////////////////////////////////////////////////////////////////
		// 출금 처리
		// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - 아래와 같이 수정
		//nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard, pItemInfo, n64SumOfPrice);
		nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard, pItemInfo, n64SumOfPrice, 0, nTotalMoney);	// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - nTotalMoney을 설정함.
		if(ERR_NO_ERROR != nRetedErr)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, nRetedErr);
			return RES_BREAK;
		}
		
		///////////////////////////////////////////////////////////////////////////////
		// 프리미엄 아이템을 추가
		nRetedErr = this->m_ItemManager.CashInsertPremiumCard(pItemInfo);
		if(ERR_NO_ERROR != nRetedErr)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, nRetedErr, 1);
			return RES_BREAK;
		}

	}
	// 2013-05-22 by jhseol, 소스정리 - 주석삭제
	else
	{// 일반 유료화 아이템 처리

		///////////////////////////////////////////////////////////////////////////////
		// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_SHOP_BUY_CASH_ITEM, 필드창고 이용권 아이템 구매가능여부  체크
		if(pItemInfo->IsExistDesParam(DES_FIELD_STORE)
			&& this->m_ItemManager.IsUseableFieldStore())
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_CANNOT_BUY_ITEM, pItemInfo->ItemNum, this->m_ItemManager.IsUseableFieldStore());
			return RES_BREAK;
		}

		if(FALSE == IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
		{// 2007-11-14 by cmkwon, 자신이 아이템을 구매 할 때
			// 최대 개수 확인
			// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
			if(IS_COUNTABLE_ITEM(pItemInfo->Kind))
			{// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인

				ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(pItemInfo->ItemNum);
				if (NULL == pItemGeneralInven
					&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
				{
					SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
					return RES_BREAK;
				}
			}
			else if(IS_GENERAL_ITEM(pItemInfo->Kind))
			{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 아래와 같이 체크 수정
				
				pBuyItem->Amount = min(pBuyItem->Amount, MAX_ITEM_COUNTS_FOR_BUY);		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 최대 구입 가능 개수 설정.

				if(m_ItemManager.GetInventoryItemCounts() + pBuyItem->Amount > m_ItemManager.GetMaxInventoryCount())
				{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
					SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
					return RES_BREAK;
				}
			}
// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 위와 같이 수정 함.
//			else if (m_ItemManager.GetInventoryItemCounts() >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))
//			{// 카운터블이 아닐 경우 최대 개수 확인
//
//				SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()));
//				return RES_BREAK;
//			}

			///////////////////////////////////////////////////////////////////////////////
			// 2005-09-13 by cmkwon, 카운터블 아이템일 경우 최대(20억) 카운트 체크
			if(IS_COUNTABLE_ITEM(pItemInfo->Kind))
			{
				INT64 tmCurrentCount = pBuyItem->Amount;

				ITEM_GENERAL *pMyItem = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyItem->ItemNum);
				if(pMyItem){				tmCurrentCount += pMyItem->CurrentCount;}
				if(tmCurrentCount > MAX_ITEM_COUNTS)
				{
					SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, 0, 0);
					return RES_BREAK;			
				}
				else if(tmCurrentCount >= MAX_NOTIFY_ITEM_COUNTS)
				{
					SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER);
				}
			}


			if (IS_GENERAL_ITEM(pItemInfo->Kind) 
				&& FALSE == IS_COUNTABLE_ITEM(pItemInfo->Kind))
			{
				if(timeGetTime()-m_dwLastTickInsertingStoreItem > 5000)
				{
					m_nInsertingStoreItemCounts = 0;
				}

				// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 
				//if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))	// 2006-10-25 by cmkwon, 오류 수정
				// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
				if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts + pBuyItem->Amount > m_ItemManager.GetMaxInventoryCount())	// 2006-10-25 by cmkwon, 오류 수정
				{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
					SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, 1);
					return RES_BREAK;
				}		
			}
		}
		

		if (COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM))
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
			return RES_BREAK;
		}
// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
//		// 무게 확인
//		if (pItemInfo->Weight > 0.0f)
//		{
//			float fItemWeight = CAtumSJ::GetItemWeight(pItemInfo, pBuyItem->Amount);
//			if (GetCurrentLoadagePercentage(fItemWeight) > 1.0f)
//			{
//				SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_ITEM_OVER_WEIGHT,
//									(INT)m_ItemManager.GetCurrentCarryingItemWeight()+fItemWeight,
//									(INT)CAtumSJ::GetTransport(&m_character));
//				return RES_BREAK;
//			}
//		}

		// 최소 거래 단위 확인: MinTradeQuantity의 배수로만 구매 할 수 있음
		if ( pBuyItem->Amount%pItemInfo->MinTradeQuantity != 0)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pItemInfo->MinTradeQuantity);
			return RES_BREAK;
		}

		// 유료화 아이템에는 스킬이 없다
		
		if (nTotalMoney <= 0)
		{// MGameMoney 오류
			
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
			return RES_BREAK;
		}

		INT64 n64SumOfPrice	= pItemInfo->CashPrice * (pBuyItem->Amount/pItemInfo->MinTradeQuantity);
		// 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "   [Check] CFieldIOCPSocket::Process_FC_SHOP_BUY_CASH_ITEM, #2 _ AUID(%d) CUID(%d) ItemNum(%d) [TotalCash(%d) = MainCash(%d) + FreeCash(%d)] [TotalPrice(%I64d) = (BuyAmount(%d) / MinTradeQuantity(%d)) * ItemPrice(%d)]\r\n"
			, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, pItemInfo->ItemNum
			, nTotalMoney, nMCash, nGiftCard
			, n64SumOfPrice, pBuyItem->Amount, pItemInfo->MinTradeQuantity, pItemInfo->CashPrice);
		// end 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
		// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
		n64LogSpend = n64SumOfPrice;		//	 총 구입비용 
		// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
		if (n64SumOfPrice > nTotalMoney)
		{
			// error
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - T_FC_SHOP_BUY_CASH_ITEM, 한정판매 아이템 구매 체크
		if(pShopItem->IsLimitedEditionShopItem())
		{
			BOOL bSuccessBuy = m_ItemManager.CheckBuyLimitedEditionShopItem(&nRemainCountForLimitedEdition, pShopItem->ItemNum);
			pShopItem->RemainCountForLimitedEdition	= nRemainCountForLimitedEdition;

			if(FALSE == bSuccessBuy)
			{
				SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_SOLD_OUT_SHOP_ITEM, pBuyItem->ItemNum, pShopItem->IsSoldOutShopItem());
				return RES_BREAK;
			}
		}


		///////////////////////////////////////////////////////////////////////////////
		// 출금 처리
		// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - CashItemMoneyPay() 인자 추가
		// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - 아래와 같이 수정
		//nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard, pItemInfo, n64SumOfPrice, pBuyItem->GiveTargetCharacterUID);
		// 2012-09-12 by jhseol, 마상 BPSoft 빌링시스템 - 선물은 유료캐쉬로만 가능
#ifdef S_BPSOFTBILLING_JHSEOL
		if( NULL != pBuyItem->GiveTargetCharacterUID )
		{
			if( nMCash < pItemInfo->CashPrice )
			{
				SendString128(STRING_128_USER_NOTICE, "\\y유료M코인이 부족하여 선물할 수 없습니다.\\y");
				SendString128(STRING_128_USER_NOTICE, "\\y유료M코인 잔액[%10dM코인]\\y", nMCash);
				SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, ERR_DB_NOT_ENOUGH_MONEY);
				return RES_BREAK;
			}
		}
#endif
		// end 2012-09-12 by jhseol, 마상 BPSoft 빌링시스템 - 선물은 유료캐쉬로만 가능
		nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard, pItemInfo, n64SumOfPrice, pBuyItem->GiveTargetCharacterUID, nTotalMoney);	// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - nTotalMoney을 설정
		if(ERR_NO_ERROR != nRetedErr)
		{
			SendErrorMessage(T_FC_SHOP_BUY_CASH_ITEM, nRetedErr);
			return RES_BREAK;
		}

		if(FALSE == IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
		{// 2007-11-14 by cmkwon, 자신이 아이템을 구매 할 때
			///////////////////////////////////////////////////////////////////////////////
			// 아이템 삽입
			m_ItemManager.InsertItemBaseByItemNum(pItemInfo->ItemNum, pBuyItem->Amount, IUT_SHOP);
		}
		else
		{
			///////////////////////////////////////////////////////////////////////////////
			// 해당 캐릭터 창고로 아이템 추가
			this->GiveItem(pItemInfo, pBuyItem->Amount, IUT_SHOP);
		}
	}

	// send log
	ITEM_GENERAL tmpItemForLog(pItemInfo);
	tmpItemForLog.UniqueNumber			= 0;	// 2007-11-28 by cmkwon, 모두 기본값 0으로 설정, // 2007-11-13 by cmkwon, 선물하기 기능 추가 - 자신이 구입이면 0, 선물하기 이면 1
	tmpItemForLog.AccountUniqueNumber	= m_character.AccountUniqueNumber;
	tmpItemForLog.Possess				= m_character.CharacterUniqueNumber;
	tmpItemForLog.Wear					= WEAR_NOT_ATTACHED;
	tmpItemForLog.CurrentCount			= pBuyItem->Amount;
// 2009-08-25 by cmkwon, 사용하지 않는 필드 제거(td_Store.ScarcityNumber) - 
//	tmpItemForLog.ScarcityNumber		= 0;
	tmpItemForLog.ItemWindowIndex		= POS_INVALID_POSITION;
	tmpItemForLog.PrefixCodeNum			= 0;
	tmpItemForLog.SuffixCodeNum			= 0;
	tmpItemForLog.NumOfEnchants			= 0;

	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐쉬탬 구매 GLog 추가
#ifdef S_GLOG_3ND_KHK	// - 캐쉬탬 구매 GLog 추가
	m_ItemManager.SetGLogData(GLOG_IL_LT_CASHSHOP_BUY,&tmpItemForLog,m_character.Level);
#endif
	// end 2013-05-30 by jhseol, GLog 시스템 보완 - 캐쉬탬 구매 GLog 추가
	
	// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - 
	CAtumLogSender::SendLogMessageITEMBuyITEM(this, &tmpItemForLog, pBuyItem->Amount, nTotalMoney, FALSE, nRemainCountForLimitedEdition);

	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	//enum ITEM_BUY_CASH_PRICE_TYPE{BUY_TYPE_SPI=1,BUY_TYPE_WARPOINT,BUY_TYPE_CASH,BUY_TYPE_INFINITY};
	CAtumLogSender::SendLogMessageITEMBuyCashPrice(this, &tmpItemForLog, pBuyItem->Amount, n64LogSpend, FALSE, BUY_TYPE_CASH, NULL); // CASH TYPE : 3
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	if(IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
	{
		// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 선물하기 로그 추가하기
		CAtumLogSender::SendLogMessageITEMGiftSend(this, &tmpItemForLog, pBuyItem->Amount, &m_giveTargetCharacter);
		// 2007-11-27 by cmkwon, 선물하기 로그 수정 - CAtumLogSender::SendLogMessageITEMGiftRecv() 함수 인자 수정, 아래와 같이 수정
		// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
		// 2012-08-30 by jhseol, 풀로그 남기기 - 변경전의 함수 임으로 주석 해제 안함.
		//CAtumLogSender::SendLogMessageITEMGiftRecv(&m_giveTargetCharacter, &tmpItemForLog, pBuyItem->Amount, &m_character);
#endif	//#ifdef S_FULL_LOG_JHSEOL
		// end 2012-08-30 by jhseol, 풀로그 남기기
		CAtumLogSender::SendLogMessageITEMGiftRecv(m_giveTargetCharacter.CharacterUID0, &tmpItemForLog, pBuyItem->Amount, m_character.CharacterUniqueNumber, m_character.CharacterName);
	}
	
	igLock.auto_unlock_cancel();

	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 메시지 다르게 처리
	if(FALSE == IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
	{
		///////////////////////////////////////////////////////////////////////////////
		// 구입 정보를 text로 전송
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0075);
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0076, pItemInfo->ItemName, pBuyItem->Amount);
	}
	else
	{
		///////////////////////////////////////////////////////////////////////////////
		// 선물 정보를 text로 전송
		SendString128(STRING_128_USER_NOTICE, STRMSG_071115_0001, m_giveTargetCharacter.CharacterName0, pItemInfo->ItemName);
		SendString128(STRING_128_USER_NOTICE, STRMSG_071115_0002, pItemInfo->ItemName, pBuyItem->Amount);

// 2007-11-28 by cmkwon, 통지시스템 구현 - 아래와 같이 통시시스템으로 처리함
//		CFieldIOCPSocket *pTargetFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pBuyItem->GiveTargetCharacterUID);
//		if(pTargetFISoc
//			&& pTargetFISoc->IsValidCharacter(FALSE))
//		{// 2007-11-15 by cmkwon, 선물 받은 사람에게 알림
//			pTargetFISoc->SendString128(STRING_128_USER_NOTICE, STRMSG_071115_0003, m_character.CharacterName, m_giveTargetCharacter.CharacterName0, pItemInfo->ItemName);
//		}
		SNOTIFY_MSG notifyMsg;		MEMSET_ZERO(&notifyMsg, sizeof(notifyMsg));
		notifyMsg.CharacterUID			= pBuyItem->GiveTargetCharacterUID;
		notifyMsg.NotifyMsgType			= NOTIFY_MSG_TYPE_RECV_GIFT;
		_snprintf(notifyMsg.NotifyMsgString, SIZE_MAX_NOTIFY_MSG_STRING, STRMSG_071128_0001, m_character.CharacterName, pItemInfo->ItemName, pBuyItem->Amount);
		notifyMsg.SenderCharacterUID	= m_character.CharacterUniqueNumber;
		STRNCPY_MEMSET(notifyMsg.SenderCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		// 2007-12-20 by cmkwon, 통지시스템 버그 수정 - CFieldIOCPSocket::InsertNotifyMsg() 함수명 변경
		//CFieldIOCPSocket::InsertNotifyMsg(&notifyMsg, this);
		CFieldIOCPSocket::InsertNotifyMsg2Anyone(&notifyMsg, this);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 남은 MGameMoney를 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK, T_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK, pSOKt, SendBuf);
	pSOKt->nMCash			= nMCash;
	pSOKt->nGiftCard		= nGiftCard;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK));

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 캐쉬아이템 구입 성공 메시지 전송
	INIT_MSG(MSG_FC_SHOP_BUY_CASH_ITEM_OK, T_FC_SHOP_BUY_CASH_ITEM_OK, pSBuyOK, SendBuf);
	pSBuyOK->ItemNum		= pBuyItem->ItemNum;
	pSBuyOK->Amount			= pBuyItem->Amount;
	if(IS_VALID_UNIQUE_NUMBER(pBuyItem->GiveTargetCharacterUID))
	{
		pSBuyOK->GiveTargetCharacterUID	= m_giveTargetCharacter.CharacterUID0;
		STRNCPY_MEMSET(pSBuyOK->GiveTargetCharacterName, m_giveTargetCharacter.CharacterName0, SIZE_MAX_CHARACTER_NAME);
	}
	pSBuyOK->RemainCountForLimitedEdition	= pShopItem->RemainCountForLimitedEdition;		// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - 
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_BUY_CASH_ITEM_OK));

	MEMSET_ZERO(&m_giveTargetCharacter, sizeof(m_giveTargetCharacter));				// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 초기화

	// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
#ifdef S_MONTHL_CASH_BUY_GIFT_JHSEOL
	if ( 0 < nBuyBeforeMCash && nBuyBeforeMCash > nMCash )
	{
// 2014-03-12 by jekim, 주민번호당 아이템 지급
		if ( FALSE == g_pFieldGlobal->IsArenaServer() )
		{
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_LoadCashBuyDate, this, m_character.AccountUniqueNumber, NULL);
		}
// 		vectItemEventInfo		vectItemEventInfo1;
// 		vectItemEventInfo1.clear();
// 		vectItemEventInfo1.reserve(20);
// 		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemFirstPurchase(&vectItemEventInfo1, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, m_character.InfluenceType, \
// 			m_character.UnitKind, m_atAccountLastBuyDate, m_atCharacterLastBuyDate, m_nChannelingNum );	// 2014-02-10 by jhseol&bckim, 체널링
// 		for (int i=0; i < vectItemEventInfo1.size(); i++)
// 		{
// 			// 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경
// 			if ( FALSE == ms_pFieldIOCP->ItemEventSubTypeCheck(m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, vectItemEventInfo1[i]) )
// 			{
// 				continue;
// 			}
// 			// end 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경
// 			
// 			char tmpAccount[SIZE_MAX_SQL_DATETIME_STRING] = {0,};
// 			m_atAccountLastBuyDate.GetSQLDateTimeString(tmpAccount, SIZE_MAX_SQL_DATETIME_STRING);
// 			char tmpCharacter[SIZE_MAX_SQL_DATETIME_STRING] = {0,};
// 			m_atCharacterLastBuyDate.GetSQLDateTimeString(tmpCharacter, SIZE_MAX_SQL_DATETIME_STRING);
// 			char EventStartTime[SIZE_MAX_SQL_DATETIME_STRING] = {0,};
// 			vectItemEventInfo1[i].StartTime.GetSQLDateTimeString(EventStartTime, SIZE_MAX_SQL_DATETIME_STRING);
// 			char EventEndTime[SIZE_MAX_SQL_DATETIME_STRING] = {0,};
// 			vectItemEventInfo1[i].EndTime.GetSQLDateTimeString(EventEndTime, SIZE_MAX_SQL_DATETIME_STRING);
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[S_MONTHL_CASH_BUY_GIFT_JHSEOL][Notify] CFieldIOCPSocket::Process_FC_SHOP_BUY_CASH_ITEM, AUID(%8d) CUID(%8d) A_Date(%s) C_Date(%s), Event ID(%5d) Time(%s ~ %s)\r\n"
// 				, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, tmpAccount, tmpCharacter, vectItemEventInfo1[i].ItemEventUID, EventStartTime, EventEndTime);
// 			QPARAM_CHECK_EVENTITEM *pQParam = new QPARAM_CHECK_EVENTITEM;
// 			pQParam->AccountUID		= m_character.AccountUniqueNumber;
// 			pQParam->ItemEventUID	= vectItemEventInfo1[i].ItemEventUID;
// 			pQParam->ItemEventType  = vectItemEventInfo1[i].ItemEventType;
// 			pQParam->ItemNum		= vectItemEventInfo1[i].ItemNum;
// 			pQParam->Count			= vectItemEventInfo1[i].Count;
// 			pQParam->PrefixCodeNum	= vectItemEventInfo1[i].PrefixCodeNum;
// 			pQParam->SuffixCodeNum	= vectItemEventInfo1[i].SuffixCodeNum;
// 			pQParam->CharacterUID	= (FALSE == vectItemEventInfo1[i].CheckWithCharacterUID) ? 0 : m_character.CharacterUniqueNumber;	// 2009-11-19 by cmkwon, 아이템 이벤트에 Account/Character 체크 기능 추가 - 
// 			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckEventItem, this, m_character.AccountUniqueNumber, pQParam);
// 		}
// 		
// 		m_atCharacterLastBuyDate.SetCurrentDateTime(FALSE);
// 		m_atAccountLastBuyDate.SetCurrentDateTime(FALSE);
// 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertCashBuyDate, this, m_character.AccountUniqueNumber, NULL);
// end 2014-03-12 by jekim, 주민번호당 아이템 지급
	}
#endif
	// end 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_SHOP_BUY_COLOR_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-06 ~ 2005-12-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_BUY_COLOR_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_BUY_COLOR_ITEM,
									MSG_FC_SHOP_BUY_COLOR_ITEM, pBuyColorItem);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}
	
	if(INVALID_UNIQUE_NUMBER != m_peerTraderCharacterUniqueNumber
		&& 0 != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_BUY_COLOR_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}

	ITEM *pColorItem = ms_pFieldIOCP->GetItemInfo(pBuyColorItem->ItemNum);
	if(NULL == pColorItem)
	{// ItemNum 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED);
		return RES_BREAK;
	}

	if (0 != pColorItem->ReqMinLevel 
		&& pColorItem->ReqMinLevel > m_character.Level)
	{// 최소 필요 레벨 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED);
		return RES_BREAK;
	}
	if (0 != pColorItem->ReqMaxLevel 
		&& pColorItem->ReqMaxLevel < m_character.Level)	
	{// 최대 필요 레벨 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED);
		return RES_BREAK;
	}
	
	if(NULL == m_pCurrentBuildingNPC)
	{
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	if (m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_TUNING_COLOR)
	{// BuildKind 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_BUILDING_KIND_NOT_MATCHED);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral 

	ITEM_GENERAL *pArmorItemGen = GetAttachItemGeneralByPosition(POS_CENTER);
	if(NULL == pArmorItemGen
		|| ITEMKIND_DEFENSE != pArmorItemGen->Kind)
	{// 아머 아이템 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_INVALID_ARMOR_ITEM);
		return RES_BREAK;
	}
	if(pArmorItemGen->ItemInfo->SourceIndex != COLORItemNum_TO_ArmorSourceIndex(pColorItem->ItemNum))
	{// ItemNum 체크
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_INVALID_ITEMNUM, 1);
		return RES_BREAK;
	}

	int nColorCost = pColorItem->Price;

	// 2006-02-08 by cmkwon, 세력분포 세금 적용
	float	fTotalTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	int		nTotalTexSPI		= CAtumSJ::GetItemTexSPI(nColorCost, fTotalTexPercent);
	nColorCost					+= nTotalTexSPI;		// 2006-02-08 by cmkwon, 세금을 더한다.

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (pMoney == NULL
		|| pMoney->CurrentCount < nColorCost)
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_SHOP_BUY_COLOR_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-06 by cmkwon, 색상 값과 SPI 감액 처리
	pArmorItemGen->ColorCode	= pColorItem->ItemNum;
	this->UpdateItemRenderInfo(POS_CENTER, TRUE);
	m_ItemManager.UpdateItemCountByPointer(pMoney, -nColorCost, IUT_SHOP);		// update money

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-06 by cmkwon, DB Update
	QPARAM_STORE_UPDATE_COLORCODE *pQParam = new QPARAM_STORE_UPDATE_COLORCODE;
	pQParam->ItemUniqueNumber	= pArmorItemGen->UniqueNumber;
	pQParam->ColorCode			= pArmorItemGen->ColorCode;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_StoreUpdateColorCode, this, m_character.AccountUniqueNumber, pQParam);

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-06 by cmkwon, 클라이언트로 전송함
	INIT_MSG_WITH_BUFFER(MSG_FC_SHOP_BUY_COLOR_ITEM_OK, T_FC_SHOP_BUY_COLOR_ITEM_OK, pSMsg, SendBuf);
	pSMsg->ItemUID64			= pArmorItemGen->UniqueNumber;
	pSMsg->ColorCode			= pArmorItemGen->ColorCode;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_BUY_COLOR_ITEM_OK));

	igLock.auto_unlock_cancel();	// 2007-10-05 by cmkwon, 

	// 2007-08-27 by dhjin, 판공비 처리
	this->SetExpediencyFundW(m_character.InfluenceType, nColorCost);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::Process_FC_SHOP_BUY_WARPOINT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		WarPoint로 구매
/// \author		dhjin
/// \date		2007-06-13 ~ 2007-06-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_BUY_WARPOINT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 2007-06-13 by dhjin, 기본적인 부분 체크
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_BUY_WARPOINT_ITEM,
									MSG_FC_SHOP_BUY_WARPOINT_ITEM, pBuyWarPointItem);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}

	if(INVALID_UNIQUE_NUMBER != m_peerTraderCharacterUniqueNumber
		&& 0 != m_peerTraderCharacterUniqueNumber)
	{// 2007-06-13 by dhjin, 거래 중인지 체크
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_BUY_WARPOINT_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}
	
	map<UINT, CShopInfo*>::iterator itr
		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(pBuyWarPointItem->BuildingIndex);
	if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_RETURN_FALSE;
	}
	CShopInfo *pShop = itr->second;
	SHOP_ITEM *pWarPointShopItem = pShop->GetSHOP_ITEMPtr(pBuyWarPointItem->ItemNum);
	if (NULL == pWarPointShopItem)
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, pBuyWarPointItem->ItemNum);
		return RES_RETURN_FALSE;
	}

	if(NULL == m_pCurrentBuildingNPC)
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	if (m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_WARPOINT_SHOP)
	{// BuildKind 체크
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_BUILDING_KIND_NOT_MATCHED);
		return RES_BREAK;
	}

	if(pBuyWarPointItem->Amount <= 0)
	{// 2007-06-13 by dhjin, 총 수가 0보다 작으면 에러		
		char szSystemLog[512];
		sprintf(szSystemLog, "[ERROR] Shop Buy WarPoint Item Error, Char(%15s) ItemNum(%8d) ItemAmoun(%8d)\r\n"
			, m_character.CharacterName, pBuyWarPointItem->ItemNum, pBuyWarPointItem->Amount);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);

		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0074);
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pBuyWarPointItem->Amount);
		return RES_RETURN_FALSE;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM *pWarPointItemInfo = ms_pFieldIOCP->GetItemInfo(pBuyWarPointItem->ItemNum);
	if (pWarPointItemInfo == NULL)
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pBuyWarPointItem->ItemNum);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_SHOP_BUY_WARPOINT_ITEM, 필드창고 이용권 아이템 구매가능여부  체크
	if(pWarPointItemInfo->IsExistDesParam(DES_FIELD_STORE)
		&& this->m_ItemManager.IsUseableFieldStore())
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_CANNOT_BUY_ITEM, pWarPointItemInfo->ItemNum, this->m_ItemManager.IsUseableFieldStore());
		return RES_BREAK;
	}


// 2009-09-16 by cmkwon, WarPoint 상점 넌카운터블 아이템 구매 버그 - 아래쪽에서 금액 계산
// 	INT64 n64SumOfPrice	= pWarPointItemInfo->CashPrice * (pBuyWarPointItem->Amount/pWarPointItemInfo->MinTradeQuantity);
// 	if (NULL == this->m_character.WarPoint
// 		|| n64SumOfPrice > this->m_character.WarPoint)
// 	{// 2007-06-13 by dhjin, 구입하려는 수량에 따른 가격 비교
// 		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
// 		return RES_BREAK;
// 	}

	// 2007-06-13 by dhjin, WarPoint 상품 구입
	// 최대 개수 확인
	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
	if(IS_COUNTABLE_ITEM(pWarPointItemInfo->Kind))
	{// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인

		ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(pWarPointItemInfo->ItemNum);
		if (NULL == pItemGeneralInven
			&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
		{
			SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
	}
	else if(IS_GENERAL_ITEM(pWarPointItemInfo->Kind))
	{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 
		pBuyWarPointItem->Amount = min(pBuyWarPointItem->Amount, MAX_ITEM_COUNTS_FOR_BUY);		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 최대 구입 가능 개수 설정.
		
		if(m_ItemManager.GetInventoryItemCounts() + pBuyWarPointItem->Amount > m_ItemManager.GetMaxInventoryCount())
		{// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
	}
// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 
//	else if (m_ItemManager.GetInventoryItemCounts() >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))
//	{// 카운터블이 아닐 경우 최대 개수 확인
//
//		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()));
//		return RES_BREAK;
//	}

	// 2009-09-16 by cmkwon, WarPoint 상점 넌카운터블 아이템 구매 버그 - 넌카운터블 아이이템 구매 가능 개수가 수정될수 있기 때문에 위치 이동
	INT64 n64SumOfPrice	= pWarPointItemInfo->CashPrice * (pBuyWarPointItem->Amount/pWarPointItemInfo->MinTradeQuantity);

	// 2013-08-12 by bckim, 신규해피아워	
#ifdef SC_RENEWER_HAPPY_HOUR_BHSOHN_BCKIM		//	Process_FC_SHOP_BUY_WARPOINT_ITEM
	float ftempWPDiscountRate = ms_pFieldIOCP->m_gameEventManager.GetWPDiscountRate(m_character.InfluenceType,this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
	n64SumOfPrice = CAtumSJ::GetItemWPPrice( n64SumOfPrice, ftempWPDiscountRate);		// 클라이언트에서 만든 함수 사용하기로 함
#endif
	// End. 2013-08-12 by bckim, 신규해피아워


	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	INT64 n64LogSpend = n64SumOfPrice;		//	 총 구입비용 
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	if (NULL == this->m_character.WarPoint
		|| n64SumOfPrice > this->m_character.WarPoint)
	{// 2007-06-13 by dhjin, 구입하려는 수량에 따른 가격 비교
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-09-13 by cmkwon, 카운터블 아이템일 경우 최대(20억) 카운트 체크
	if(IS_COUNTABLE_ITEM(pWarPointItemInfo->Kind))
	{
		INT64 tmCurrentCount = pBuyWarPointItem->Amount;

		ITEM_GENERAL *pMyItem = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyWarPointItem->ItemNum);
		if(pMyItem){				tmCurrentCount += pMyItem->CurrentCount;}
		if(tmCurrentCount > MAX_ITEM_COUNTS)
		{
			SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, 0, 0);
			return RES_BREAK;			
		}
		else if(tmCurrentCount >= MAX_NOTIFY_ITEM_COUNTS)
		{
			SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER);
		}
	}

	if (IS_GENERAL_ITEM(pWarPointItemInfo->Kind) 
		&& FALSE == IS_COUNTABLE_ITEM(pWarPointItemInfo->Kind))
	{
		if(timeGetTime()-m_dwLastTickInsertingStoreItem > 5000)
		{
			m_nInsertingStoreItemCounts = 0;
		}

		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 
		//if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts >= CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))	// 2006-10-25 by cmkwon, 오류 수정
		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
		if(m_ItemManager.GetInventoryItemCounts() + m_nInsertingStoreItemCounts + pBuyWarPointItem->Amount > m_ItemManager.GetMaxInventoryCount())	// 2006-10-25 by cmkwon, 오류 수정
		{
			SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, 1);
			return RES_BREAK;
		}		
	}

	if (COMPARE_BIT_FLAG(pWarPointItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM))
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	// 최소 거래 단위 확인: MinTradeQuantity의 배수로만 구매 할 수 있음
	if ( pBuyWarPointItem->Amount%pWarPointItemInfo->MinTradeQuantity != 0)
	{
		SendErrorMessage(T_FC_SHOP_BUY_WARPOINT_ITEM, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pWarPointItemInfo->MinTradeQuantity);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 아이템 삽입
	m_ItemManager.InsertItemBaseByItemNum(pWarPointItemInfo->ItemNum, pBuyWarPointItem->Amount, IUT_SHOP, FALSE, ITEM_IN_CHARACTER,	TRUE, TRUE, 0, 0, 0, 0, GLOG_WARPOINTSHOP);  // 2012-11-21 by khkim, GLog 2차 
	
	// 2007-06-13 by dhjin, WarPoint 감소
	this->m_character.WarPoint -= n64SumOfPrice;

	// start 2012-01-16 by hskim, 통계 - 화패
	if( NULL != this->ms_pFieldIOCP->m_pStatisticsManager )
	{
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(STATISTICS_WAR_POINT, n64SumOfPrice);
	}
	// end 2012-01-16 by hskim, 통계 - 화패

	// send log
	ITEM_GENERAL tmpItemForLog(pWarPointItemInfo);
	tmpItemForLog.UniqueNumber			= 0;
	tmpItemForLog.AccountUniqueNumber	= m_character.AccountUniqueNumber;
	tmpItemForLog.Possess				= m_character.CharacterUniqueNumber;
	tmpItemForLog.Wear					= WEAR_NOT_ATTACHED;
	tmpItemForLog.CurrentCount			= pBuyWarPointItem->Amount;
// 2009-08-25 by cmkwon, 사용하지 않는 필드 제거(td_Store.ScarcityNumber) - 
//	tmpItemForLog.ScarcityNumber		= 0;
	tmpItemForLog.ItemWindowIndex		= POS_INVALID_POSITION;
	tmpItemForLog.PrefixCodeNum			= 0;
	tmpItemForLog.SuffixCodeNum			= 0;
	tmpItemForLog.NumOfEnchants			= 0;
	CAtumLogSender::SendLogMessageITEMBuyITEM(this, &tmpItemForLog, pBuyWarPointItem->Amount, this->m_character.WarPoint, TRUE);
	
	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	//enum ITEM_BUY_CASH_PRICE_TYPE{BUY_TYPE_SPI=1,BUY_TYPE_WARPOINT,BUY_TYPE_CASH,BUY_TYPE_INFINITY};
	CAtumLogSender::SendLogMessageITEMBuyCashPrice(this, &tmpItemForLog, pBuyWarPointItem->Amount, n64LogSpend, FALSE, BUY_TYPE_WARPOINT, NULL); // WARPOINT type : 2
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	igLock.auto_unlock_cancel();

	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CAtumLogSender::SendLogMessageGetWarPoint()에 인자(, BYTE i_byWPUpdateTy) 추가
	CAtumLogSender::SendLogMessageGetWarPoint(this, n64SumOfPrice, this->m_character.WarPoint, this->m_character.CumulativeWarPoint, WPUT_SHOP);
	// 2007-05-16 by dhjin, DB에 업데이트
	QPARAM_UPDATE_WARPOINT *pQparam = new QPARAM_UPDATE_WARPOINT;
	pQparam->CharacterUID		= this->m_character.CharacterUniqueNumber;
	pQparam->AccountUID			= this->m_character.AccountUniqueNumber;
	pQparam->TotalWarPoint		= this->m_character.WarPoint;
	pQparam->CumulativeWarPoint	= this->m_character.CumulativeWarPoint;
	this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateWarPoint, this, this->m_character.AccountUniqueNumber, pQparam);

	// 2007-05-16 by dhjin, 클라이언트에게 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_SHOP_BUY_WARPOINT_ITEM_OK, T_FC_SHOP_BUY_WARPOINT_ITEM_OK, pMsg, SendBuf);
	pMsg->PayWarPoint				= n64SumOfPrice;
	pMsg->WarPoint					= this->m_character.WarPoint;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_BUY_WARPOINT_ITEM_OK));

	// 2014-03-20 by jekim, GLog 워포통계
#if defined(TEST140)
	if(1)
#else
	if(!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
#endif
	{
		MSG_FL_LOG_ITEM LogItemParameter;
		MEMSET_ZERO(&LogItemParameter, sizeof(LogItemParameter));
		LogItemParameter.LogType			= GLOG_IL_LT_WARPOINT_DEL; 
		LogItemParameter.Count1				= (UID64_t)n64SumOfPrice;
		LogItemParameter.Count2				= (UID64_t)this->m_character.WarPoint;
		LogItemParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
		LogItemParameter.CharLv				= (int)m_character.Level;
		LogItemParameter.GameServerID		= g_pFieldGlobal->GetMGameServerID();
		CAtumLogSender::SendLogItem(&LogItemParameter);
	}
	// end 2014-03-20 by jekim, GLog 워포통계

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::Process_FC_SHOP_CHECK_GIVE_TARGET(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2007-11-13 by cmkwon, 선물하기 기능 추가 - CFieldIOCPSocket::Process_FC_SHOP_CHECK_GIVE_TARGET() 추가
/// \author		cmkwon
/// \date		2007-11-13 ~ 2007-11-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_CHECK_GIVE_TARGET(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_CHECK_GIVE_TARGET,
									MSG_FC_SHOP_CHECK_GIVE_TARGET, pRMsg);

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - T_FC_SHOP_CHECK_GIVE_TARGET
	LowercaseOnly_i_forTurkish(pRMsg->GiveTargetCharName, SIZE_MAX_CHARACTER_NAME);

	MEMSET_ZERO(&m_giveTargetCharacter, sizeof(m_giveTargetCharacter));				// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 초기화

	if(FALSE == IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_INVALID_CHARACTER, 100);
		return RES_BREAK;
	}

// 2009-03-02 by cmkwon, 선물하기 모든 서비스 가능하게 수정 - 기존에는 한국 서비스만 가능하였음.
// 	if(LANGUAGE_TYPE_KOREAN != g_pFieldGlobal->GetLanguageType())
// 	{// 2007-11-15 by cmkwon, 선물하기는 한국만 서비스 된다.
// 		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_COMMON_SERVICE_TEMPORARILY_PAUSED, 110);
// 		return RES_BREAK;
// 	}

	if(0 == stricmp("", pRMsg->GiveTargetCharName))
	{
		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_PROTOCOL_EMPTY_CHARACTERNAME, 111);
		return RES_BREAK;
	}

	if(0 == stricmp(m_character.CharacterName, pRMsg->GiveTargetCharName))
	{// 2007-11-15 by cmkwon, 자기자신에게 ㅅ너물하기 불가
		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_COMMON_NOT_ALLOWED_TO_MYSELF, 112);
		return RES_BREAK;
	}

	ITEM *pGiftItem = ms_pFieldIOCP->GetItemInfo(pRMsg->GiveItemNum);
	if(NULL == pGiftItem
		|| FALSE == COMPARE_BIT_FLAG(pGiftItem->ItemAttribute, ITEM_ATTR_CASH_ITEM))
	{// 2007-11-14 by cmkwon, 선물하기는 유료아이템만 가능하다

		// 2013-09-06 by bckim, 베트남서버 다운 및 해킹정보남기기
		//SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_PROTOCOL_NO_SUCH_ITEM, 101, pGiftItem->ItemNum);
		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_PROTOCOL_NO_SUCH_ITEM, 101, pRMsg->GiveItemNum);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! MSG_FC_SHOP_CHECK_GIVE_TARGET Command Using: HackingIP(%15s),CharName(%s)>>>TargetCharName(%s),ItemNum(%d)\r\n",
			this->GetPeerIP(),m_character.CharacterName,pRMsg->GiveTargetCharName,pRMsg->GiveItemNum);
		// End. 2013-09-06 by bckim, 베트남서버 다운 및 해킹정보남기기
		return RES_BREAK;
	}

	if(ITEMKIND_COLOR_ITEM == pGiftItem->Kind
		|| CASH_ITEMKIND_COLOR_ITEM == pGiftItem->SummonMonster
// 2008-10-20 by cmkwon, 멥버쉽 아이템 체크 ItemAttribute 로 처리 - 
//		|| CASH_ITEMKIND_PREMIUM_CARD == pGiftItem->SummonMonster)
		|| COMPARE_BIT_FLAG(pGiftItem->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
	{// 2007-11-14 by cmkwon, 아머컬러아이템,멤버쉽은 선물하기 불가
		SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_CANNOT_PUT_ITEM, 102, pGiftItem->ItemNum);
		return RES_BREAK;
	}

	STRNCPY_MEMSET(m_giveTargetCharacter.CharacterName0, pRMsg->GiveTargetCharName, SIZE_MAX_CHARACTER_NAME);	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 
	m_giveTargetCharacter.BuyItemNum = pRMsg->GiveItemNum;

	QPARAM_CHECK_GiveTarget *pQParam = new QPARAM_CHECK_GiveTarget;
	*pQParam		= *pRMsg;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckGiveTarget, this, this->m_character.AccountUniqueNumber, pQParam);
	return RES_RETURN_TRUE;
}

// 2013-05-09 by hskim, 세력 포인트 개선
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_INFLUENCE_BUFF(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_INFLUENCE_BUFF, MSG_FC_SHOP_INFLUENCE_BUFF, pRMsg);

	int iLastSkillNum = 0;
	int arSkillNum[] = { 0, 0, CONSECUTIVE_VICTORIES_BUFF_SKILL_2ND, CONSECUTIVE_VICTORIES_BUFF_SKILL_3RD, CONSECUTIVE_VICTORIES_BUFF_SKILL_4TH, CONSECUTIVE_VICTORIES_BUFF_SKILL_5TH, CONSECUTIVE_VICTORIES_BUFF_SKILL_6TH, CONSECUTIVE_VICTORIES_BUFF_SKILL_7TH, CONSECUTIVE_VICTORIES_BUFF_SKILL_8TH };

	if(FALSE == IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_SHOP_INFLUENCE_BUFF, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if( !COMPARE_INFLUENCE(m_character.InfluenceType, (INFLUENCE_TYPE_VCN | INFLUENCE_TYPE_ANI)) )
	{
		SendErrorMessage(T_FC_SHOP_INFLUENCE_BUFF, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED);
		return RES_BREAK;
	}

	if( pRMsg->nConsecutiveVictories != ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(m_character.InfluenceType) )
	{
		SendErrorMessage(T_FC_SHOP_INFLUENCE_BUFF, ERR_PROTOCOL_RACE_PERMISSION_DENIED);
		return RES_BREAK;
	}

	if( IsInvisibleCharacter() )
	{
		SendErrorMessage(T_FC_SHOP_INFLUENCE_BUFF, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	for(int i=0; i<=pRMsg->nConsecutiveVictories; i++)
	{
		if( pRMsg->nConsecutiveVictories < 0 || pRMsg->nConsecutiveVictories > 8 ) break;
		if( 0 == arSkillNum[i] ) continue;

		if( TRUE == this->ApplyBuffSkill(arSkillNum[i]) )
		{
			iLastSkillNum = arSkillNum[i];
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_SHOP_INFLUENCE_BUFF_OK, T_FC_SHOP_INFLUENCE_BUFF_OK, pMsg, SendBuf);
	pMsg->nLastSkillNum = iLastSkillNum;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_INFLUENCE_BUFF_OK));

	return RES_RETURN_TRUE;
}
// end 2013-05-09 by hskim, 세력 포인트 개선

void CFieldIOCPSocket::SendString128Static(BYTE string128_type, char* pFormat, ...)
{
	if (string128_type < m_STRING_128_print_level)
	{
		return;
	}
	char szStrTemp[1024];
	int nHeaderSize = 0;
	MEMSET_ZERO(szStrTemp, 1024);
	if (string128_type == STRING_128_DEBUG_L1)
	{
		strcpy(szStrTemp, "[D1]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_DEBUG_L2)
	{
		strcpy(szStrTemp, "[D2]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_DEBUG_L3)
	{
		strcpy(szStrTemp, "[D3]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_ADMIN_CMD)
	{
		strcpy(szStrTemp, "[A]");
		nHeaderSize = 3;
	}

	va_list args;
	va_start(args, pFormat);
	vsprintf(szStrTemp+nHeaderSize, pFormat, args);
    va_end(args);

	// start 2011-06-22 by hskim, 사설 서버 방지
	WORD wSecurityNumber = ms_pFieldIOCP->m_pSecurityManager->GetSecurityNumber();
	// end 2011-06-22 by hskim, 사설 서버 방지

	int nStrLen = strlen(szStrTemp);
	if(128 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 128);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
	}
	else if(256 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_256, T_FC_STRING_256, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 256);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_256));
	}
	else if(512 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
	}
	else
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));

		char szErrStr[1024];
 		wsprintf(szErrStr, "  Error: String Too Long For STRING_XXX(Length:%d, %s)\r\n", nStrLen, szStrTemp);
		g_pFieldGlobal->WriteSystemLog(szErrStr);
		DbgOut(szErrStr);
	}

// 2006-04-13 by cmkwon
// 	int nHeaderSize = 0;
// 	INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
// 	MsgStr->PrintType = STR128_PRINT_TYPE_STATIC;
// 	if (string128_type == STRING_128_DEBUG_L1)
// 	{
// 		strcpy(MsgStr->String, "[D1]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_DEBUG_L2)
// 	{
// 		strcpy(MsgStr->String, "[D2]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_DEBUG_L3)
// 	{
// 		strcpy(MsgStr->String, "[D3]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_ADMIN_CMD)
// 	{
// 		strcpy(MsgStr->String, "[A]");
// 		nHeaderSize = 3;
// 	}
// 
// 	va_list args;
// 	va_start(args, pFormat);
// 	vsprintf(MsgStr->String+nHeaderSize, pFormat, args);
// 	int ret = GDeleteNewLine(MsgStr->String);	// delete newline character(s)
// 	if (ret < 128)
// 	{
// 		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
// 	}
// 	else
// 	{
// 		MsgStr->String[127] = '\0';
// 		DBGOUT("  Error: String Too Long For STRING_128(ret: %d): %s\r\n", ret, MsgStr->String);
// 		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
// 	}
// 	va_end(args);

// check: static string128은 찍지 말자, 20031203, kelovon
//	if (string128_type == STRING_128_ADMIN_CMD)
//	{
//		DBGOUT2(DO2_SYSLOG|DO2_DBGOUT, "	SendString128 %s: %s\r\n",
//			GetCharacterString(&m_character, string()),
//			MsgStr->String);
//	}
}

void CFieldIOCPSocket::SendString128(BYTE string128_type, char* pFormat, ...)
{
	if (string128_type < m_STRING_128_print_level)
	{
		return;
	}

	// start 2011-06-22 by hskim, 사설 서버 방지
	WORD wSecurityNumber = ms_pFieldIOCP->m_pSecurityManager->GetSecurityNumber();
	// end 2011-06-22 by hskim, 사설 서버 방지

	char szStrTemp[1024];
	int nHeaderSize = 0;
	MEMSET_ZERO(szStrTemp, 1024);
	if (string128_type == STRING_128_DEBUG_L1)
	{
		strcpy(szStrTemp, "[D1]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_DEBUG_L2)
	{
		strcpy(szStrTemp, "[D2]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_DEBUG_L3)
	{
		strcpy(szStrTemp, "[D3]");
		nHeaderSize = 4;
	}
	else if (string128_type == STRING_128_ADMIN_CMD)
	{
		strcpy(szStrTemp, "[A]");
		nHeaderSize = 3;
	}

	va_list args;
	va_start(args, pFormat);
	vsprintf(szStrTemp+nHeaderSize, pFormat, args);
    va_end(args);

	int nStrLen = strlen(szStrTemp);

	if ( STRING_128_USER_OPERATOR != string128_type )	// 2013-10-02 by bckim, 보스몬스터 보상강화 스트링 보완작업
	{
	if(128 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 128);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
	}
	else if(256 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_256, T_FC_STRING_256, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 256);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_256));
	}
	else if(512 > nStrLen)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
	}
	else
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));

		char szErrStr[1024];
 		wsprintf(szErrStr, "  Error: String Too Long For STRING_XXX(Length:%d, %s)\r\n", nStrLen, szStrTemp);
		g_pFieldGlobal->WriteSystemLog(szErrStr);
		DbgOut(szErrStr);
	}
	}


	// start 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어
	if( STRING_128_DEBUG_PRINT == string128_type )
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_DBGOUT;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
		MsgStr->SecurityNumber = wSecurityNumber;		// 2011-06-22 by hskim, 사설 서버 방지
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
	}
	// end 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어
	// start 2012-03-30 by hskim, EP4 트리거 시스템 이벤트 알림
	else if( STRING_128_SYSTEM_NOTICE == string128_type )
	{
		if(128 > nStrLen)
		{
		INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
		MsgStr->PrintType = STR128_PRINT_TYPE_NOTICE;
		STRNCPY_MEMSET(MsgStr->String, szStrTemp, 128);
		MsgStr->SecurityNumber = wSecurityNumber;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
		}
		else if(256 > nStrLen)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_256, T_FC_STRING_256, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_NOTICE;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 256);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_256));
		}
		else
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_NOTICE;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
		}
	}
	// end 2012-03-30 by hskim, EP4 트리거 시스템 이벤트 알림
	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 팝업으로 알림
	else if ( STRING_128_USER_POPUP == string128_type )
	{
		if(128 > nStrLen)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_POPUP;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 128);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
		}
		else if(256 > nStrLen)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_256, T_FC_STRING_256, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_POPUP;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 256);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_256));
		}
		else
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_POPUP;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
		}
	}
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 팝업으로 알림

	// 2013-10-02 by bckim, 보스몬스터 보상강화 스트링 보완작업 
	else if ( STRING_128_USER_OPERATOR == string128_type )
	{
		if(128 > nStrLen)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_OPERATOR;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 128);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
		}
		else if(256 > nStrLen)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_256, T_FC_STRING_256, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_OPERATOR;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 256);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_256));
		}
		else
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_STRING_512, T_FC_STRING_512, MsgStr, SendBuf);
			MsgStr->PrintType = STR128_PRINT_TYPE_OPERATOR;
			STRNCPY_MEMSET(MsgStr->String, szStrTemp, 512);
			MsgStr->SecurityNumber = wSecurityNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_512));
		}
	}
	// End. 2013-10-02 by bckim, 보스몬스터 보상강화 스트링 보완작업

	if (string128_type == STRING_128_ADMIN_CMD)
	{
		DBGOUT2(DO2_SYSLOG, "	SendString128 %s: %s\r\n",
			GetCharacterString(&m_character, string()),
			szStrTemp);
	}

// 2006-04-13 by cmkwon, 위의 코드로 수정함
// 	int nHeaderSize = 0;
// 	INIT_MSG_WITH_BUFFER(MSG_FC_STRING_128, T_FC_STRING_128, MsgStr, SendBuf);
// 	MsgStr->PrintType = STR128_PRINT_TYPE_CHAT;
// 	if (string128_type == STRING_128_DEBUG_L1)
// 	{
// 		strcpy(MsgStr->String, "[D1]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_DEBUG_L2)
// 	{
// 		strcpy(MsgStr->String, "[D2]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_DEBUG_L3)
// 	{
// 		strcpy(MsgStr->String, "[D3]");
// 		nHeaderSize = 4;
// 	}
// 	else if (string128_type == STRING_128_ADMIN_CMD)
// 	{
// 		strcpy(MsgStr->String, "[A]");
// 		nHeaderSize = 3;
// 	}
// 
// 	va_list args;
// 	va_start(args, pFormat);
// 	vsprintf(MsgStr->String+nHeaderSize, pFormat, args);
// 	int ret = GDeleteNewLine(MsgStr->String);	// delete newline character(s)
// 	if (ret < 128)
// 	{
// 		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
// 	}
// 	else
// 	{
// 		MsgStr->String[127] = '\0';
// 		DBGOUT("  Error: String Too Long For STRING_128(ret: %d): %s\r\n", ret, MsgStr->String);
// 		SendAddData(SendBuf, MSG_SIZE(MSG_FC_STRING_128));
// 	}
// 	va_end(args);
// 
// 	if (string128_type == STRING_128_ADMIN_CMD)
// 	{
// 		DBGOUT2(DO2_SYSLOG, "	SendString128 %s: %s\r\n",
// 			GetCharacterString(&m_character, string()),
// 			MsgStr->String);
// 	}
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_REQUEST_INVITE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_REQUEST_INVITE,
									MSG_FC_PARTY_REQUEST_INVITE, pMsgReqInvite);

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - T_FC_PARTY_REQUEST_INVITE
	LowercaseOnly_i_forTurkish(pMsgReqInvite->CharacterName, SIZE_MAX_CHARACTER_NAME);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-08-01 by cmkwon, 개인 상점 체크
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_USING_BAZAAR, 0);
		return RES_BREAK;
	}

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (NULL == pFParty)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}

	mt_auto_lock pmlock(&pFParty->m_ListPartyMember);

	if (pFParty->GetMasterCharacterUniqueNumber() != m_character.CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_PARTY_MASTER_NOT_MATCHED);
		return RES_BREAK;
	}

	if (pFParty->m_FieldPartyInfo.nTotalPartyMember >= SIZE_MAX_PARTY_MEMBER)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_ALREADY_MAX_PARTY_MEMBER);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pInvitee = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pMsgReqInvite->CharacterName);
	if (NULL == pInvitee
		|| FALSE == pInvitee->IsUsing())
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_COMMON_NO_SUCH_CHARACTER, 0, 0, pMsgReqInvite->CharacterName);
		return RES_BREAK;
	}

//	// check: 레벨 차이 확인, 경험치 분배 쪽으로 옮기기
//	if (abs(pInvitee->m_character.Level - m_character.Level) > 6)
//	{
//		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED, abs(pInvitee->m_character.Level - m_character.Level));
//		return RES_BREAK;
//	}

	if(BAZAAR_STATE_NONE != pInvitee->m_bazaarManager.GetBazaarState())
	{// 2006-07-31 by cmkwon, 개인 상점 체크 
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_USING_BAZAAR, 1);
		return RES_BREAK;
	}

	if (FALSE == pInvitee->IsValidCharacter()
		|| COMPARE_BODYCON_BIT(pInvitee->m_character.BodyCondition, BODYCON_DEAD_MASK|BODYCON_EVENT_HANDLE_MASK))
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_CANNOT_INVITE_USER);
		return RES_BREAK;
	}

	// 2005-12-07 by cmkwon, 세력체크
	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_PARTY_JOIN, m_character.Race, m_character.InfluenceType,
		pInvitee->GetCharacter()->Race, pInvitee->GetCharacter()->InfluenceType))
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_CANNOT_INVITE_USER);
		return RES_BREAK;
	}

	if (pInvitee->m_pFieldParty != NULL)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_INVITE, ERR_PROTOCOL_CANNOT_INVITE_USER);
		return RES_BREAK;
	}

	// send message to invitee...
	INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_REQUEST_INVITE_QUESTION, T_FC_PARTY_REQUEST_INVITE_QUESTION, pQuestion, pQuestionBuf);
	pQuestion->PartyID = pFParty->m_PartyID;
	STRNCPY_MEMSET(pQuestion->MasterCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pInvitee->SendAddData(pQuestionBuf, MSG_SIZE(MSG_FC_PARTY_REQUEST_INVITE_QUESTION));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_ACCEPT_INVITE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_ACCEPT_INVITE,
									MSG_FC_PARTY_ACCEPT_INVITE, pMsgAccept);

	// lock m_MapParties
	mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);

	CFieldParty *pParty = ms_pFieldIOCP->m_MapParties.findLock(pMsgAccept->PartyID);
	if (pParty == NULL)
	{
		SendErrorMessage(T_FC_PARTY_ACCEPT_INVITE, ERR_PROTOCOL_NO_SUCH_PARTY, LODWORD(pMsgAccept->PartyID), HIDWORD(pMsgAccept->PartyID));
		return RES_BREAK;
	}

	mt_auto_lock pmlock(&pParty->m_ListPartyMember);

	FieldPartyMember tmpMember;
	if ( TRUE == pParty->GetMemberByCharacterUniqueNumber(m_character.CharacterUniqueNumber, tmpMember)
		|| NULL != m_pFieldParty)
	{
		SendErrorMessage(T_FC_PARTY_ACCEPT_INVITE, ERR_PROTOCOL_PARTY_MEMBER_ALREADY_EXISTS);
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0077);
		return RES_BREAK;
	}

	if (pParty->GetMasterCharacterUniqueNumber() == m_character.CharacterUniqueNumber)
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0078);
		return RES_BREAK;
	}

	if (pParty->m_PeerBattlePartyID != 0 || pParty->m_PeerBattleRequesterPartyID != 0)
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0079);
		return RES_BREAK;
	}

	if (pParty->m_FieldPartyInfo.nTotalPartyMember >= SIZE_MAX_PARTY_MEMBER)
	{
		SendErrorMessage(T_FC_PARTY_ACCEPT_INVITE, ERR_PROTOCOL_ALREADY_MAX_PARTY_MEMBER);
		return RES_BREAK;
	}

	// 파티원 및 필드 서버들에게 PARTY_ACCEPT_INVITE_OK를 보내도록 IM Server에 요청한다.
	INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_ACCEPT_INVITE_OK, T_FI_PARTY_ACCEPT_INVITE_OK, msgAcceptInviteOK, msgAcceptInviteOKBuf);
	msgAcceptInviteOK->PartyID = pMsgAccept->PartyID;
	msgAcceptInviteOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	msgAcceptInviteOK->FieldPartyInfo.nTotalPartyMember = 0;	// 이 MSG가 F->I일 때는 무시함
	msgAcceptInviteOK->FieldPartyInfo.lowestMemberLevel = 0;	// 이 MSG가 F->I일 때는 무시함
	ms_pFieldIOCP->m_pIMWinSocket->Write((char*)msgAcceptInviteOKBuf, MSG_SIZE(MSG_FI_PARTY_ACCEPT_INVITE_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_REJECT_INVITE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_REJECT_INVITE,
									MSG_FC_PARTY_REJECT_INVITE, pMsgReject);

	// lock m_MapParties
	mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);

	CFieldParty *pParty = ms_pFieldIOCP->m_MapParties.findLock(pMsgReject->PartyID);
	if (pParty == NULL)
	{
		SendErrorMessage(T_FC_PARTY_REJECT_INVITE, ERR_PROTOCOL_NO_SUCH_PARTY, LODWORD(pMsgReject->PartyID), HIDWORD(pMsgReject->PartyID));
		return RES_BREAK;
	}

	mt_auto_lock pmlock(&pParty->m_ListPartyMember);

	// send message to master...
	CFieldIOCPSocket *pMasterSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pParty->GetMasterCharacterUniqueNumber());
	if (pMasterSocket == NULL)
	{
		SendErrorMessage(T_FC_PARTY_REJECT_INVITE, ERR_COMMON_NO_SUCH_CHARACTER, pParty->GetMasterCharacterUniqueNumber());
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_REJECT_INVITE_OK, T_FC_PARTY_REJECT_INVITE_OK, pRejectOK, pRejectOKBuf);
	pRejectOK->PartyID = pRejectOK->PartyID;
	STRNCPY_MEMSET(pRejectOK->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pMasterSocket->SendAddData(pRejectOKBuf, MSG_SIZE(MSG_FC_PARTY_REJECT_INVITE_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_GET_MEMBER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_GET_MEMBER,
									MSG_FC_PARTY_GET_MEMBER, pMsgGetMember);

	CFieldParty *pFParty = this->m_pFieldParty;		// 2006-04-17 by cmkwon
	if (pFParty == NULL)
	{
		SendErrorMessage(T_FC_PARTY_GET_MEMBER, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}

	mt_auto_lock pmlock(&pFParty->m_ListPartyMember);
	FieldPartyMember retMember;
	if (FALSE == pFParty->GetMemberByCharacterUniqueNumber(pMsgGetMember->CharacterUniqueNumber, retMember))
	{
		SendErrorMessage(T_FC_PARTY_GET_MEMBER, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER, pMsgGetMember->CharacterUniqueNumber);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(pMsgGetMember->CharacterUniqueNumber);
	if (NULL == pSocket || pSocket->m_pCurrentFieldMapChannel !=  m_pCurrentFieldMapChannel ||
		COMPARE_BODYCON_BIT(pSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
	)
	{
		SendErrorMessage(T_FC_PARTY_GET_MEMBER, ERR_PROTOCOL_GET_MEMBER_FAIL, pMsgGetMember->CharacterUniqueNumber);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_PUT_MEMBER, T_FC_PARTY_PUT_MEMBER, pPutMember, pPutMemberBuf);
	pPutMember->FieldMemberInfo = pSocket->m_character;
	SendAddData(pPutMemberBuf, MSG_SIZE(MSG_FC_PARTY_PUT_MEMBER));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_GET_ALL_MEMBER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_GET_ALL_MEMBER,
									MSG_FC_PARTY_GET_ALL_MEMBER, pMsgGetAllMember);

	///////////////////////////////////////////////////////////////////////////
	// check: 필요하면 지원함, 20031005
	///////////////////////////////////////////////////////////////////////////
	SendString128(STRING_128_USER_NOTICE, "모든 파티원 정보 가져오기는 지원되지 않음!");

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_REQUEST_PARTY_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_PARTY_REQUEST_PARTY_WARP	*pMsgPartyWarp = NULL;

	nRecvTypeSize = sizeof(MSG_FC_PARTY_REQUEST_PARTY_WARP)
					+ ((MSG_FC_PARTY_REQUEST_PARTY_WARP*)(pPacket+nBytesUsed))->nPartyMembers*sizeof(UINT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14047);
		return RES_RETURN_FALSE;
	}
	pMsgPartyWarp = (MSG_FC_PARTY_REQUEST_PARTY_WARP*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldParty *pFParty = this->m_pFieldParty;		// 2006-04-17 by cmkwon
	if (pFParty == NULL)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}
// 2007-02-12 by cmkwon, 아래와 같이 함수로 처리함
//	mt_auto_lock pmlock(&pFParty->m_ListPartyMember);
//
//	if (m_character.CharacterUniqueNumber != pFParty->GetMasterCharacterUniqueNumber())
	if(FALSE == this->IsPartyMaster())
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_PARTY_PERMISSION_DENIED);
		return RES_BREAK;
	}

	// 타일 정보 찾기
	EVENTINFO *pEventInfo
		= m_pCurrentFieldMapChannel->GetTileEventInfoW(&m_character.PositionVector);

	if (pEventInfo
		&& pEventInfo->m_bEventType == EVENT_TYPE_WARP
		&& COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_FLY_MASK) == TRUE)
	{

		CMapProject *pMapProject = ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(pEventInfo->m_EventwParam3);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_PARTY_REQUEST_PARTY_WARP#, 세력별 도시맵
		if(INFLUENCE_CITY_MAP_INDEX == pEventInfo->m_EventwParam3)
		{
			pMapProject = this->GetCityFieldMapProjectPtr();
		}
		if(COMPARE_INFLUENCE(m_character.InfluenceType, pEventInfo->m_nObejctMonsterUnitKind))
		{// 2009-10-13 by cmkwon, 워프게이트 이용 불가 세력 체크
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pEventInfo->m_nObejctMonsterUnitKind);
			return RES_BREAK;			
		}

		if (pMapProject == NULL)
		{
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);
			return RES_BREAK;
		}

		Err_t err = this->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp);
		if(ERR_NO_ERROR != err)
		{// 2006-11-02 by cmkwon
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, err);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2006-11-02 by cmkwon
		MAP_CHANNEL_INDEX beforeMapChannIndex = m_character.MapChannelIndex;

		//////////////////////////////////////////
		// 파티장 워프 처리
		//////////////////////////////////////////
		EventResult_t ret = HandleEvent(pEventInfo);

		// event result에 대한 작업
		if (ret == EVENT_RESULT_BREAK)
		{
#ifdef _DEBUG
			DBGOUT(STRERR_S_F2NOTIFY_0005,
				pEventInfo->m_bEventType, GetCharacterString(&m_character, string()));
#endif
			return RES_BREAK;
		}
		else if (ret == EVENT_RESULT_CONTINUE)
		{
			// do nothing
		}
		else if (ret == EVENT_RESULT_CLOSE_CONNECTION)
		{
			// do nothing
			// check: 맵 에러 처리
			//SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO, eventType, ret);
#ifdef _DEBUG
			SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0081);
			g_pFieldGlobal->WriteSystemLogEX(FALSE, STRERR_S_F2NOTIFY_0006,
				m_character.AccountName, m_character.CharacterName, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_nMapIndex,
				pEventInfo->m_EventwParam3, pEventInfo->m_EventwParam2);
#else
			Close(0x14026);
			return RES_RETURN_FALSE;
#endif
		}
		else
		{
			// error
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO, pEventInfo->m_bEventType, ret);
			return RES_BREAK;
		}

		//////////////////////////////////////////
		// 파티원 워프 처리, 파티장은 제외함
		//////////////////////////////////////////
		UID32_t *ArrCharacterUniqueNumber = (UID32_t*)(((char*)pMsgPartyWarp) + sizeof(MSG_FC_PARTY_REQUEST_PARTY_WARP));
		for (int i = 0; i < pMsgPartyWarp->nPartyMembers; i++)
		{
			CFieldIOCPSocket *pMemberSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(ArrCharacterUniqueNumber[i]);
			if (NULL == pMemberSock
				|| FALSE == pMemberSock->IsValidCharacter())
			{
// 2006-11-02 by cmkwon
//				SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER);
				continue;
			}

			if(FALSE == beforeMapChannIndex.IsSameMapChannelIndex(pMemberSock->GetCharacter()->MapChannelIndex))
			{// 2006-11-02 by cmkwon, 같은맵에 있었는지 체크
				continue;
			}

			err = pMemberSock->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp);
			if(ERR_NO_ERROR != err)
			{// 2006-11-02 by cmkwon
				pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP, err);
				continue;
			}

			EventResult_t ret = pMemberSock->HandleEvent(pEventInfo);

			// event result에 대한 작업
			if (ret == EVENT_RESULT_BREAK)
			{
#ifdef _DEBUG
				DBGOUT(STRERR_S_F2NOTIFY_0007,
					GetCharacterString(&m_character, string()));
#endif
				continue;
			}
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME(const char* pPacket, int nLength, int &nBytesUsed)
{
	int												nRecvTypeSize = 0;
	MSG_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME	*pMsgPartyWarpMap = NULL;

	nRecvTypeSize = sizeof(MSG_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME)
					+ ((MSG_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME*)(pPacket+nBytesUsed))->nPartyMembers*sizeof(UINT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14047);
		return RES_RETURN_FALSE;
	}
	pMsgPartyWarpMap = (MSG_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pFParty == NULL)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}

// 2007-02-12 by cmkwon, 아래와 같이 함수로 처리함
//	mt_auto_lock pmlock(&pFParty->m_ListPartyMember);
//
//	if (m_character.CharacterUniqueNumber != pFParty->GetMasterCharacterUniqueNumber())
	if(FALSE == this->IsPartyMaster())
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, ERR_PROTOCOL_PARTY_PERMISSION_DENIED);
		return RES_BREAK;
	}

	CMapProject *pMapProject
		= ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(pMsgPartyWarpMap->MapChannelIndex.MapIndex);
	if (pMapProject == NULL)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);
		return RES_BREAK;
	}

	Err_t err = this->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp);
	if(ERR_NO_ERROR != err)
	{// 2006-11-02 by cmkwon
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, err);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-02 by cmkwon
	MAP_CHANNEL_INDEX beforeMapChannIndex = m_character.MapChannelIndex;

	//////////////////////////////////////////
	// 파티장에게 워프 전송
	//////////////////////////////////////////
	EventResult_t ret = WarpToMap(pMsgPartyWarpMap->MapChannelIndex);
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(109) : %10s SocketIndex[%4d] Map(%4d)	Position(%5d, %5d, %5d)\r\n",
		m_character.CharacterName, m_character.ClientIndex, m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
		(int)m_character.PositionVector.y, (int)m_character.PositionVector.z);
	g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);

	// event result에 대한 작업
	if (ret == EVENT_RESULT_BREAK)
	{
#ifdef _DEBUG
		DBGOUT(STRERR_S_F2NOTIFY_0008,
			EVENT_TYPE_WARP,
			GetCharacterString(&m_character, string())
		);

		return RES_BREAK;
#endif
	}

	//////////////////////////////////////////
	// 멤버들에게 워프 전송, 파티장은 제외함
	//////////////////////////////////////////
	UID32_t *ArrCharacterUniqueNumber = (UID32_t*)(((char*)pMsgPartyWarpMap) + sizeof(MSG_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME));
	for (int i = 0; i < pMsgPartyWarpMap->nPartyMembers; i++)
	{
		CFieldIOCPSocket *pMemberSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(ArrCharacterUniqueNumber[i]);
		if (NULL == pMemberSock
			|| FALSE == pMemberSock->IsValidCharacter())
		{
// 2006-11-02 by cmkwon, 필요 없음
//			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER);
			continue;
		}

		if(FALSE == beforeMapChannIndex.IsSameMapChannelIndex(pMemberSock->GetCharacter()->MapChannelIndex))
		{// 2006-11-02 by cmkwon, 같은맵에 있었는지 체크
			continue;
		}

		err = pMemberSock->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp);
		if(ERR_NO_ERROR != err)
		{// 2006-11-02 by cmkwon
			pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME, err);
			continue;
		}

		EventResult_t ret = pMemberSock->WarpToMap(pMsgPartyWarpMap->MapChannelIndex);
		// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
		char szSystemLog[1024];
		sprintf(szSystemLog, "[Notify] WarpToMap(110) : %10s SocketIndex[%4d] Map(%4d)	Position(%5d, %5d, %5d)\r\n",
			pMemberSock->m_character.CharacterName, pMemberSock->m_character.ClientIndex, pMemberSock->m_character.MapChannelIndex.MapIndex, (int)pMemberSock->m_character.PositionVector.x,
			(int)pMemberSock->m_character.PositionVector.y, (int)pMemberSock->m_character.PositionVector.z);
		g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);

		// event result에 대한 작업
		if (ret == EVENT_RESULT_BREAK)
		{
#ifdef _DEBUG
			DBGOUT(STRERR_S_F2NOTIFY_0009,
				pMsgPartyWarpMap->MapChannelIndex.MapIndex,
				GetCharacterString(&m_character, string())
			);
#endif
			continue;
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize = 0;
	MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT	*pMsgPartyObjectEvent = NULL;

	nRecvTypeSize = sizeof(MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT)
					+ ((MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT*)(pPacket+nBytesUsed))->nPartyMembers*sizeof(UINT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14047);
		return RES_RETURN_FALSE;
	}
	pMsgPartyObjectEvent = (MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(NULL == pFParty)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}

// 2007-02-12 by cmkwon, 필요없음	mt_auto_lock pmlock(&pFParty->m_ListPartyMember);

	D3DXVECTOR3	tmVec3 = A2DX(pMsgPartyObjectEvent->ObjectPosition);
	EVENTINFO *pEventInfo = m_pCurrentFieldMapChannel->GetEventInfoByObjectTypeAndDistanceW(pMsgPartyObjectEvent->ObjectType, &tmVec3);
	if(NULL == pEventInfo)
	{
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_TOO_FAR_TO_DO,
			pMsgPartyObjectEvent->ObjectType, 0);
		return RES_BREAK;
	}

// 2007-12-14 by cmkwon, 편대대형 워프는 캐릭터 모드에서는 불가 - 아래와 같이 처리
//	if(EVENT_TYPE_CHARACTERMODE_WARP == pEventInfo->m_bEventType
//		&& FALSE == m_character.CharacterMode)
//	{// 2007-10-15 by cmkwon, 캐릭터모드 워프시 캐릭터모드 체크
//		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_TOO_FAR_TO_DO, pMsgPartyObjectEvent->ObjectType, 100);
//		return RES_BREAK;
//	}
	if(m_character.CharacterMode)
	{// 2007-12-14 by cmkwon, 편대대형 워프는 캐릭터 모드에서는 불가 - 
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED, pMsgPartyObjectEvent->ObjectType, 100);
		return RES_BREAK;
	}

	if (EVENT_TYPE_WARP == pEventInfo->m_bEventType)
// 2007-12-14 by cmkwon, 편대대형 워프는 캐릭터 모드에서는 불가 - 캐릭터모드 워프 체크 필요 없음
//		|| EVENT_TYPE_CHARACTERMODE_WARP == pEventInfo->m_bEventType)
	{
		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
		{
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_INVALID_BODYCONDITION);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////
		//	- WARP는 파티장만이 요청할 수 있다.
		//	- 파티장이 아닌 파티원이 요청하면 무시.
// 2007-02-12 by cmkwon, 아래와 같이 함수로 처리함
// 		if (pFParty->GetMasterCharacterUniqueNumber() != m_character.CharacterUniqueNumber)
		if(FALSE == this->IsPartyMaster())
		{
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_PARTY_MASTER_NOT_MATCHED);
			return RES_BREAK;
		}

		CFieldMapProject *pFieldMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pEventInfo->m_EventwParam3);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT#, 세력별 도시맵으로 워프
		switch(pEventInfo->m_EventwParam3)
		{
		case INFLUENCE_CITY_MAP_INDEX:		pFieldMapProject = this->GetCityFieldMapProjectPtr();			break;
		case INFLUENCE_GARDEN_MAP_INDEX:	pFieldMapProject = this->GetGardenFieldMapProjectPtr();			break;
		}
		if(COMPARE_INFLUENCE(m_character.InfluenceType, pEventInfo->m_nObejctMonsterUnitKind))
		{// 2009-10-13 by cmkwon, 워프게이트 이용 불가 세력 체크
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pEventInfo->m_nObejctMonsterUnitKind);
			return RES_BREAK;			
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2005-11-14 by cmkwon, Warp is possible check
		Err_t	nErrCode	= ERR_NO_ERROR;
		int		nErrParam1	= 0;
		int		nErrParam2	= 0;
		if(NULL == pFieldMapProject)
		{
			nErrCode		= ERR_PROTOCOL_NO_SUCH_MAP_SERVED;
			nErrParam2		= pEventInfo->m_EventwParam3;
		}
		else
		{
			// 2013-11-18 by jhseol, NGC 전전기지 트리거 시스템 - 파티상태에서도 워프제한
#ifdef S_TRIGGER_OUTPOST_JHSEOL
			if (FALSE == ms_pFieldIOCP->GetNextMapWarpPossible(pFieldMapProject->m_nMapIndex) )
			{
				SendString128(STRING_128_USER_NOTICE, STRMSG_130121_0007);
				SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED, pFieldMapProject->m_nMapIndex, 0);
				return RES_BREAK;
			}
#endif
			// end 2013-11-18 by jhseol, NGC 전전기지 트리거 시스템 - 파티상태에서도 워프제한
			nErrCode		= this->IsEnableWarp(pFieldMapProject->GetMapInfluenceType(), pFieldMapProject->IsConflictAreaMap(), pFieldMapProject->m_nQuestIndexForWarp, FALSE, pFieldMapProject);		// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
			nErrParam1		= ERR_PROTOCOL_REQ_QUEST_NOT_MATCHED;
			nErrParam2		= pEventInfo->m_EventwParam3;
		}

		if(ERR_NO_ERROR != nErrCode)
		{
			//////////////////////////////////////////
			// 파티장에게 에러 전송
			SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, nErrCode, nErrParam1, nErrParam2);

			//////////////////////////////////////////
			// 파티원 모두에게 에러 전송
			UID32_t *ArrCharacterUniqueNumber = (UID32_t*)(((char*)pMsgPartyObjectEvent) + sizeof(MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT));
			for (int i = 0; i < pMsgPartyObjectEvent->nPartyMembers; i++)
			{
				CFieldIOCPSocket *pMemberSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(ArrCharacterUniqueNumber[i]);
				if (NULL == pMemberSock
					|| FALSE == pMemberSock->IsValidCharacter(FALSE))
				{
					continue;
				}
				pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, nErrCode, nErrParam1, nErrParam2);
			}
			return RES_BREAK;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-08-28 by dhjin, 전진기지 전쟁맵 들어가는것 체크
		// 2007-09-21 by cmkwon, 현재 맵이 전진기지 도시맵이 아닌 경우만 체크
		if(FALSE == IS_OUTPOST_CITY_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex)
			&& IS_MAP_INFLUENCE_OUTPOST(pFieldMapProject->GetMapInfluenceType()) 
			&& FALSE == ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pFieldMapProject->m_nMapIndex))
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-28 by cmkwon, 지도자,부지도자도 같은 세력의 전진기지맵,전진기지도시맵으로 워프 가능
			// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -
			//if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER))
			if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
			{
				if(FALSE == ms_pFieldIOCP->m_OutPostManager.CheckValidGuildUID(pFieldMapProject->m_nMapIndex, m_character.GuildUniqueNumber))
				{
					SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST, pFieldMapProject->m_nMapIndex, 1);
					return RES_BREAK;
				}
			}
			else
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2007-09-28 by cmkwon, 지도자,부지도자의 세력이 해당 전진기지의 소유세력과 같은지 체크
				BYTE byInflTy = ms_pFieldIOCP->m_OutPostManager.GetOutPostInfluenceByMapIndex(pFieldMapProject->m_nMapIndex);
				if(FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, byInflTy))
				{
					SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST, pEventInfo->m_EventwParam3, 2);
					return RES_BREAK;
				}
			}
		}

		// 2007-09-21 by cmkwon, 전진기지 도시맵으로 들어갈 경우 체크
		if(IS_OUTPOST_CITY_MAP_INDEX(pFieldMapProject->m_nMapIndex))
		{
			if(FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
			{
				SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 3);
				return RES_BREAK;
			}

			if(ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pFieldMapProject->m_nMapIndex))
			{
				SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 4);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-28 by cmkwon, 지도자,부지도자도 같은 세력의 전진기지맵,전진기지도시맵으로 워프 가능
			// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -
			//if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER))
			if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
			{			
				if(FALSE == ms_pFieldIOCP->m_OutPostManager.CheckValidGuildUID(m_character.MapChannelIndex.MapIndex, m_character.GuildUniqueNumber))
				{
					SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 5);
					return RES_BREAK;
				}
			}
			else
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2007-09-28 by cmkwon, 지도자,부지도자의 세력이 해당 전진기지의 소유세력과 같은지 체크
				BYTE byInflTy = ms_pFieldIOCP->m_OutPostManager.GetOutPostInfluenceByMapIndex(pFieldMapProject->m_nMapIndex);
				if(FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, byInflTy))
				{
					SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 6);
					return RES_BREAK;
				}
			}

		}
		
		if (FALSE == pFieldMapProject->IsMultiMapChannel(m_character.InfluenceType))
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2006-11-02 by cmkwon
			MAP_CHANNEL_INDEX beforeMapChannIndex = m_character.MapChannelIndex;

			//////////////////////////////////////////
			// 파티장 워프 처리
			CFieldMapChannel *pFMChann = pFieldMapProject->GetFirstFieldMapChannel(TRUE);
			WarpToMap(pFMChann->m_MapChannelIndex, pEventInfo->m_EventwParam2);
			// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
			char szSystemLog[1024];
			sprintf(szSystemLog, "[Notify] WarpToMap(111) : %10s SocketIndex[%4d] Map(%4d)	Position(%5d, %5d, %5d)\r\n",
				m_character.CharacterName, m_character.ClientIndex, m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
				(int)m_character.PositionVector.y, (int)m_character.PositionVector.z);
			g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);

			//////////////////////////////////////////
			// 파티원 워프 처리, 파티장은 제외함
			//////////////////////////////////////////
			UID32_t *ArrCharacterUniqueNumber = (UID32_t*)(((char*)pMsgPartyObjectEvent) + sizeof(MSG_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT));
			for (int i = 0; i < pMsgPartyObjectEvent->nPartyMembers; i++)
			{
				CFieldIOCPSocket *pMemberSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(ArrCharacterUniqueNumber[i]);
				if (NULL == pMemberSock
					|| FALSE == pMemberSock->IsValidCharacter())
				{
// 2006-11-02 by cmkwon, 필요 없음
//					SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER);
					continue;
				}

				if(FALSE == beforeMapChannIndex.IsSameMapChannelIndex(pMemberSock->GetCharacter()->MapChannelIndex))
				{// 2006-11-02 by cmkwon, 같은맵에 있었는지 체크
					continue;
				}

				//////////////////////////////////////////////////////////////////////////
				// 2007-08-28 by dhjin, 전진기지 전쟁맵 들어가는것 체크
				// 2007-09-21 by cmkwon, 현재 맵이 전진기지 도시맵이 아닌 경우만 체크
				if(FALSE == IS_OUTPOST_CITY_MAP_INDEX(pMemberSock->m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex)
					&& IS_MAP_INFLUENCE_OUTPOST(pFieldMapProject->GetMapInfluenceType()) 
					&& FALSE == ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pFieldMapProject->m_nMapIndex))
				{
					///////////////////////////////////////////////////////////////////////////////
					// 2007-09-28 by cmkwon, 지도자,부지도자도 같은 세력의 전진기지맵,전진기지도시맵으로 워프 가능
					// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -
					//if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER))
					if(FALSE == COMPARE_RACE(pMemberSock->m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
					{
						if(FALSE == ms_pFieldIOCP->m_OutPostManager.CheckValidGuildUID(pFieldMapProject->m_nMapIndex, pMemberSock->m_character.GuildUniqueNumber))
						{
							pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST, pFieldMapProject->m_nMapIndex, 1);
							continue;
						}
					}
					else
					{
						///////////////////////////////////////////////////////////////////////////////
						// 2007-09-28 by cmkwon, 지도자,부지도자의 세력이 해당 전진기지의 소유세력과 같은지 체크
						BYTE byInflTy = ms_pFieldIOCP->m_OutPostManager.GetOutPostInfluenceByMapIndex(pFieldMapProject->m_nMapIndex);
						if(FALSE == COMPARE_INFLUENCE(pMemberSock->m_character.InfluenceType, byInflTy))
						{
							pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST, pEventInfo->m_EventwParam3, 2);
							continue;
						}
					}
				}

				// 2007-09-21 by cmkwon, 전진기지 도시맵으로 들어갈 경우 체크
				if(IS_OUTPOST_CITY_MAP_INDEX(pFieldMapProject->m_nMapIndex))
				{
					if(FALSE == IS_VALID_UNIQUE_NUMBER(pMemberSock->m_character.GuildUniqueNumber))
					{
						pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 3);
						continue;
					}

					if(ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pFieldMapProject->m_nMapIndex))
					{
						pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 4);
						continue;
					}

					///////////////////////////////////////////////////////////////////////////////
					// 2007-09-28 by cmkwon, 지도자,부지도자도 같은 세력의 전진기지맵,전진기지도시맵으로 워프 가능
					// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -
					//if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER))
					if(FALSE == COMPARE_RACE(pMemberSock->m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
					{			
						if(FALSE == ms_pFieldIOCP->m_OutPostManager.CheckValidGuildUID(pMemberSock->m_character.MapChannelIndex.MapIndex, pMemberSock->m_character.GuildUniqueNumber))
						{
							pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 5);
							continue;
						}
					}
					else
					{
						///////////////////////////////////////////////////////////////////////////////
						// 2007-09-28 by cmkwon, 지도자,부지도자의 세력이 해당 전진기지의 소유세력과 같은지 체크
						BYTE byInflTy = ms_pFieldIOCP->m_OutPostManager.GetOutPostInfluenceByMapIndex(pFieldMapProject->m_nMapIndex);
						if(FALSE == COMPARE_INFLUENCE(pMemberSock->m_character.InfluenceType, byInflTy))
						{
							pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 6);
							continue;
						}
					}

				}

				///////////////////////////////////////////////////////////////////////////////
				// 2005-11-14 by cmkwon, Warp is possible check
				nErrCode = pMemberSock->IsEnableWarp(pFieldMapProject->GetMapInfluenceType(), pFieldMapProject->IsConflictAreaMap(), pFieldMapProject->m_nQuestIndexForWarp, FALSE, pFieldMapProject);		// 2011-12-19 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
				if(ERR_NO_ERROR != nErrCode)
				{
					pMemberSock->SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, nErrCode);
					continue;
				}

				if ( //(D3DXVec3Length(&(m_character.PositionVector-pMemberSock->m_character.PositionVector)) < 500.0f)	// check: 정확한 거리 찾기, 20040226, kelovon
					pMemberSock->m_pFieldParty == pFParty 
					&& FALSE == COMPARE_BODYCON_BIT(pMemberSock->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
				)
				{
					pMemberSock->WarpToMap(pFMChann->m_MapChannelIndex, pEventInfo->m_EventwParam2);
					// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
					char szSystemLog[1024];
					sprintf(szSystemLog, "[Notify] WarpToMap(112) : %10s SocketIndex[%4d] Map(%4d)	Position(%5d, %5d, %5d)\r\n",
						pMemberSock->m_character.CharacterName, pMemberSock->m_character.ClientIndex, pMemberSock->m_character.MapChannelIndex.MapIndex, (int)pMemberSock->m_character.PositionVector.x,
						(int)pMemberSock->m_character.PositionVector.y, (int)pMemberSock->m_character.PositionVector.z);
					g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
				}
// 2005-11-14 by cmkwon, 필요없음
//				else
//				{
//#ifdef _DEBUG
//					DBGOUT(STRERR_S_F2NOTIFY_0012,
//						GetCharacterString(&pMemberSock->m_character, string()),
//						(D3DXVec3Length(&(m_character.PositionVector-pMemberSock->m_character.PositionVector))),
//						HIDWORD(pMemberSock->m_character.BodyCondition),
//						LODWORD(pMemberSock->m_character.BodyCondition));
//#endif
//				}
			}

		}// end_if (FALSE == pFieldMapProject->IsMultiMapChannel(m_character.InfluenceType))
		else
		{
			SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK|BODYCON_EVENT_SELECTCHANNEL_MASK);
			SendAllChannelState(pFieldMapProject, pEventInfo);
		}
	}
	else if (pEventInfo->m_bEventType == EVENT_TYPE_ENTER_BUILDING)
	{
		// 나머지는 처리 안 함
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO);		// 2007-10-15 by cmkwon, 추가함
		return RES_BREAK;
	}
	else
	{
		// 나머지는 처리 안 함
		SendErrorMessage(T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO);		// 2007-10-15 by cmkwon, 추가함
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_PARTY_GET_OTHER_MOVE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_PARTY_GET_OTHER_MOVE,
									MSG_FC_PARTY_GET_OTHER_MOVE, pPartyOtherMove);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_PARTY_GET_OTHER_MOVE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pOtherSock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pPartyOtherMove->OtherCharacterUniqueNumber);
	if (pOtherSock == NULL
		|| FALSE == pOtherSock->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_PARTY_GET_OTHER_MOVE, ERR_COMMON_NO_SUCH_CHARACTER, pPartyOtherMove->OtherCharacterUniqueNumber);
		return RES_BREAK;
	}

	// 다른 맵이면 보내지 않음
	if (m_pCurrentFieldMapChannel == NULL || m_pCurrentFieldMapChannel != pOtherSock->m_pCurrentFieldMapChannel)
	{
// 2004-12-23 by cmkwon, 필요없음
//		g_pFieldGlobal->WriteSystemLogEX(FALSE, "  GET_OTHER_MOVE: 다른 맵은 보내지 않음, %s가 %s의 정보 요청\r\n"
//				, m_character.CharacterName
//				, pOtherSock->m_character.CharacterName);
		return RES_BREAK;
	}

	CFieldParty *pMeFParty		= this->m_pFieldParty;			// 2006-07-04 by cmkwon
	CFieldParty *pOtherFParty	= pOtherSock->m_pFieldParty;	// 2006-07-04 by cmkwon	
	if (pMeFParty == NULL
		|| pOtherFParty == NULL
		|| (pMeFParty->m_PartyID != pOtherFParty->m_PartyID)
		)
	{
		// 같은 파티원이 아니면
		SendErrorMessage(T_FC_PARTY_GET_OTHER_MOVE, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_OK, T_FC_MOVE_OK, pMoveOK, pMoveOKBuf);
	pMoveOK->ClientIndex	= pOtherSock->m_character.ClientIndex;
// 2007-03-29 by cmkwon, 아래와 같이 비트플래그 변수 추가함
//	pMoveOK->CharacterMode0	= pOtherSock->m_character.CharacterMode;
	pMoveOK->moveBitFlag	= pOtherSock->Get_MSG_FC_MOVE_BIT_FLAG();	
	pMoveOK->PositionVector	= pOtherSock->m_character.PositionVector;
	pMoveOK->TargetVector	= pOtherSock->m_character.TargetVector*1000.0f;
	pMoveOK->UpVector		= pOtherSock->m_character.UpVector;

	SendAddData(pMoveOKBuf, MSG_SIZE(MSG_FC_MOVE_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_GUILD_GET_MAP_OWNER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_GUILD_GET_MAP_OWNER_INFO,
									MSG_FC_GUILD_GET_MAP_OWNER_INFO, pMsgGetOwnerInfo);

// 2008-08-27 by cmkwon, 날쿼리를 Procedure로 수정 - 사용하지 않는 부분임
// 	MAP_OWNERSHIP	mapOwnership;
// 
// 	ms_pFieldIOCP->m_MapOwnershipManager.GetMapOwnership(pMsgGetOwnerInfo->MapIndex, &mapOwnership);
// 
// 	INIT_MSG_WITH_BUFFER(MSG_FC_GUILD_GET_MAP_OWNER_INFO_OK, T_FC_GUILD_GET_MAP_OWNER_INFO_OK, pGetOK, pGetOKBuf);
// 	STRNCPY_MEMSET(pGetOK->DefenderGuildName, mapOwnership.OwnerGuildName, SIZE_MAX_GUILD_NAME);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_GUILD_GET_WAR_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_GUILD_GET_WAR_INFO,
									MSG_FC_GUILD_GET_WAR_INFO, pMsgGetWarInfo);

	INIT_MSG_WITH_BUFFER(MSG_FC_GUILD_GET_WAR_INFO_OK, T_FC_GUILD_GET_WAR_INFO_OK, pGetOK, pGetOKBuf);

	ms_pFieldIOCP->m_GuildWarManager.LockGuildWarManager();	
	{
		CGuildWar *pGuildWar = ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(pMsgGetWarInfo->GuildUID);
		if (pGuildWar == NULL)
		{
			ms_pFieldIOCP->m_GuildWarManager.UnlockGuildWarManager();
			return RES_BREAK;
		}	
		pGetOK->MapChannel		= pGuildWar->GetMapChannelIndex();
		pGetOK->PeerGuildUID	= pGuildWar->GetPeerGuildForGuildWar(m_character.GuildUniqueNumber)->uidGuildUID;
	}
	ms_pFieldIOCP->m_GuildWarManager.UnlockGuildWarManager();

	SendAddData(pGetOKBuf, MSG_SIZE(MSG_FC_GUILD_GET_WAR_INFO_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_GUILD_SUMMON_MEMBER_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_GUILD_SUMMON_MEMBER_OK,
									MSG_FC_GUILD_SUMMON_MEMBER_OK, pRSummonOK);

	if(CS_PLAYING != this->GetClientState()
		|| COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_GUILD_SUMMON_MEMBER_OK, ERR_PROTOCOL_CANNOT_WARP_INVALID_STATE);
		return RES_BREAK;
	}

	CFieldMapChannel *pFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(pRSummonOK->MapChannel);
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_CARDITEM_GUILDSUMMON_NOTIFY, T_FC_ITEM_USE_CARDITEM_GUILDSUMMON_NOTIFY, pSNotify, SendBuf);
	pSNotify->guildSummonClientIdx		= this->GetCharacter()->ClientIndex;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(this->GetCharacter()->PositionVector
		, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_GUILDSUMMON_NOTIFY), this->GetCurrentFieldMapChannel());	

	D3DXVECTOR3 tmVec3Pos(pRSummonOK->PositionVector.x, pRSummonOK->PositionVector.y, pRSummonOK->PositionVector.z);
	EventResult_t ret = WarpToMap(pRSummonOK->MapChannel, &tmVec3Pos);
	if (ret == EVENT_RESULT_BREAK)
	{
#ifdef _DEBUG
		DBGOUT(STRERR_S_F2NOTIFY_0013,
			pRSummonOK->MapChannel.MapIndex, GetCharacterString(&m_character, string()));
#endif
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_GUILD_DISMEMBER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-11-12 ~ 2007-11-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_GUILD_DISMEMBER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_GUILD_DISMEMBER,
									MSG_FC_GUILD_DISMEMBER, pMsgRequestGuildWar);

	// 2007-11-12 by dhjin, 유효한 여단인지 체크
	if(FALSE == this->IsValidCharacter()
		|| this->m_character.GuildUniqueNumber != pMsgRequestGuildWar->GuildUniqueNumber)
	{
		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	
	
	if(FALSE == ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber))
	{// 2009-06-30 by cmkwon, 여단장인지 체크 빠져 있음
		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_PROTOCOL_NOT_GUILD_MASTER);
		return RES_BREAK;
	}

	// 2014-03-04 by jekim, 지도자 후보 사퇴한 경우 여단장 위임 가능하게 수정
	if(TRUE == ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(MAP_INDEX_ALL, m_character.CharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_CANNOT_USE_NEW_COMMANDER_BY_CITYLEADER);
		return RES_BREAK;  
	}
	if(TRUE == ms_pFieldIOCP->m_InflWarManager.CheckPossibleDeleteLeaderCandidate(this->m_character.CharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_CANNOT_USE_NEW_COMMANDER_BY_POLL);
		return RES_BREAK;
	}
	// end 2014-03-04 by jekim, 지도자 후보 사퇴한 경우 여단장 위임 가능하게 수정
	
// 2009-06-30 by cmkwon, 여단 해체시 체크 수정 - 아래와 같이 수정 함.
// 	//////////////////////////////////////////////////////////////////////////
// 	// 2007-11-09 by dhjin, 전진기지 관련하여 처리
// 	if(ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring()
// 		&& ms_pFieldIOCP->m_OutPostManager.CheckOutPostPossessByGuildUID(pMsgRequestGuildWar->GuildUniqueNumber))
// 	{
// 		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_WARING_OUTPOST_TO_OWNMAP);
// 		return RES_BREAK;
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-06-30 by cmkwon, 여단 해체시 체크 수정 - 전진 기지 소유 여단은 해체 불가
	if(ms_pFieldIOCP->m_OutPostManager.CheckOutPostPossessByGuildUID(pMsgRequestGuildWar->GuildUniqueNumber))
	{
 		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_POSSESS_OUTPOST);
 		return RES_BREAK;
	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-06-30 by cmkwon, 여단 해체시 체크 수정 - 전진 기지전 진행중 각인 가능한 여단 해체 불가
	if(ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring()
		&& ms_pFieldIOCP->m_OutPostManager.CheckOutPostResetByGuildUID(pMsgRequestGuildWar->GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_GUILD_DISMEMBER, ERR_WARING_OUTPOST_TO_OWNMAP);
		return RES_BREAK;
	}


	INIT_MSG_WITH_BUFFER(MSG_FI_GUILD_DISMEMBER, T_FI_GUILD_DISMEMBER, pSMsg, SendBuf);
	pSMsg->GuildUniqueNumber	= pMsgRequestGuildWar->GuildUniqueNumber;
	ms_pFieldIOCP->Send2IMServer(SendBuf, MSG_SIZE(MSG_FI_GUILD_DISMEMBER));		

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_GUILD_REQUEST_GUILD_WAR(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_GUILD_REQUEST_GUILD_WAR,
									MSG_FC_GUILD_REQUEST_GUILD_WAR, pMsgRequestGuildWar);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_REQUEST_TRADE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize;
	MSG_FC_TRADE_REQUEST_TRADE		*pMsgRequest;
	BYTE SendBuf[SIZE_MAX_PACKET];

	nRecvTypeSize = sizeof(MSG_FC_TRADE_REQUEST_TRADE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14048);
		return RES_RETURN_FALSE;
	}
	pMsgRequest = (MSG_FC_TRADE_REQUEST_TRADE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;
	
	// 2008-02-26 by dhjin, 아레나 통합 - 아레나 서버에서 사용 불가
	if(g_pFieldGlobal->IsArenaServer())
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}

	// 자신이 이미 거래중임
	if (IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_PROTOCOL_ALREADY_TRADING);
		// 2008-02-12 by cmkwon, 취소 처리되면 안된다. 서로 동시에 거래를 걸 경우 버그를 유발 시키는 코드임
		//SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 자기 자신인지 확인
	if (strnicmp(pMsgRequest->TradeTarget, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME) == 0)
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_COMMON_NOT_ALLOWED_TO_MYSELF, 0, 0, pMsgRequest->TradeTarget);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	if(FALSE == this->IsValidGameUser())
//	{// 2006-06-14 by cmkwon, 베트남 정액제 처리 - 거래 불가
//		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_INVALID_GAMEUSER, 0);
//		SendTradeCanceledAndReset(NULL, FALSE);
//		return RES_BREAK;
//	}

	if(this->m_pCurrentBuildingNPC)
	{// 2006-05-11 by cmkwon, 자기 자신이 상점 이용 중 - 거래 불가
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_USING_SHOP, 0, 0, m_character.CharacterName);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-07-31 by cmkwon, 개인 상점 체크 
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_USING_BAZAAR, 0);
		return RES_BREAK;
	}

	// 해당 캐릭터가 없음
	CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pMsgRequest->TradeTarget);
	if (NULL == pTargetSocket
		|| FALSE == pTargetSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_INVALID_CHARACTER, 0, 0, pMsgRequest->TradeTarget);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	if(FALSE == pTargetSocket->IsValidGameUser())
//	{// 2006-06-14 by cmkwon, 베트남 정액제 처리 - 거래 불가
//		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_INVALID_GAMEUSER, 1);
//		SendTradeCanceledAndReset(NULL, FALSE);
//		return RES_BREAK;
//	}


// 2005-12-06 by cmkwon, 아래 함수에서 체크
//	// 데모 계정 등은 거래를 할 수 없음
//	// 2005-11-01 by cmkwon, GameMaster도 거래 막음
//	if (COMPARE_RACE(m_character.Race, RACE_DEMO|RACE_GUEST|RACE_MONITOR|RACE_GAMEMASTER)
//		|| COMPARE_RACE(pTargetSocket->m_character.Race, RACE_DEMO|RACE_GUEST|RACE_MONITOR|RACE_GAMEMASTER)
//	)
//	{
//		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0082);
//		SendTradeCanceledAndReset(NULL, FALSE);
//		return RES_BREAK;
//	}
	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_TRADE, (0 == m_backupRace)?m_character.Race:m_backupRace, m_character.InfluenceType
		, (0 == pTargetSocket->m_backupRace)?pTargetSocket->GetCharacter()->Race:pTargetSocket->m_backupRace, pTargetSocket->GetCharacter()->InfluenceType))
	{// 2005-12-06 by cmkwon, Race 및 세력 체크
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0082);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 상대방이 이미 거래중임
	if (IS_VALID_UNIQUE_NUMBER(pTargetSocket->m_peerTraderCharacterUniqueNumber))
	{
		m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
		m_bOKTradeChecked = FALSE;
		m_mapTradeItem.clearLock();

		INIT_MSG(MSG_FC_TRADE_REJECT_TRADING, T_FC_TRADE_REJECT_TRADING, msgRejectTrading, SendBuf);
		STRNCPY_MEMSET(msgRejectTrading->TradeTarget, pMsgRequest->TradeTarget, SIZE_MAX_CHARACTER_NAME);
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_REJECT_TRADING));

		return RES_BREAK;
	}
	if(BAZAAR_STATE_NONE != pTargetSocket->m_bazaarManager.GetBazaarState())
	{// 2006-07-31 by cmkwon, 개인 상점 체크 
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_USING_BAZAAR, 1);
		return RES_BREAK;
	}

	// 거리가 멀어서 trade 불가
	if (D3DXVec3Length(&(m_character.PositionVector-pTargetSocket->m_character.PositionVector)) > REQUERED_TRADE_DISTANCE)
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_PROTOCOL_TOO_FAR_TO_TRADE);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	if(pTargetSocket->m_pCurrentBuildingNPC)
	{// 2006-05-11 by cmkwon, 상대방이 상점 이용 중 - 거래 불가
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_USING_SHOP, 0, 0, pTargetSocket->m_character.CharacterName);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_TRADE_REQUEST_TRADE 요청시 자신/상대방 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock()
		|| FALSE == pTargetSocket->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_SECPASS_LOCKED, 0);
		return RES_BREAK;
	}

	// 최대 개수 확인
	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
	// 2014-12-22 by shchoi 거래 시작할 때 인벤토리 최대치 측정 안하도록 변경
// 	if (m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
// 	{
// 		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
// 		SendTradeCanceledAndReset(NULL, FALSE);
// 		return RES_BREAK;
// 	}
// 
// 	if (pTargetSocket->m_ItemManager.GetInventoryItemCounts() >= pTargetSocket->m_ItemManager.GetMaxInventoryCount())
// 	{
// 		SendErrorMessage(T_FC_TRADE_REQUEST_TRADE, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, pTargetSocket->m_ItemManager.GetMaxInventoryCount());
// 		SendTradeCanceledAndReset(NULL, FALSE);
// 		return RES_BREAK;
// 	}
	// end 2014-12-22 by shchoi 거래 시작할 때 인벤토리 최대치 측정 안하도록 변경

	// 상대방 거래자를 setting (동시에 거래중인 상태로 바뀜)
	m_peerTraderCharacterUniqueNumber = pTargetSocket->m_character.CharacterUniqueNumber;
	pTargetSocket->m_peerTraderCharacterUniqueNumber = m_character.CharacterUniqueNumber;

	// MSG_FC_TRADE_REQUEST_TRADE_OK를 전송
	INIT_MSG(MSG_FC_TRADE_REQUEST_TRADE_OK, T_FC_TRADE_REQUEST_TRADE_OK, msgRequestOK, SendBuf);
	STRNCPY_MEMSET(msgRequestOK->TradeSource, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgRequestOK->TradeSourceCharacterUniqueNumber = m_character.CharacterUniqueNumber;

	pTargetSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_REQUEST_TRADE_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_CANCEL_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;
	MSG_FC_TRADE_CANCEL_REQUEST	*pMsgCancelRequest;
	BYTE SendBuf[SIZE_MAX_PACKET];

	nRecvTypeSize = sizeof(MSG_FC_TRADE_CANCEL_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_TRADE_CANCEL_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1404A);
		return RES_RETURN_FALSE;
	}
	pMsgCancelRequest = (MSG_FC_TRADE_CANCEL_REQUEST*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (!IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_TRADE_CANCEL_REQUEST, ERR_PROTOCOL_TRADE_NOT_STARTED);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pTargetSocket)
	{
		SendErrorMessage(T_FC_TRADE_CANCEL_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	if (strcmp(pMsgCancelRequest->TradeTarget, pTargetSocket->GetCharacter()->CharacterName) != 0)
	{
		SendErrorMessage(T_FC_TRADE_CANCEL_REQUEST, ERR_PROTOCOL_PEER_TRADER_NOT_MATCHED);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	INIT_MSG(MSG_FC_TRADE_CANCEL_REQUEST_OK, T_FC_TRADE_CANCEL_REQUEST_OK, msgCancelRequestOK, SendBuf);
	STRNCPY_MEMSET(msgCancelRequestOK->TradeSource, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgCancelRequestOK->TradeSourceCharacterUniqueNumber = m_character.CharacterUniqueNumber;

	pTargetSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_REQUEST_OK));

	// 거래 reset
	m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	m_bOKTradeChecked = FALSE;
	m_mapTradeItem.clearLock();
	pTargetSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	pTargetSocket->m_bOKTradeChecked = FALSE;
	pTargetSocket->m_mapTradeItem.clearLock();


	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_ACCEPT_TRADE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;
	MSG_FC_TRADE_ACCEPT_TRADE	*pMsgAccept;
	BYTE SendBuf[SIZE_MAX_PACKET];

	nRecvTypeSize = sizeof(MSG_FC_TRADE_ACCEPT_TRADE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_TRADE_ACCEPT_TRADE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1404B);
		return RES_RETURN_FALSE;
	}
	pMsgAccept = (MSG_FC_TRADE_ACCEPT_TRADE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 거래를 요청한 사람이 다름
	if (pMsgAccept->TradeSourceCharacterUniqueNumber != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_TRADE_ACCEPT_TRADE, ERR_PROTOCOL_PEER_TRADER_NOT_MATCHED);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pSourceSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pSourceSocket
		|| FALSE == pSourceSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_ACCEPT_TRADE, ERR_COMMON_NO_SUCH_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// Send MSG_FC_TRADE_ACCEPT_TRADE_OK
	INIT_MSG(MSG_FC_TRADE_ACCEPT_TRADE_OK, T_FC_TRADE_ACCEPT_TRADE_OK, msgAcceptOK, SendBuf);
	STRNCPY_MEMSET(msgAcceptOK->TradeTarget, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgAcceptOK->TradeTargetCharacterUniqueNumber = m_character.CharacterUniqueNumber;

	pSourceSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_ACCEPT_TRADE_OK));

	// Send MSG_FC_TRADE_SHOW_TRADE_WINDOW
	INIT_MSG(MSG_FC_TRADE_SHOW_TRADE_WINDOW, T_FC_TRADE_SHOW_TRADE_WINDOW, msgShowWindow, SendBuf);
	// To Source
	msgShowWindow->PeerTradeCharacterUniqueNumber = m_character.CharacterUniqueNumber;
	pSourceSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_SHOW_TRADE_WINDOW));
	// To Target
	msgShowWindow->PeerTradeCharacterUniqueNumber = pSourceSocket->m_character.CharacterUniqueNumber;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_SHOW_TRADE_WINDOW));

	// set lock
	m_pCurrentLockTrade = &(pSourceSocket->m_lockTrade);
	pSourceSocket->m_pCurrentLockTrade = &(pSourceSocket->m_lockTrade);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_REJECT_TRADE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;
	MSG_FC_TRADE_REJECT_TRADE	*pMsgReject;
	BYTE SendBuf[SIZE_MAX_PACKET];

	nRecvTypeSize = sizeof(MSG_FC_TRADE_REJECT_TRADE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_TRADE_REJECT_TRADE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1404C);
		return RES_RETURN_FALSE;
	}
	pMsgReject = (MSG_FC_TRADE_REJECT_TRADE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 거래를 요청한 사람이 다름
	if (pMsgReject->TradeSourceCharacterUniqueNumber != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_TRADE_REJECT_TRADE, ERR_PROTOCOL_PEER_TRADER_NOT_MATCHED);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pSourceSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pSourceSocket)
	{
		SendErrorMessage(T_FC_TRADE_REJECT_TRADE, ERR_COMMON_NO_SUCH_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	INIT_MSG(MSG_FC_TRADE_REJECT_TRADE_OK, T_FC_TRADE_REJECT_TRADE_OK, msgRejectOK, SendBuf);
	STRNCPY_MEMSET(msgRejectOK->TradeTarget, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgRejectOK->TradeTargetCharacterUniqueNumber = m_character.CharacterUniqueNumber;

	pSourceSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_REJECT_TRADE_OK));

	// 거래 reset
	m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	m_bOKTradeChecked = FALSE;
	m_mapTradeItem.clearLock();
	pSourceSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	pSourceSocket->m_bOKTradeChecked = FALSE;
	pSourceSocket->m_mapTradeItem.clearLock();

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_TRANS_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_TRADE_TRANS_ITEM,
									MSG_FC_TRADE_TRANS_ITEM, pMsgTransItem);
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_INVALID_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pPeerTraderSocket
		|| FALSE == pPeerTraderSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_COMMON_NO_SUCH_CHARACTER, m_peerTraderCharacterUniqueNumber);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 둘중에 한명이라도 거래 승인 상태면 아이템 추가 불가
	if(pPeerTraderSocket->m_bOKTradeChecked)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_CANNOT_PUT_ITEM, pPeerTraderSocket->m_bOKTradeChecked, pMsgTransItem->ItemNum);
		return RES_BREAK;
	}

	if (pMsgTransItem->CharacterUniqueNumber != m_character.CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_TRADE_TRANS_ITEM 요청시 자신/상대방 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock()
		|| FALSE == pPeerTraderSocket->CheckSecondaryPasswordLock())
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_SECPASS_LOCKED);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_TRADE_TRANS_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	if(this->m_bOKTradeChecked)
	{// 2008-11-21 by cmkwon, 거래 승인 확인 시스템 구현 - 거래 승인 이면 아이템 추가 할수 없다. 에러 전송
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_CANNOT_PUT_ITEM, this->m_bOKTradeChecked, pMsgTransItem->ItemNum);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItem = m_ItemManager.GetItemGeneralByUID(pMsgTransItem->ItemUniqueNumber);
	if (NULL == pItem)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_TRADE_TRANS_ITEM
	if(pItem->UniqueNumber != pMsgTransItem->ItemUniqueNumber
		|| pItem->Possess != GetCharacter()->CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d\r\n"
			, GetProtocolTypeString(T_FC_TRADE_TRANS_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItem, string()), pItem->Possess, pMsgTransItem->ItemUniqueNumber);
		return RES_BREAK;
	}

	if (pMsgTransItem->ItemNum != pItem->ItemNum)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_INVALID_ITEMNUM);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - 
	//if(pItem->ItemWindowIndex < POS_INVALID_POSITION)
	if(IS_ATTACHABLE_POSITION(pItem->ItemWindowIndex))
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if (COMPARE_BIT_FLAG(pItem->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM|ITEM_ATTR_ACCOUNT_POSSESSION))
	{// 2007-09-17 by cmkwon, 예당 캐쉬상점 캐쉬아이템 거래 불가 기능 추가 - 계정 소유 아이템 체크 추가
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if(ITEMKIND_ACCESSORY_TIMELIMIT == pItem->Kind
		&& pItem->UsingTimeStamp != ITEM_NOT_USING)
	{// 2006-06-16 by cmkwon, 이미 사용 시작된 아이템은 상점에 판매/거래/창고로 이동 불가
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1, 0);
		return RES_BREAK;
	}

	if (pMsgTransItem->Amount > pItem->CurrentCount)
	{
		SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	INT nFinalAmountOfTradeItem = 0;
	mt_auto_lock mtaTrade(&m_mapTradeItem);
	mtmapUID2TradeItem::iterator itrTrade = m_mapTradeItem.find(pMsgTransItem->ItemUniqueNumber);
	if (itrTrade != m_mapTradeItem.end())
	{// 이미 올라간 아이템인 경우
		
		if(FALSE == IS_COUNTABLE_ITEM(pItem->Kind))
		{			
			SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ALREADY_TRADE_ITEM);
			return RES_BREAK;
		}
		if(pItem->CurrentCount < itrTrade->second.Count + pMsgTransItem->Amount)
		{// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 합쳐진 아이템 개수 체크
			SendErrorMessage(T_FC_TRADE_TRANS_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED, pItem->CurrentCount, itrTrade->second.Count + pMsgTransItem->Amount);
			SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
			return RES_BREAK;
		}
		
		itrTrade->second.Count += pMsgTransItem->Amount;
		nFinalAmountOfTradeItem = itrTrade->second.Count;
	}
	else
	{// Trade Item 리스트에 추가

		TradeItem tradeItem;
		tradeItem.ItemUniqueNumber = pItem->UniqueNumber;
		tradeItem.Count = pMsgTransItem->Amount;
		tradeItem.pStoreItem = pItem;
		m_mapTradeItem.insertNoLock(pItem->UniqueNumber, tradeItem);
		nFinalAmountOfTradeItem = pMsgTransItem->Amount;
	}
	mtaTrade.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_TRANS_ITEM_OK, T_FC_TRADE_TRANS_ITEM_OK, msgTransItemOK, SendBuf);
	msgTransItemOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	msgTransItemOK->TradeItem = *pItem;
	msgTransItemOK->TradeItem.CurrentCount = nFinalAmountOfTradeItem;
	msgTransItemOK->NumOfEnchants = 0;	// 아래서 할당
	// lock
	m_mapEnchant.lock();
	mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(pItem->UniqueNumber);
	if (itrEnchantList != m_mapEnchant.end())
	{
		vectENCHANT &vecECH = itrEnchantList->second;
		msgTransItemOK->NumOfEnchants = vecECH.size();
		INT *ArrInchantItemNum = (INT*)(SendBuf+MSG_SIZE(MSG_FC_TRADE_TRANS_ITEM_OK));
		for (int i = 0; i < msgTransItemOK->NumOfEnchants; i++)
		{
			ArrInchantItemNum[i] = vecECH[i].EnchantItemNum;
		}
	}
	// unlock
	m_mapEnchant.unlock();
	igLock.auto_unlock_cancel();

	// Send Message
	if(pPeerTraderSocket
		&& pPeerTraderSocket->IsUsing())
	{
		
		pPeerTraderSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_TRANS_ITEM_OK) + msgTransItemOK->NumOfEnchants*sizeof(INT));
	}

		
	// 2010-06-15 by shcho&hslee 펫시스템 - 거래 시 펫 정보 전송
	vecPetCurrentInfo::iterator petiter = this->m_ItemManager.m_vectPetCurrentInfo.begin();
	// 패킷 생성
	INIT_MSG_WITH_BUFFER(MSG_TRADE_PET_DATA, T_FC_TRADE_SEE_PET_DATA, Petcurrentmsg, sendPetbuff);

	for(;petiter != this->m_ItemManager.m_vectPetCurrentInfo.end(); ++petiter)
	{
		if( pMsgTransItem->ItemUniqueNumber == (*petiter)->CreatedPetUID ) // 아이템 고유번호가 소유한 펫 아이템과 같을 때만 전송 
		{
			///////////////////////////////////////////////////////////////////////////////////////
			// start 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
			//
			// 기존 
			//

// 			Petcurrentmsg->CreatedPetUID = (*petiter)->CreatedPetUID;
// 			Petcurrentmsg->EnableEditPetName = (*petiter)->EnableEditPetName;
// 			Petcurrentmsg->EnableLevelUp = (*petiter)->EnableLevelUp;
// 			Petcurrentmsg->PetExp = (*petiter)->PetExp;
// 			Petcurrentmsg->PetIndex = (*petiter)->PetIndex;
// 			Petcurrentmsg->PetLevel = (*petiter)->PetLevel;
// 			memcpy(Petcurrentmsg->szPetName,(*petiter)->szPetName,SIZE_MAX_PET_NAME);

			/////////
			// 수정

			Petcurrentmsg->CreatedPetUID = (*petiter)->CreatedPetUID;
			Petcurrentmsg->PetExp = (*petiter)->PetExp;
			Petcurrentmsg->PetIndex = (*petiter)->PetIndex;
			Petcurrentmsg->PetLevel = (*petiter)->PetLevel;
			memcpy(Petcurrentmsg->PetName,(*petiter)->PetName,SIZE_MAX_PET_NAME);

			// end 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
			///////////////////////////////////////////////////////////////////////////////////////

			pPeerTraderSocket->SendAddData( sendPetbuff, MSG_SIZE(MSG_TRADE_PET_DATA) ); // 펫 정보 전송
			break;
		}
	}
	// END 2010-06-15 by shcho&hslee 펫시스템 - 거래 시 펫 정보 전송
//#ifdef _DEBUG
//	DBGOUT("\n\nProcess_FC_TRADE_TRANS_ITEM From %s...\n", m_character.CharacterName);
//
//	DBG_PRINT_ITEM();
//#endif
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_SEE_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_TRADE_SEE_ITEM,
									MSG_FC_TRADE_SEE_ITEM, pMsgSeeItem);

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pPeerTraderSocket
		|| FALSE == pPeerTraderSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_COMMON_NO_SUCH_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-09-13 by cmkwon, 카운터블아이템의 최대 수치는 20억개 체크
	if(IS_COUNTABLE_ITEM(pMsgSeeItem->ItemNum))
	{
		// lock m_mapItemGeneral, MSG_FC_TRADE_SEE_ITEM
		mt_auto_lock myigLock(&m_ItemManager.m_mapItemGeneral);
		
		INT64 tmCurrentCount = pMsgSeeItem->Amount;
		ITEM_GENERAL *pMyItem = m_ItemManager.GetFirstItemGeneralByItemNum(pMsgSeeItem->ItemNum);
		if(pMyItem){				tmCurrentCount += pMyItem->CurrentCount;}
		if(tmCurrentCount > MAX_ITEM_COUNTS)
		{
			SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, 0, 0);
			SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
			return RES_BREAK;
		}
	}

	// lock m_mapItemGeneral, MSG_FC_TRADE_SEE_ITEM
	mt_auto_lock igLock(&pPeerTraderSocket->m_ItemManager.m_mapItemGeneral);

	TradeItem tradeItem;

	m_mapTradeItem.lock();
	mtmapUID2TradeItem::iterator itr = pPeerTraderSocket->m_mapTradeItem.find(pMsgSeeItem->ItemUniqueNumber);
	if (m_mapTradeItem.end() == itr)
	{
		m_mapTradeItem.unlock();
		SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgSeeItem->ItemUniqueNumber);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}
	tradeItem = itr->second;
	m_mapTradeItem.unlock();

	// 아이템 일치 여부 확인
	if (pMsgSeeItem->ItemUniqueNumber != tradeItem.ItemUniqueNumber || pMsgSeeItem->Amount != tradeItem.Count)
	{
		SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItem = pPeerTraderSocket->m_ItemManager.GetItemGeneralByUID(pMsgSeeItem->ItemUniqueNumber);
	if (NULL == pItem)
	{
		SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	if (pItem->CurrentCount < pMsgSeeItem->Amount)
	{
		SendErrorMessage(T_FC_TRADE_SEE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_SEE_ITEM_OK, T_FC_TRADE_SEE_ITEM_OK, msgSeeOk, SendBuf);
	msgSeeOk->CharacterUniqueNumber = pPeerTraderSocket->m_character.CharacterUniqueNumber;

	int offset = MSG_SIZE(MSG_FC_TRADE_SEE_ITEM_OK);
	ITEM_GENERAL *pItemCopy = (ITEM_GENERAL*)(SendBuf + offset);

	offset += CopyItem2Buffer((char*)pItemCopy, pItem);
	pItemCopy->CurrentCount = pMsgSeeItem->Amount;

	pPeerTraderSocket->SendAddData(SendBuf, offset);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_OK_TRADE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_TRADE_OK_TRADE,
									MSG_FC_TRADE_OK_TRADE, pMsgOKTrade);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_INVALID_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 거래 확인 요청시 자신의 개인 상점 체크 
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_USING_BAZAAR, m_character.CharacterUniqueNumber);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	if (NULL == pPeerTraderSocket
		|| FALSE == pPeerTraderSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_COMMON_NO_SUCH_CHARACTER);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 거래 확인 요청시 상대방의 개인 상점 체크 
	if(BAZAAR_STATE_NONE != pPeerTraderSocket->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_USING_BAZAAR, m_peerTraderCharacterUniqueNumber);
		SendTradeCanceledAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	m_pCurrentLockTrade->lock();
	if (m_bOKTradeChecked == TRUE && pPeerTraderSocket->m_bOKTradeChecked == TRUE)
	{
#ifdef _DEBUG
		DBGOUT(STRERR_S_F2NOTIFY_0014, GetCharacterString(&m_character, string()));
#endif
		m_pCurrentLockTrade->unlock();
		return RES_BREAK;
	}
	m_bOKTradeChecked = TRUE;
	if (!pPeerTraderSocket->m_bOKTradeChecked)
	{
		m_pCurrentLockTrade->unlock();

		// 2008-11-21 by cmkwon, 거래 승인 확인 시스템 구현 - 아래와 같이 거래 승인 실행 정보 양쪽 모두에게 전송함
		INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_OK_TRADE_NOTIFY, T_FC_TRADE_OK_TRADE_NOTIFY, pTradeOKNotify, SendBuf);
		pTradeOKNotify->CharacterUniqueNumber	= this->GetCharacter()->CharacterUniqueNumber;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_OK_TRADE_NOTIFY));
		pPeerTraderSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_OK_TRADE_NOTIFY));
		return RES_BREAK;
	}
	m_pCurrentLockTrade->unlock();

	///////////////////////////////////////////////////////////////////////////////////
	// 거래 시작
	///////////////////////////////////////////////////////////////////////////////////

	// lock m_mapItemGeneral, MSG_FC_TRADE_OK_TRADE
	mt_auto_lock igLock1(&m_ItemManager.m_mapItemGeneral);
	mt_auto_lock meTILock(&m_mapTradeItem);

	// lock m_mapItemGeneral, MSG_FC_TRADE_OK_TRADE
	mt_auto_lock igLock2(&pPeerTraderSocket->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock peerTILock(&pPeerTraderSocket->m_mapTradeItem);

///////////////////////////////////////////////////////////////////////////////
// 2006-05-15 by cmkwon, 거래 시스템 수정
// 	QPARAM_EXECUTETRADE *pParam	= new QPARAM_EXECUTETRADE;
// 	pParam->pPeerTraderSocket	= pPeerTraderSocket;
// 
// 	BOOL bOuterDeleted = FALSE;		// Outer Loop의 itrTrd이 지워졌다면, itrTrd++을 할 필요가 없다.
// 
// 	mtmapUID2TradeItem::iterator itrTrd = m_mapTradeItem.begin();
// 	while (itrTrd != m_mapTradeItem.end())
// 	{
// 		if (!IS_COUNTABLE_ITEM(itrTrd->second.pStoreItem->Kind))
// 		{
// 			itrTrd++;
// 			continue;
// 		}
// 
// 		mtmapUID2TradeItem::iterator itrTrdPeer = pPeerTraderSocket->m_mapTradeItem.begin();
// 		while (itrTrdPeer != pPeerTraderSocket->m_mapTradeItem.end())
// 		{
// 			if (!IS_COUNTABLE_ITEM(itrTrdPeer->second.pStoreItem->Kind))
// 			{
// 				itrTrdPeer++;
// 				continue;
// 			}
// 
// 			if (itrTrd->second.pStoreItem->ItemNum == itrTrdPeer->second.pStoreItem->ItemNum)
// 			{
// 				if (itrTrd->second.Count > itrTrdPeer->second.Count)
// 				{
// 					itrTrd->second.Count -= itrTrdPeer->second.Count;
// 					pPeerTraderSocket->m_mapTradeItem.erase(itrTrdPeer);
// 					break;
// 				}
// 				else if (itrTrd->second.Count < itrTrdPeer->second.Count)
// 				{
// 					itrTrdPeer->second.Count -= itrTrd->second.Count;
// 					m_mapTradeItem.erase(itrTrd++); bOuterDeleted = TRUE;
// 					break;
// 				}
// 				else if (itrTrd->second.Count == itrTrdPeer->second.Count)
// 				{
// 					m_mapTradeItem.erase(itrTrd++); bOuterDeleted = TRUE;
// 					pPeerTraderSocket->m_mapTradeItem.erase(itrTrdPeer);
// 					break;
// 				}
// 			}
// 			itrTrdPeer++;
// 		}
// 
// 		if (!bOuterDeleted) itrTrd++;	// 지워졌다면 이미 itrTrd++이 수행되었으므로 또 할 필요 없다.
// 		bOuterDeleted = FALSE;
// 	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-05-11 by cmkwon, 거래 아이템 추가가 가능한지 체크
	Err_t err = this->TradeCheckEnableInsertItems(pPeerTraderSocket);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, err, 0, 0, pPeerTraderSocket->m_character.CharacterName);
		pPeerTraderSocket->SendErrorMessage(T_FC_TRADE_OK_TRADE, err, 1, 0, pPeerTraderSocket->m_character.CharacterName);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}
	err = pPeerTraderSocket->TradeCheckEnableInsertItems(this);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_TRADE_OK_TRADE, err, 1, 0, this->m_character.CharacterName);
		pPeerTraderSocket->SendErrorMessage(T_FC_TRADE_OK_TRADE, err, 0, 0, this->m_character.CharacterName);
		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-05-11 by cmkwon, 거래 아이템을 실제로 처리함
	this->TradeInsertItems(pPeerTraderSocket);
	pPeerTraderSocket->TradeInsertItems(this);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-05-11 by cmkwon, 거래 관련 초기화
	this->m_peerTraderCharacterUniqueNumber	= INVALID_UNIQUE_NUMBER;
	this->m_bOKTradeChecked					= FALSE;
	this->m_mapTradeItem.clear();
	pPeerTraderSocket->m_peerTraderCharacterUniqueNumber	= INVALID_UNIQUE_NUMBER;
	pPeerTraderSocket->m_bOKTradeChecked					= FALSE;
	pPeerTraderSocket->m_mapTradeItem.clear();


	peerTILock.auto_unlock_cancel();
	meTILock.auto_unlock_cancel();
	igLock2.auto_unlock_cancel();
	igLock1.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-05-11 by cmkwon, 거래 완료 메시지 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_OK_TRADE_OK, T_FC_TRADE_OK_TRADE_OK, pTradeOK, SendBuf);
	pTradeOK->CharacterUniqueNumber	= pPeerTraderSocket->GetCharacter()->CharacterUniqueNumber;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_OK_TRADE_OK));

	pTradeOK->CharacterUniqueNumber	= this->GetCharacter()->CharacterUniqueNumber;
	pPeerTraderSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_OK_TRADE_OK));

//#ifdef _DEBUG
//	DBGOUT("  거래 아이템 정리 이후\r\n");
//	DBG_PRINT_ITEM();
//	pPeerTraderSocket->DBG_PRINT_ITEM();
//#endif // _DEBUG

// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
//	// 적재량 확인
//	if (GetCurrentLoadagePercentage(pPeerTraderSocket->GetTradeItemWeight()) > 1.0f)
//	{
//		SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_PROTOCOL_ITEM_OVER_WEIGHT,
//							(INT)m_ItemManager.GetCurrentCarryingItemWeight()+pPeerTraderSocket->GetTradeItemWeight(),
//							(INT)CAtumSJ::GetTransport(&m_character));
//		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0083, m_character.CharacterName);
//		pPeerTraderSocket->SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0083, m_character.CharacterName);
//		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
//		return RES_BREAK;
//	}
//
//	if (pPeerTraderSocket->GetCurrentLoadagePercentage(GetTradeItemWeight()) > 1.0f)
//	{
//		pPeerTraderSocket->SendErrorMessage(T_FC_TRADE_OK_TRADE, ERR_PROTOCOL_ITEM_OVER_WEIGHT,
//											(INT)pPeerTraderSocket->m_ItemManager.GetCurrentCarryingItemWeight()+GetTradeItemWeight(),
//											(INT)CAtumSJ::GetTransport(&pPeerTraderSocket->m_character));
//		pPeerTraderSocket->SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0083, pPeerTraderSocket->m_character.CharacterName);
//		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0083, pPeerTraderSocket->m_character.CharacterName);
//		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
//		return RES_BREAK;
//	}

// 2006-05-11 by cmkwon, 위에서 처리함
// 	// check: QP_ExecuteTrade() 구현후 살리기! 20030903, kelovon
// 	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ExecuteTrade, this, m_character.AccountUniqueNumber, pParam);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TRADE_CANCEL_TRADE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;
	MSG_FC_TRADE_CANCEL_TRADE	*pMsgCancelTrade;

	nRecvTypeSize = sizeof(MSG_FC_TRADE_CANCEL_TRADE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_TRADE_CANCEL_TRADE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14052);
		return RES_RETURN_FALSE;
	}
	pMsgCancelTrade = (MSG_FC_TRADE_CANCEL_TRADE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	SendTradeCanceledAndReset(NULL, TRUE);

	return RES_RETURN_TRUE;
}

// Countdown
ProcessResult CFieldIOCPSocket::Process_FC_COUNTDOWN_DONE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize;
	MSG_FC_COUNTDOWN_DONE	*pReMsg;
	
	nRecvTypeSize = sizeof(MSG_FC_COUNTDOWN_DONE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14052);
		return RES_RETURN_FALSE;
	}
	pReMsg = (MSG_FC_COUNTDOWN_DONE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(NULL == m_pCurrentFieldMapChannel)
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 시간이 경과 되었는지 체크(향후 추가해야함)
	// ERR_COUNTDOWN_NOT_ENOUGH_TIME
	if (FALSE == m_countdownChecker.IsEndedCountDown(pReMsg->byCountdownType, timeGetTime()))
	{
		SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_COUNTDOWN_NOT_ENOUGH_TIME, pReMsg->byCountdownType);
		
		INIT_MSG_WITH_BUFFER(MSG_FC_COUNTDOWN_START, T_FC_COUNTDOWN_START, pSMsg, pSendBuf);
		pSMsg->byCountdownType	= pReMsg->byCountdownType;
		pSMsg->nWaitingSecond	= SECOND_COUNTDOWN_TIME_GAP/2;
		this->SendAddData(pSendBuf, MSG_SIZE(MSG_FC_COUNTDOWN_START));
		return RES_BREAK;
	}

	switch(pReMsg->byCountdownType)
	{
	case COUNTDOWN_TYPE_P2P_WAR:
		{
			if(FALSE == m_bP2PPKStarted
				|| INVALID_CLIENT_INDEX == m_peerP2PPKClientIndex)
			{
				return RES_BREAK;
			}

			CFieldIOCPSocket *pPeerFISocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
			if(NULL == pPeerFISocket
				|| FALSE == pPeerFISocket->IsUsing())
			{
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 시간이 경과 되었는지 체크(향후 추가해야함)

			///////////////////////////////////////////////////////////////////////////////
			// Send MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK
			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK, T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK, pSMsg, SendBuf);
			pSMsg->PeerClientIndex = m_peerP2PPKClientIndex;
			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK));
		}
		break;
	case COUNTDOWN_TYPE_PARTY_WAR:
		{
			CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if(NULL == pMeFParty
				|| 0 == pMeFParty->m_PeerBattleRequesterPartyID)
			{
				return RES_BREAK;
			}

			// 상대방 모든 파티원 정보를 전송
			CFieldParty *pPeerParty = ms_pFieldIOCP->m_MapParties.findLock(pMeFParty->m_PeerBattlePartyID);
			if (pPeerParty == NULL || 0 == pPeerParty->m_PeerBattleRequesterPartyID)
			{
				SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_PROTOCOL_NO_SUCH_PARTY, LODWORD(pMeFParty->m_PeerBattlePartyID), HIDWORD(pMeFParty->m_PeerBattlePartyID));
				return RES_BREAK;
			}

			// 상대편 파티장 체크
			CFieldIOCPSocket *pPeerMasterSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pPeerParty->GetMasterCharacterUniqueNumber());
			if (pPeerMasterSocket == NULL || FALSE == pPeerMasterSocket->IsUsing())
			{
				SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_COMMON_NO_SUCH_CHARACTER, pPeerParty->GetMasterCharacterUniqueNumber());
				return RES_BREAK;
			}			

			// 파티 아이디 확인
			if (pMeFParty->m_PeerBattleRequesterPartyID != pPeerParty->m_PartyID
				|| pMeFParty->m_PartyID != pPeerParty->m_PeerBattleRequesterPartyID
				)
			{
				SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_PROTOCOL_PARTY_ID_NOT_MATCHED, HIDWORD(pMeFParty->m_PeerBattleRequesterPartyID), 0, m_character.CharacterName);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 시간이 경과 되었는지 체크(향후 추가해야함)
			// ERR_COUNTDOWN_NOT_ENOUGH_TIME


			int i = 0;
			CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
			MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
			INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_BATTLE_START, T_FC_PARTY_BATTLE_START, pSMsg, pSendBuf);
			
			// Send MSG to Target(this) Party
			pSMsg->PeerPartyID					= pMeFParty->m_PeerBattlePartyID;
			pSMsg->PeerPartyMasterClientIndex	= pPeerMasterSocket->m_character.ClientIndex;
			pSMsg->nPeerPartyMemberToBattle		= 0;
			int nMemCount = pPeerParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel);
			nMemCount = min(nMemCount, SIZE_MAX_PARTY_MEMBER);
			PEER_PARTY_MEMBER *pMember = (PEER_PARTY_MEMBER*)(pSendBuf + MSG_SIZE(MSG_FC_PARTY_BATTLE_START));
			for (i = 0; i < nMemCount; i++)
			{
				if(ArrayPartyMember[i] && ArrayPartyMember[i]->IsUsing())
				{
					pMember->ClientIndex			= ArrayPartyMember[i]->m_character.ClientIndex;
					pMember->CharacterUniqueNumber	= ArrayPartyMember[i]->m_character.CharacterUniqueNumber;
					pSMsg->nPeerPartyMemberToBattle++;
					pMember++;
				}
			}
			this->SendAddData(pSendBuf
				, MSG_SIZE(MSG_FC_PARTY_BATTLE_START) + pSMsg->nPeerPartyMemberToBattle*sizeof(PEER_PARTY_MEMBER));		
		}
		break;
	default:
		{
			SendErrorMessage(T_FC_COUNTDOWN_DONE, ERR_COUNTDOWN_INVALID_COUNTDOWN_TYPE, pReMsg->byCountdownType);
			return RES_BREAK;
		}
	}
	
	return RES_RETURN_TRUE;
}


// Object
ProcessResult CFieldIOCPSocket::Process_FC_OBJECT_CHANGE_BODYCONDITION(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_OBJECT_CHANGE_BODYCONDITION,
		MSG_FC_OBJECT_CHANGE_BODYCONDITION, pRObjChangeBodyCond);

	///////////////////////////////////////////////////////////////////////////////	
	// 2009-01-21 by cmkwon, 투명 상태인 유저 워프 이펙트 안보이게 처리 - 투명상태 체크
	if(FALSE == IsValidCharacter(FALSE)
		|| this->IsInvisibleCharacter())
	{
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_OBJECT_CHANGE_BODYCONDITION_OK, T_FC_OBJECT_CHANGE_BODYCONDITION_OK, pSObjBodyCond, pBuffer);
	*pSObjBodyCond = *pRObjChangeBodyCond;

	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pBuffer, MSG_SIZE(MSG_FC_OBJECT_CHANGE_BODYCONDITION_OK),
													GetCurrentFieldMapChannel(), FALSE, GetCurrentFieldMapChannel()->GetUserVisibleDiameterW());	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_AUCTION_REGISTER_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_AUCTION_REGISTER_ITEM,
		MSG_FC_AUCTION_REGISTER_ITEM, pMsgAuctionRegister);

	// 경매 상점에 있을 때만 가능
	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_AUCTION)
	{
		SendErrorMessage(T_FC_AUCTION_GET_ITEM_LIST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AuctionRegisterItem, this, m_character.AccountUniqueNumber, NULL, NULL, pMsgAuctionRegister->ItemUID, pMsgAuctionRegister->Price);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_AUCTION_CANCEL_REGISTER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_AUCTION_CANCEL_REGISTER,
		MSG_FC_AUCTION_CANCEL_REGISTER, pMsgCancelRegister);

	// 경매 상점에 있을 때만 가능
	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_AUCTION)
	{
		SendErrorMessage(T_FC_AUCTION_CANCEL_REGISTER, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AuctionCancelRegister, this, m_character.AccountUniqueNumber, NULL, NULL, pMsgCancelRegister->ItemUID);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_AUCTION_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_AUCTION_BUY_ITEM,
		MSG_FC_AUCTION_BUY_ITEM, pMsgAuctionBuy);

	// 경매 상점에 있을 때만 가능
	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_AUCTION)
	{
		SendErrorMessage(T_FC_AUCTION_BUY_ITEM, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AuctionBuyItem, this, m_character.AccountUniqueNumber, NULL, NULL, pMsgAuctionBuy->ItemUID);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_AUCTION_GET_ITEM_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_AUCTION_GET_ITEM_LIST,
		MSG_FC_AUCTION_GET_ITEM_LIST, pMsgAuctionGetItemList);

	// 경매 상점에 있을 때만 가능
	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_AUCTION)
	{
		SendErrorMessage(T_FC_AUCTION_GET_ITEM_LIST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AuctionGetItemList, this, m_character.AccountUniqueNumber, NULL, NULL, pMsgAuctionGetItemList->AuctionKind, pMsgAuctionGetItemList->CharacterUID);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_USE_SKILLPOINT(const char* pPacket, int nLength, int &nBytesUsed)
{
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_SETUP_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	return RES_RETURN_TRUE;
}


// 2014-07-17 by bckim, 프리미엄 아머 컬렉션
BOOL CFieldIOCPSocket::ApplyItemDesParamOnlyPremiumAmor(ITEM *i_pItem, INT i_nStatLevel)
{
	if( i_pItem->IsExistDesParam(DES_PREMIUM_OPTION_ITEM_DEFAULT_DESPARAM))
	{
		ApplyItemDesParam(i_pItem);
		
		BYTE tempStatLevel = i_nStatLevel - 1;	// 위에서 한번은 해줬음.. -.- 특정 데스파람만 가변형이라.. 어떻하지 ?
		if( 0 < tempStatLevel )
		{			
			SetParamFactor(DES_DROP_EXP, (float)(i_pItem->GetParameterValue(DES_DROP_EXP)*tempStatLevel));
			SetParamFactor(DES_DROP_ITEM, (float)(i_pItem->GetParameterValue(DES_DROP_ITEM)*tempStatLevel));
		}
		return TRUE;
	}
	return FALSE;
}

BOOL CFieldIOCPSocket::ReleaseItemDesParamOnlyPremiumAmor(ITEM *i_pItem, INT i_nStatLevel)
{
	if( i_pItem->IsExistDesParam(DES_PREMIUM_OPTION_ITEM_DEFAULT_DESPARAM))
	{
		ReleaseItemDesParam(i_pItem);
		
		BYTE tempStatLevel = i_nStatLevel - 1;	// 위에서 한번은 해줬음.. -.- 특정 데스파람만 가변형이라.. 어떻하지 ?
		if( 0 < tempStatLevel )
		{			
			UnsetParamFactor(DES_DROP_EXP, (float)(i_pItem->GetParameterValue(DES_DROP_EXP)*tempStatLevel));
			UnsetParamFactor(DES_DROP_ITEM, (float)(i_pItem->GetParameterValue(DES_DROP_ITEM)*tempStatLevel));
		}
		return TRUE;
	}
	return FALSE;
}
// End. 2014-07-17 by bckim, 프리미엄 아머 컬렉션

// 2014-12-24 by shchoi 이달의 구 아머
BOOL CFieldIOCPSocket::ApplyItemDesParamOnlyOldAmor(ITEM *i_pItem, INT i_nStatLevel)
{
	if( i_pItem->IsExistDesParam(DES_OLD_OPTION_ITEM_DEFAULT_DESPARAM))
	{
		ApplyItemDesParam(i_pItem);
		
		BYTE tempStatLevel = i_nStatLevel - 1;
		if( 0 < tempStatLevel )
		{			
			SetParamFactor(DES_ITEM_ADDATTACK, (float)(i_pItem->GetParameterValue(DES_ITEM_ADDATTACK)*tempStatLevel));
			SetParamFactor(DES_ITEM_ADDATTACK_SEC, (float)(i_pItem->GetParameterValue(DES_ITEM_ADDATTACK_SEC)*tempStatLevel));
		}
		return TRUE;
	}
	return FALSE;
}

BOOL CFieldIOCPSocket::ReleaseItemDesParamOnlyOldAmor(ITEM *i_pItem, INT i_nStatLevel)
{
	if( i_pItem->IsExistDesParam(DES_OLD_OPTION_ITEM_DEFAULT_DESPARAM))
	{
		ReleaseItemDesParam(i_pItem);
		
		BYTE tempStatLevel = i_nStatLevel - 1;
		if( 0 < tempStatLevel )
		{			
			UnsetParamFactor(DES_ITEM_ADDATTACK, (float)(i_pItem->GetParameterValue(DES_ITEM_ADDATTACK)*tempStatLevel));
			UnsetParamFactor(DES_ITEM_ADDATTACK_SEC, (float)(i_pItem->GetParameterValue(DES_ITEM_ADDATTACK_SEC)*tempStatLevel));
		}
		return TRUE;
	}
	return FALSE;
}
// end 2014-12-24 by shchoi 이달의 구 아머

// 2006-07-21 by cmkwon, 인자 추가 - ClientIndex_t i_SkillUseClientIdx
BOOL CFieldIOCPSocket::SetParamFactor(CParamFactor *i_pParamFactor, DestParam_t desParam, float paramValue, ClientIndex_t i_SkillUseClientIdx/*=0*/)		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
{
	//////////////////////////////////////////////////////////////////////////
	// 2006-11-27 by dhjin, 
	//if(0.0f == paramValue){						return FALSE;}		// 2006-04-24 by cmkwon

	switch (desParam)
	{	
	case DES_SP:						// 14, 소울포인트
		{
			// 일정 시간 후에 SP 5만큼 증가, UnSet은 불필요하다
			m_character.CurrentSP += paramValue;
			if (m_character.CurrentSP >= m_character.SP)
			{
				m_character.CurrentSP = m_character.SP;
			}

			// MSG 전송
			INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_CURRENTSP, T_FC_CHARACTER_CHANGE_CURRENTSP, pMsgSP, pMsgSPBuf);
			pMsgSP->ClientIndex = m_character.ClientIndex;
			pMsgSP->CurrentSP = m_character.CurrentSP;
			SendAddData(pMsgSPBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_CURRENTSP));

			// DB에 저장
			QPARAM_CHARACTER_CHANGE_CURRENTHPDPSPEP *pQChangeHPDPSPEP
				= new QPARAM_CHARACTER_CHANGE_CURRENTHPDPSPEP;
			pQChangeHPDPSPEP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			pQChangeHPDPSPEP->CurrentHP = m_character.CurrentHP;
			pQChangeHPDPSPEP->CurrentDP = m_character.CurrentDP;
			pQChangeHPDPSPEP->CurrentSP = m_character.CurrentSP;
			pQChangeHPDPSPEP->CurrentEP = m_character.CurrentEP;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeCurrentHPDPSPEP, this, m_character.AccountUniqueNumber, pQChangeHPDPSPEP);
		}
		break;
	case DES_MINATTACK_01:				// 18, 최소 공격력 01
		{
			i_pParamFactor->pfm_MINATTACK_01 += paramValue;
		}
		break;
	case DES_MAXATTACK_01:				// 71, 최대 공격력 01
		{
			i_pParamFactor->pfm_MAXATTACK_01 += paramValue;
		}
		break;
	case DES_MINATTACK_02:				// 19, 최소 공격력 02
		{
			i_pParamFactor->pfm_MINATTACK_02 += paramValue;
		}
		break;
	case DES_MAXATTACK_02:				// 72, 최대 공격력 02
		{
			i_pParamFactor->pfm_MAXATTACK_02 += paramValue;
		}
		break;
	case DES_ATTACKPROBABILITY_01:		// 20, 공격확률 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_ATTACKPROBABILITY_01 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_ATTACKPROBABILITY_01 += paramValue;
		}
		break;
	case DES_ATTACKPROBABILITY_02:		// 21, 공격확률 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_ATTACKPROBABILITY_02 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_ATTACKPROBABILITY_02 += paramValue;
		}
		break;
	case DES_DEFENSE_01:				// 22, 방어력 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSE_01 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSE_01 += paramValue;
		}
		break;
	case DES_DEFENSE_02:				// 23, 방어력 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSE_02 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSE_02 += paramValue;
		}
		break;
	case DES_DEFENSEPROBABILITY_01:		// 24, 방어확률 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSEPROBABILITY_01 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSEPROBABILITY_01 += paramValue;
		}
		break;
	case DES_DEFENSEPROBABILITY_02:		// 25, 방어확률 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSEPROBABILITY_02 += ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSEPROBABILITY_02 += paramValue;
		}
		break;	
	case DES_REATTACKTIME_01:			// 31, (*) 리어택타임 01
		{
			i_pParamFactor->pfm_REATTACKTIME_01 += paramValue;
		}
		break;
	case DES_REATTACKTIME_02:			// 32, (*) 리어택타임 02
		{
			i_pParamFactor->pfm_REATTACKTIME_02 += paramValue;
		}
		break;	
	case DES_RANGE_01:					// 35, (*) 유효거리 01
		{
			i_pParamFactor->pfm_RANGE_01 += paramValue;
		}
		break;
	case DES_RANGE_02:					// 36, (*) 유효거리 02
		{
			i_pParamFactor->pfm_RANGE_02 += paramValue;
		}
		break;	
	case DES_EXPLOSIONRANGE_01:			// 40, 폭발반경 01
		{
			// 현재, Primary 무기는 해당 사항 없음, 20040909, kelovon
			i_pParamFactor->pfp_EXPLOSIONRANGE_01 += paramValue;
		}
		break;
	case DES_EXPLOSIONRANGE_02:			// 67, 폭발반경 02
		{
			// Secondary 무기에만 해당
			i_pParamFactor->pfp_EXPLOSIONRANGE_02 += paramValue;
		}
		break;
	case DES_SHOTNUM_01:				// 44, 일점사 당 발사 수 01
		{
			i_pParamFactor->pfp_SHOTNUM_01 += (INT)paramValue;
		}
		break;
	case DES_SHOTNUM_02:				// 69, 일점사 당 발사 수 02
		{
			i_pParamFactor->pfp_SHOTNUM_02 += (INT)paramValue;
		}
		break;
	case DES_MULTINUM_01:				// 45, 동시 발사 수 01
		{
			i_pParamFactor->pfp_MULTINUM_01 += (INT)paramValue;
		}
		break;
	case DES_MULTINUM_02:				// 70, 동시 발사 수 02
		{
			i_pParamFactor->pfp_MULTINUM_02 += (INT)paramValue;
		}
		break;	
	case DES_IMMEDIATE_HP_UP:			// 59, 에너지류, 현재 HP를 즉시 VALUE만큼 올려줌
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_HP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				this->ChangeCurrentHP(paramValue, DAMAGE_BY_NA, i_SkillUseClientIdx);
			}
		}
		break;
	case DES_IMMEDIATE_DP_UP:
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_DP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				this->ChangeCurrentDP(paramValue, i_SkillUseClientIdx);	
			}
		}
		break;
	case DES_IMMEDIATE_SP_UP:
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_SP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				this->ChangeCurrentSP(paramValue);
			}
		}
		break;
	case DES_IMMEDIATE_EP_UP:
		{
			this->ChangeCurrentEP(paramValue);
		}
		break;
	case DES_REACTION_RANGE:
		{
			i_pParamFactor->pfp_REACTION_RANGE += ((Prob256_t)paramValue);
		}
		break;
	case DES_SKILL_REDUCE_SHIELD_DAMAGE:	// 121, 쉴드에 가는 데미지를 줄여준다, 2005-11-21 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_REDUCE_SHIELD_DAMAGE += paramValue;
		}
		break;
	case DES_SKILL_COLLISIONDAMAGE_DOWN:	// 140, 배경 오브젝트,바닥 충돌시 데미지를 감소시킨다, 2005-11-21 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_COLLISIONDAMAGE_DOWN += paramValue;
		}
		break;
	case DES_SKILL_SMARTSP:					// 148, 자신이 사용하는 모든 스킬의 사용량을 줄여준다.(*), 2005-11-24 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_SMARTSP += paramValue;
		}
		break;

	case DES_RANGEANGLE_01:			// 37, 유효각도 01
		{
			i_pParamFactor->pfp_RANGEANGLE_01 += paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_RANGEANGLE_02:			// 38, 유효각도 02
		{
			i_pParamFactor->pfp_RANGEANGLE_02 += paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_TIME_01:				// 48, 지속 시간 01
		{
			i_pParamFactor->pfm_TIME_01	+= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_TIME_02:				// 49, 지속 시간 02
		{
			i_pParamFactor->pfm_TIME_02	+= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_REACTIONSPEED:				// 154, (*)하이퍼 무빙(반응속도), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_REACTIONSPEED += paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_ENGINEANGLE:					// 155, (*)하이퍼 무빙(선회각), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_ENGINEANGLE += paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_ENGINEBOOSTERANGLE:			// 156, (*)하이퍼 무빙(부스터 선회각), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_ENGINEBOOSTERANGLE += paramValue;		// 2005-12-21 by cmkwon
		}
		break;

// 2005-12-02 by cmkwon
//	case DES_SKILL_HYPERMOVING:				// 132, 2005-11-28 by cmkwon - 유닛의 전체 이동속도가 좋아지고, 부스터 사용이 되지 않는다.(*), 서버 처리 필요없음, 2005-11-28 by cmkwon
//		break;
//	case DES_SKILL_SLOWMOVING:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Debuff 체크로 처리 // 138, 적의 움직임을 둔하게 한다.(최대이동 속도, 부스터 속도, 이동 각도, 부스터 이동 각도)(*), 서버 처리 필요없음, 2005-11-26 by cmkwon
	case DES_SKILL_REVERSEENGINE:				// 145, 엔진이 후진이 가능하게 한다, 서버 처리 필요없음, 2005-11-26 by cmkwon
	case DES_SKILL_SUMMON_FORMATION_MEMBER:		// 149, 편대원 중 1명을 소환한다, 서버 처리 필요없음, 2005-11-24 by cmkwon
		break;
// 2006-03-30 by cmkwon
	case DES_DROP_EXP:					// 157, 2006-03-30 by cmkwon - 경험치, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_EXP					+= paramValue;
		}
		break;
	case DES_DROP_SPI:					// 158, 2006-03-30 by cmkwon - SPI, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_SPI					+= paramValue;
		}
		break;
	case DES_DROP_ITEM:					// 159, 2006-03-30 by cmkwon - 아이템 드랍율, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_ITEM					+= paramValue;
		}
		break;
	case DES_RARE_ITEM_DROP_RATE:		// 238,2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
		{
			i_pParamFactor->pfm_DROP_RAREITEM				+= paramValue;
		}
		break;
	case DES_HP_REPAIR_RATE_FLIGHTING:	// 160, 2006-03-30 by cmkwon - 비행시 HP 회복율
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_HP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				i_pParamFactor->pfm_HP_REPAIR_RATE_FLIGHTING	+= paramValue;
				this->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);	// 2006-04-12 by cmkwon, HP 회복 시작			
			}
		}
		break;
	case DES_DP_REPAIR_RATE:			// 161, 2006-03-30 by cmkwon - DP 회복율
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_DP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				i_pParamFactor->pfm_DP_REPAIR_RATE				+= paramValue;
				this->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);	// 2006-04-12 by cmkwon, DP 회복 시작						
			}
		}
		break;
	case DES_SP_REPAIR_RATE:			// 162, 2006-03-30 by cmkwon - SP 회복율
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(!this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_SP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				i_pParamFactor->pfm_SP_REPAIR_RATE				+= paramValue;
				this->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);	// 2006-04-12 by cmkwon, SP 회복 시작			
			}
		}
		break;
	case DES_SKILL_ROLLING_TIME:		// 170, 2006-11-17 by dhjin - 30초간 롤링 재사용 시간이 없다
		{
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_ROLLING_TIME		=	TRUE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_ROLLING_TIME	= TRUE;
		}
		break;
	case DES_SKILL_BARRIER:				// 173, 2006-11-17 by dhjin - A기어의 고급무기에 대한 무적스킬
		{
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_Barrier			=	TRUE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_Barrier	= TRUE;
		}
		break;
 	case DES_SKILL_SHIELD_PARALYZE:		// 175, 2006-11-24 by dhjin - A기어의 쉴드마비 스킬, 상대기어의 쉴드 회복율을 0으로 만든다
 		{	// 2009-09-09 ~ 2010-02-18 by dhjin, 인피니티 - Debuff 체크도 추가
 			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
 			//i_pParamFactor->pfb_SKILL_SHIELD_PARALYZE	=	TRUE;
 			i_pParamFactor->pfb_BitFlag.pfb_SKILL_SHIELD_PARALYZE	= TRUE;
 		}
 		break;
	case DES_SKILL_INVINCIBLE:			// 122, 2006-11-24 by dhjin - 무적상태
		{																											 
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_Invincible		=	TRUE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible		=	TRUE;
		}
		break;
	case DES_INVISIBLE:					// 131, 2006-11-24 by dhjin - 투명 모드로서 적에게 보이지 않으며, 레이다에도 잡히지 않는다.
		{
			m_UnitRenderInfo.RI_Invisible		=	TRUE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_INVISIBLE, T_FN_CHARACTER_CHANGE_INVISIBLE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bInvisible		= m_UnitRenderInfo.RI_Invisible;
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_INVISIBLE));
		}
		break;
	// 2013-05-09 by hskim, 세력 포인트 개선
	case DES_CASH_STEALTH:				// 108, 스텔스 카드
		{
			m_bStealthStateBySkill		=	TRUE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bStealthState2	= this->GetStealthState();
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
		}
		break;
	// end 2013-05-09 by hskim, 세력 포인트 개선
	case DES_SKILL_CAMOUFLAGE:			// 172, 2006-11-24 by dhjin - A기어의 위장 스킬
		{
			m_UnitRenderInfo.RI_Invisible		=	TRUE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_INVISIBLE, T_FN_CHARACTER_CHANGE_INVISIBLE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bInvisible		= m_UnitRenderInfo.RI_Invisible;
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_INVISIBLE));
		}
		break;
	case DES_WARHEAD_SPEED:				// 176, 2007-06-11 by cmkwon, 탄두의 속도
		{
			i_pParamFactor->pfm_WARHEAD_SPEED		+= paramValue;
		}
		break;
	case DES_HP:						// 13, // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가
		{
			i_pParamFactor->pfp_HP					+= paramValue;	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeHP(GetCharacterTotalHP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_DP:						// 89, // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가
		{
			i_pParamFactor->pfp_DP					+= paramValue;	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeDP(GetCharacterTotalDP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_EP:						// 15, // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가
		{
			i_pParamFactor->pfp_EP					+= paramValue;	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeEP(GetCharacterTotalEP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_MAX_SP_UP:
		{
			// 2010-08-26 by shcho&jsKim, 밤 아이템 구현 - Set
			i_pParamFactor->pfp_SP					+= paramValue;
		}
		break;	
	// 2008-09-22 by dhjin, 신규 인첸트
	case DES_ENGINE_BOOSTER_TIME_UP:
		{
			i_pParamFactor->pfn_ENGINE_BOOSTER_TIME_UP += paramValue;
		}
		break;
	case DES_ENGINE_MAX_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_MAX_SPEED_UP += paramValue;
		}
		break;
	case DES_ENGINE_MIN_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_MIN_SPEED_UP += paramValue;
		}
		break;
	case DES_ENGINE_BOOSTER_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_BOOSTER_SPEED_UP += paramValue;
		}
		break;
	case DES_ENGINE_GROUND_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_GROUND_SPEED_UP += paramValue;
		}
		break;
	case DES_RADAR_OBJECT_DETECT_RANGE:
		{
			i_pParamFactor->pfn_RADAR_OBJECT_DETECT_RANGE += (INT)paramValue;
		}
		break;
	case DES_PIERCE_UP_01:
		{
			i_pParamFactor->pfm_PIERCE_UP_01			+= paramValue;
		}
		break;
	case DES_PIERCE_UP_02:
		{
			i_pParamFactor->pfm_PIERCE_UP_02			+= paramValue;
		}
		break;
	case DES_ENGINE_ANGLE_UP:
		{
			i_pParamFactor->pfm_ENGINE_ANGLE_UP			+= paramValue;
		}
		break;
	case DES_ENGINE_BOOSTERANGLE_UP:
		{
			i_pParamFactor->pfm_ENGINE_BOOSTERANGLE_UP	+= paramValue;
		}
		break;	
	case DES_SKILL_DAMAGE_DISTRIBUTION:		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 설정
		{
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_DamageDistribution	= TRUE;
		}
		break;
	case DES_ITEM_RESISTANCE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 저항 아이템 사용 체크 
		{
			i_pParamFactor->pf_ITEM_Resistance	+= paramValue;
		}
		break;
	case DES_ITEM_ADDATTACK:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 사용 체크 
		{
			i_pParamFactor->pf_ITEM_AddAttack	+= paramValue;
		}
		break;
	case DES_ITEM_IGNOREDEFENCE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 방어력 무시 아이템 사용 체크
		{
			i_pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreDefence	= TRUE;
		}
		break;
	case DES_ITEM_IGNOREAVOID:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 회피력 무시 아이템 사용 체크
		{
			i_pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreAvoid	= TRUE;
		}
		break;
	case DES_ITEM_REDUCEDAMAGE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 절대값 감소 아이템 사용 체크
		{
			i_pParamFactor->pf_ITEM_ReduceDamage	+= paramValue;
		}
		break;
	case DES_ITEM_ADDATTACK_SEC:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류)
		{
			i_pParamFactor->pf_ITEM_AddAttack_Sec	+= paramValue;
		}
		break;
	case DES_ITEM_ONCE_RESISTANCE:		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가 
		{
			i_pParamFactor->pf_ITEM_OnceResistance	+= paramValue;
		}
		break;
	case DES_IMMEDIATE_HP_OR_DP_UP:		// 2010-03-31 by dhjin, 인피니티(기지방어) -
		{
			this->IncreaseCurrentHPDP(paramValue);
		}
		break;
	case DES_PLUS_WARPOINT_RATE:		// 2010-05-18 by cmkwon, WarPoint 증가 아이템 구현(일본요청) - 
		{
			i_pParamFactor->pfm_PLUS_WARPOINT_RATE	+= paramValue;
		}
		break;
// 2013-02-28 by bckim, 복귀유져 버프추가
#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN		// 다회성 WP 획득 데스파람 적용 
	case DES_PLUS_WARPOINT_RATE_FOR_RETURN_USER:		
		{
			i_pParamFactor->pfm_PLUS_WARPOINT_RATE	+= paramValue;
		}
		break;
#endif
// End. 2013-02-28 by bckim, 복귀유져 버프추가
	case DES_PCROOM_USE_CARD:
		{ // 2010-06-01 by shcho, PC방 권한 획득(캐쉬) 아이템 - 
			this->SetHomepremium(TRUE);
		}
		break;
	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	case DES_RARE_ITEM_PARTNER_SPEED:		
		{
			i_pParamFactor->pf_ITEMS_MOVE_SPEED_RATE	+= paramValue;
		}
		break;
	// end 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현

	// 2013-05-09 by hskim, 세력 포인트 개선
	case DES_SKILL_BUFF_MON_ATTACK_POWER:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_POWER	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_ATTACK_PROBABILITY:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_PROBABILITY	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_ATTACK_PIERCE:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_PIERCE	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_DEFENCE:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_DEFENCE	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_DEFENCE_AVOID:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_DEFENCE_AVOID	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_ATTACK_POWER:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK	+= paramValue;
		}
		break;
		// 2013-08-01 by jhseol, 역전의 버프 리뉴얼
	case DES_SKILL_BUFF_PVP_ATTACK_PROBABILITY:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK_PROBABILITY	+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_ATTACK_PIERCE:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK_PIERCE		+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_DEFENCE:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_DEFENCE				+= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_DEFENCE_PROBABILITY:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_DEFENCE_PROBABILITY	+= paramValue;
		}
		break;
		// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼
	// end 2013-05-09 by hskim, 세력 포인트 개선
		// 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화
	case DES_ATTACK_RANGE_01:
		{
			i_pParamFactor->pfm_ATTACK_RANGE_01	+= paramValue;
		}
		break;
	case DES_ATTACK_RANGE_02:
		{
			i_pParamFactor->pfm_ATTACK_RANGE_02	+= paramValue;
		}
		break;
		// end 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화
	default:
		{
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::UnsetParamFactor(CParamFactor *i_pParamFactor, DestParam_t desParam, float paramValue)			// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)	
{

///////////////////////////////////////////////////////////////////////////////
// 2006-11-27 by dhjin
//	if (desParam == DES_NULL)
//	{
//		return TRUE;
//	}

	switch (desParam)
	{
	case DES_NULL:					// 0, 대상 파라미터가 없는 경우 사용
		{
		}
		break;
	case DES_ATTACK_PART:			// 1, 공격 파트
		{
		}
		break;
	case DES_DEFENSE_PART:			// 2, 방어 파트
		{
		}
		break;
	case DES_FUEL_PART:				// 3, 연료 파트
		{
		}
		break;
	case DES_SOUL_PART:				// 4, 감응 파트
		{
		}
		break;
	case DES_SHIELD_PART:			// 5, 쉴드 파트
		{
		}
		break;
	case DES_DODGE_PART:			// 6, 회피 파트
		{
		}
		break;
	case DES_BODYCONDITION:			// 7, 몸상태
		{
		}
		break;
	case DES_ENDURANCE_01 :			// 8, 내구도 01
		{
		}
		break;
	case DES_ENDURANCE_02:			// 9, 내구도 02
		{
		}
		break;
	case DES_CHARGING_01:			// 10, 장탄수 01
		{
		}
		break;
	case DES_CHARGING_02:			// 11, 장탄수 02
		{
		}
		break;
	case DES_PROPENSITY:			// 12, 성향
		{
		}
		break;
	case DES_HP:					// 13, 히트포인트
		{
			m_ParamFactor.pfp_HP			-= paramValue;
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeHP(GetCharacterTotalHP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::UnsetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_DP:					// 89, // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::UnsetParamFactor() 에 처리 추가
		{
			m_ParamFactor.pfp_DP			-= paramValue;
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeDP(GetCharacterTotalDP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::UnsetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_SP:					// 14, 소울포인트
		{
			// do nothing
			// UnSet은 불필요함!
		}
		break;
	case DES_EP:					// 15, 엔진포인트
		{
			m_ParamFactor.pfp_EP		-= paramValue;
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//			this->ChangeEP(GetCharacterTotalEP());		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::UnsetParamFactor() 에 처리 추가 함
		}
		break;
	case DES_MAX_SP_UP:
		{
			// 2010-08-26 by shcho&jsKim, 밤 아이템 구현 unSet
			m_ParamFactor.pfp_SP		-= paramValue;
		}
		break;	
	case DES_SPRECOVERY:			// 16, 소울포인트회복력
		{
		}
		break;
	case DES_HPRECOVERY:			// 17, 에너지포인트회복력
		{
		}
		break;
	case DES_MINATTACK_01:				// 18, 최소 공격력 01
		{
			i_pParamFactor->pfm_MINATTACK_01 -= paramValue;
			i_pParamFactor->pfm_MINATTACK_01 = (i_pParamFactor->pfm_MINATTACK_01 < 0.01f)?0.0f:i_pParamFactor->pfm_MINATTACK_01;
		}
		break;
	case DES_MAXATTACK_01:				// 71, 최대 공격력 01
		{
			i_pParamFactor->pfm_MAXATTACK_01 -= paramValue;
		}
		break;
	case DES_MINATTACK_02:				// 19, 최소 공격력 02
		{
			i_pParamFactor->pfm_MINATTACK_02 -= paramValue;
		}
		break;
	case DES_MAXATTACK_02:				// 72, 최대 공격력 02
		{
			i_pParamFactor->pfm_MAXATTACK_02 -= paramValue;
		}
		break;
	case DES_ATTACKPROBABILITY_01:	// 20, 공격확률 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_ATTACKPROBABILITY_01 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_ATTACKPROBABILITY_01 -= paramValue;
		}
		break;
	case DES_ATTACKPROBABILITY_02:	// 21, 공격확률 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_ATTACKPROBABILITY_02 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_ATTACKPROBABILITY_02 -= paramValue;
		}
		break;
	case DES_DEFENSE_01:			// 22, 방어력 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSE_01 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSE_01 -= paramValue;
		}
		break;
	case DES_DEFENSE_02:			// 23, 방어력 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSE_02 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSE_02 -= paramValue;
		}
		break;
	case DES_DEFENSEPROBABILITY_01:	// 24, 방어확률 01
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSEPROBABILITY_01 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSEPROBABILITY_01 -= paramValue;
		}
		break;
	case DES_DEFENSEPROBABILITY_02:	// 25, 방어확률 02
		{
			// 2010-07-19 by dhjin, 확률 수식 변경
//			i_pParamFactor->pfp_DEFENSEPROBABILITY_02 -= ((Prob256_t)paramValue);
			i_pParamFactor->pfp_DEFENSEPROBABILITY_02 -= paramValue;
		}
		break;
	case DES_SKILLPROBABILITY_01:	// 26, 스킬공격확률 01
		{
		}
		break;
	case DES_SKILLPROBABILITY_02:	// 64, 스킬공격확률 02
		{
		}
		break;
	case DES_FACTIONRESISTANCE_01:		// 27, 속성저항력 01
		{
		}
		break;
	case DES_FACTIONRESISTANCE_02:		// 65, 속성저항력 02
		{
		}
		break;
	case DES_SPEED:					// 28, (*) 이동속도
		{
		}
		break;
	case DES_TRANSPORT:				// 29, 운반력
		{
		}
		break;
	case DES_MATERIAL:				// 30, 재질
		{
		}
		break;
	case DES_REATTACKTIME_01:		// 31, (*) 리어택타임 01
		{
			i_pParamFactor->pfm_REATTACKTIME_01 -= paramValue;
		}
		break;
	case DES_REATTACKTIME_02:		// 32, (*) 리어택타임 02
		{
			i_pParamFactor->pfm_REATTACKTIME_02 -= paramValue;
		}
		break;
	case DES_ABRASIONRATE_01:		// 33, 마모율 01
		{
		}
		break;
	case DES_ABRASIONRATE_02:		// 34, 마모율 02
		{
		}
		break;
	case DES_RANGE_01:				// 35, (*) 유효거리 01
		{
			i_pParamFactor->pfm_RANGE_01 -= paramValue;
		}
		break;
	case DES_RANGE_02:				// 36, (*) 유효거리 02
		{
			i_pParamFactor->pfm_RANGE_02 -= paramValue;
		}
		break;
	case DES_RANGEANGLE_01:			// 37, 유효각도 01
		{
			i_pParamFactor->pfp_RANGEANGLE_01 -= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_RANGEANGLE_02:			// 38, 유효각도 02
		{
			i_pParamFactor->pfp_RANGEANGLE_02 -= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_MULTITAGET_01:			// 39, 멀티타겟 01
		{
			// 서버에선 불필요
		}
		break;
	case DES_MULTITAGET_02:			// 66, 멀티타겟 02
		{
			// 서버에선 불필요
		}
		break;
	case DES_EXPLOSIONRANGE_01:		// 40, 폭발반경 01
		{
			// 현재, Primary 무기는 해당 사항 없음, 20040909, kelovon
			i_pParamFactor->pfp_EXPLOSIONRANGE_01 -= paramValue;
		}
		break;
	case DES_EXPLOSIONRANGE_02:		// 67, 폭발반경 02
		{
			// Secondary 무기에만 해당
			i_pParamFactor->pfp_EXPLOSIONRANGE_02 -= paramValue;
		}
		break;
	case DES_UNIT:					// 41, 유닛의 종류 (28 ~ 29이 같이 쓰여 유닛마다의 보정값으로 사용됨)
		{
		}
		break;
	case DES_REVISION:				// 42, 유닛의 보정값 (28 ~ 29이 같이 쓰여 유닛마다의 보정값으로 사용됨)
		{
		}
		break;
	case DES_FACTIONPROBABILITY_01:	// 43, 속성에 대한 방어확률 01
		{
		}
		break;
	case DES_FACTIONPROBABILITY_02:	// 68, 속성에 대한 방어확률 02
		{
		}
		break;
	case DES_SHOTNUM_01:			// 44, 일점사 당 발사 수 01
		{
			i_pParamFactor->pfp_SHOTNUM_01 -= (INT)paramValue;
		}
		break;
	case DES_SHOTNUM_02:			// 69, 일점사 당 발사 수 02
		{
			// 현재 2형 무기는 해당 사항 없음, 20031217, kelovon
			i_pParamFactor->pfp_SHOTNUM_02 -= (INT)paramValue;
		}
		break;
	case DES_MULTINUM_01:			// 45, 동시 발사 수 01
		{
			// 현재 1형 무기는 해당 사항 없음, 20031217, kelovon
			i_pParamFactor->pfp_MULTINUM_01 -= (INT)paramValue;
		}
		break;
	case DES_MULTINUM_02:			// 70, 동시 발사 수 02
		{
			i_pParamFactor->pfp_MULTINUM_02 -= (INT)paramValue;
		}
		break;
	case DES_ATTACKTIME_01:			// 46, 처음 공격 시의 타임 01
		{
			// check: 기획과 무기가 나올 때까지 연기함, 차징 무기류
		}
		break;
	case DES_ATTACKTIME_02:			// 47, 처음 공격 시의 타임 02
		{
			// check: 기획과 무기가 나올 때까지 연기함, 차징 무기류
		}
		break;
	case DES_REACTION_RANGE:
		{
			i_pParamFactor->pfp_REACTION_RANGE -= ((Prob256_t)paramValue);
		}
		break;
	case DES_SKILL_REDUCE_SHIELD_DAMAGE:	// 121, 쉴드에 가는 데미지를 줄여준다, 2005-11-21 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_REDUCE_SHIELD_DAMAGE -= paramValue;
		}
		break;
	case DES_SKILL_COLLISIONDAMAGE_DOWN:	// 140, 배경 오브젝트,바닥 충돌시 데미지를 감소시킨다, 2005-11-21 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_COLLISIONDAMAGE_DOWN -= paramValue;
		}
		break;
	case DES_SKILL_SMARTSP:					// 148, 자신이 사용하는 모든 스킬의 사용량을 줄여준다.(*), 2005-11-24 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_SMARTSP -= paramValue;
		}
		break;

	case DES_TIME_01:				// 48, 지속 시간 01
		{
			i_pParamFactor->pfm_TIME_01	-= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_TIME_02:				// 49, 지속 시간 02
		{
			i_pParamFactor->pfm_TIME_02	-= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_REACTIONSPEED:				// 154, (*)하이퍼 무빙(반응속도), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_REACTIONSPEED -= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_ENGINEANGLE:					// 155, (*)하이퍼 무빙(선회각), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_ENGINEANGLE -= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
	case DES_SKILL_ENGINEBOOSTERANGLE:			// 156, (*)하이퍼 무빙(부스터 선회각), 서버 처리 필요없음, 2005-12-02 by cmkwon
		{
			i_pParamFactor->pfm_SKILL_ENGINEBOOSTERANGLE -= paramValue;		// 2005-12-21 by cmkwon
		}
		break;
// 2005-12-02 by cmkwon
//	case DES_SKILL_HYPERMOVING:				// 132, 2005-11-28 by cmkwon - 유닛의 전체 이동속도가 좋아지고, 부스터 사용이 되지 않는다.(*), 서버 처리 필요없음, 2005-11-28 by cmkwon
//		break;
//	case DES_SKILL_SLOWMOVING:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Debuff 체크로 처리	// 138, (*)적의 움직임을 둔하게 한다.(최대이동 속도, 부스터 속도, 이동 각도, 부스터 이동 각도), 서버 처리 필요없음, 2005-11-26 by cmkwon
	case DES_SKILL_REVERSEENGINE:				// 145, (*)엔진이 후진이 가능하게 한다, 서버 처리 필요없음, 2005-11-26 by cmkwon
	case DES_SKILL_SUMMON_FORMATION_MEMBER:		// 149, (*)편대원 중 1명을 소환한다, 서버 처리 필요없음, 2005-11-24 by cmkwon
		break;
// 2006-03-30 by cmkwon
	case DES_DROP_EXP:					// 157, 2006-03-30 by cmkwon - 경험치, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_EXP = max(0.0f, i_pParamFactor->pfm_DROP_EXP - paramValue);
		}
		break;
	case DES_DROP_SPI:					// 158, 2006-03-30 by cmkwon - SPI, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_SPI = max(0.0f, i_pParamFactor->pfm_DROP_SPI - paramValue);
		}
		break;
	case DES_DROP_ITEM:					// 159, 2006-03-30 by cmkwon - 아이템 드랍율, 프리미엄과 중첩 불가
		{
			i_pParamFactor->pfm_DROP_ITEM = max(0.0f, i_pParamFactor->pfm_DROP_ITEM - paramValue);
		}
		break;
	case DES_RARE_ITEM_DROP_RATE:		// 238,2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
		{
			i_pParamFactor->pfm_DROP_RAREITEM = max(0.0f, i_pParamFactor->pfm_DROP_RAREITEM - paramValue);
		}
		break;
	case DES_HP_REPAIR_RATE_FLIGHTING:	// 160, 2006-03-30 by cmkwon - 비행시 HP 회복율
		{
			i_pParamFactor->pfm_HP_REPAIR_RATE_FLIGHTING -= paramValue;			
		}
		break;
	case DES_DP_REPAIR_RATE:			// 161, 2006-03-30 by cmkwon - DP 회복율
		{
			// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 아래와 같이 수정
			//i_pParamFactor->pfm_DP_REPAIR_RATE -= paramValue;
			i_pParamFactor->pfm_DP_REPAIR_RATE = max(0.0f, i_pParamFactor->pfm_DP_REPAIR_RATE - paramValue);
		}
		break;
	case DES_SP_REPAIR_RATE:			// 162, 2006-03-30 by cmkwon - SP 회복율
		{
			// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 아래와 같이 수정
			//i_pParamFactor->pfm_SP_REPAIR_RATE -= paramValue;
			i_pParamFactor->pfm_SP_REPAIR_RATE = max(0.0f, i_pParamFactor->pfm_SP_REPAIR_RATE - paramValue);
		}
		break;
	case DES_SKILL_ROLLING_TIME:		// 170, 2006-11-17 by dhjin - 30초간 롤링 재사용 시간이 없다
		{
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_ROLLING_TIME		=	FALSE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_ROLLING_TIME			= FALSE;
		}
		break;
	case DES_SKILL_BARRIER:				// 173, 2006-11-17 by dhjin - A기어의 고급무기에 대한 무적스킬
		{
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_Barrier			=	FALSE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_Barrier			= FALSE;
		}
		break;
 	case DES_SKILL_SHIELD_PARALYZE:		// 175, 2006-11-24 by dhjin - A기어의 쉴드마비 스킬, 상대기어의 쉴드 회복율을 0으로 만든다
 		{	// 2009-09-09 ~ 2010-02-18 by dhjin, 인피니티 - Debuff 체크도 추가
 			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
 			//i_pParamFactor->pfb_SKILL_SHIELD_PARALYZE	=	FALSE;
 			i_pParamFactor->pfb_BitFlag.pfb_SKILL_SHIELD_PARALYZE	= FALSE;
 		}
 		break;
	case DES_SKILL_INVINCIBLE:			// 122, 2006-11-24 by dhjin - 무적상태
		{
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
			//i_pParamFactor->pfb_SKILL_Invincible		=	FALSE;
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible		=	FALSE;
		}
		break;
	case DES_INVISIBLE:					// 131, 2006-11-24 by dhjin - 투명 모드로서 적에게 보이지 않으며, 레이다에도 잡히지 않는다.
		{
			m_UnitRenderInfo.RI_Invisible		=	FALSE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_INVISIBLE, T_FN_CHARACTER_CHANGE_INVISIBLE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bInvisible		= m_UnitRenderInfo.RI_Invisible;
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_INVISIBLE));
		}
		break;
	// 2013-05-09 by hskim, 세력 포인트 개선
	case DES_CASH_STEALTH:				// 108, 스텔스 카드
		{
			m_bStealthStateBySkill		=	FALSE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bStealthState2	= this->GetStealthState();
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
		}
		break;
	// end 2013-05-09 by hskim, 세력 포인트 개선
	case DES_SKILL_CAMOUFLAGE:			// 172, 2006-11-24 by dhjin - A기어의 위장 스킬
		{
			m_UnitRenderInfo.RI_Invisible		=	FALSE;
			INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_INVISIBLE, T_FN_CHARACTER_CHANGE_INVISIBLE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bInvisible		= m_UnitRenderInfo.RI_Invisible;
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_INVISIBLE));
		}
		break;
	case DES_WARHEAD_SPEED:				// 176, 2007-06-11 by cmkwon, 탄두의 속도
		{
			i_pParamFactor->pfm_WARHEAD_SPEED		-= paramValue;
		}
		break;
	// 2008-09-22 by dhjin, 신규 인첸트
	case DES_ENGINE_BOOSTER_TIME_UP:
		{
			i_pParamFactor->pfn_ENGINE_BOOSTER_TIME_UP -= paramValue;
		}
		break;
	case DES_ENGINE_MAX_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_MAX_SPEED_UP -= paramValue;
		}
		break;
	case DES_ENGINE_MIN_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_MIN_SPEED_UP -= paramValue;
		}
		break;
	case DES_ENGINE_BOOSTER_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_BOOSTER_SPEED_UP -= paramValue;
		}
		break;
	case DES_ENGINE_GROUND_SPEED_UP:
		{
			i_pParamFactor->pfn_ENGINE_GROUND_SPEED_UP -= paramValue;
		}
		break;
	case DES_RADAR_OBJECT_DETECT_RANGE:
		{
			i_pParamFactor->pfn_RADAR_OBJECT_DETECT_RANGE -= (INT)paramValue;
		}
		break;
	case DES_PIERCE_UP_01:
		{
			i_pParamFactor->pfm_PIERCE_UP_01			-= paramValue;
		}
		break;
	case DES_PIERCE_UP_02:
		{
			i_pParamFactor->pfm_PIERCE_UP_02			-= paramValue;
		}
		break;
	case DES_ENGINE_ANGLE_UP:
		{
			i_pParamFactor->pfm_ENGINE_ANGLE_UP			-= paramValue;
		}
		break;
	case DES_ENGINE_BOOSTERANGLE_UP:
		{
			i_pParamFactor->pfm_ENGINE_BOOSTERANGLE_UP	-= paramValue;
		}
		break;
	case DES_SKILL_DAMAGE_DISTRIBUTION:		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 해제
		{
			i_pParamFactor->pfb_BitFlag.pfb_SKILL_DamageDistribution	= FALSE;
		}
		break;
	case DES_ITEM_RESISTANCE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 저항 아이템 사용 체크 
		{
			i_pParamFactor->pf_ITEM_Resistance	-= paramValue;
		}
		break;
	case DES_ITEM_ADDATTACK:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 사용 체크 
		{
			i_pParamFactor->pf_ITEM_AddAttack	-= paramValue;
		}
		break;
	case DES_ITEM_IGNOREDEFENCE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 방어력 무시 아이템 사용 체크
		{
			i_pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreDefence	= FALSE;
		}
		break;
	case DES_ITEM_IGNOREAVOID:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 회피력 무시 아이템 사용 체크
		{
			i_pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreAvoid	= FALSE;
		}
		break;
	case DES_ITEM_REDUCEDAMAGE:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 절대값 감소 아이템 사용 체크
		{
			i_pParamFactor->pf_ITEM_ReduceDamage	-= paramValue;
		}
	case DES_ITEM_ADDATTACK_SEC:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류)
		{
			i_pParamFactor->pf_ITEM_AddAttack_Sec	-= paramValue;
		}
		break;
	case DES_ITEM_ONCE_RESISTANCE:		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가 
		{
			i_pParamFactor->pf_ITEM_OnceResistance	-= paramValue;
		}
		break;
	case DES_PLUS_WARPOINT_RATE:		// 2010-05-18 by cmkwon, WarPoint 증가 아이템 구현(일본요청) - 
		{
			i_pParamFactor->pfm_PLUS_WARPOINT_RATE	-= paramValue;
		}
		break;
		// 2013-02-28 by bckim, 복귀유져 버프추가
#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN		// 다회성 WP 획득 데스파람 적용 
	case DES_PLUS_WARPOINT_RATE_FOR_RETURN_USER:		
		{
			i_pParamFactor->pfm_PLUS_WARPOINT_RATE	-= paramValue;
		}
		break;
#endif
// End. 2013-02-28 by bckim, 복귀유져 버프추가
	case DES_PCROOM_USE_CARD:
		{// 2010-06-01 by shcho, PC방 권한 획득(캐쉬) 아이템 - 
			this->SetHomepremium(FALSE);
		}
		break;
		// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	case DES_RARE_ITEM_PARTNER_SPEED:		
		{
			i_pParamFactor->pf_ITEMS_MOVE_SPEED_RATE	-= paramValue;
		}
		break;
		// end 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	// 2013-05-09 by hskim, 세력 포인트 개선
	case DES_SKILL_BUFF_MON_ATTACK_POWER:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_POWER	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_ATTACK_PROBABILITY:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_PROBABILITY	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_ATTACK_PIERCE:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_ATTACK_PIERCE	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_DEFENCE:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_DEFENCE	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_MON_DEFENCE_AVOID:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_MON_DEFENCE_AVOID	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_ATTACK_POWER:		
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK	-= paramValue;
		}
		break;
		// 2013-08-01 by jhseol, 역전의 버프 리뉴얼
	case DES_SKILL_BUFF_PVP_ATTACK_PROBABILITY:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK_PROBABILITY	-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_ATTACK_PIERCE:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_ATTACK_PIERCE		-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_DEFENCE:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_DEFENCE				-= paramValue;
		}
		break;
	case DES_SKILL_BUFF_PVP_DEFENCE_PROBABILITY:
		{
			i_pParamFactor->pfp_SKILL_BUFF_PVP_DEFENCE_PROBABILITY	-= paramValue;
		}
		break;
		// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼
	// end 2013-05-09 by hskim, 세력 포인트 개선
		// 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화
	case DES_ATTACK_RANGE_01:
		{
			i_pParamFactor->pfm_ATTACK_RANGE_01	-= paramValue;
		}
		break;
	case DES_ATTACK_RANGE_02:
		{
			i_pParamFactor->pfm_ATTACK_RANGE_02	-= paramValue;
		}
		break;
		// end 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화
	default:
		{
			return FALSE;
		}
	}

	return TRUE;
}

// 2006-07-21 by cmkwon, 인자 추가 - ClientIndex_t i_SkillUseClientIdx
BOOL CFieldIOCPSocket::SetParamFactor(DestParam_t desParam, float paramValue, ClientIndex_t i_SkillUseClientIdx/*=0*/)		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
{
	return SetParamFactor(&this->m_ParamFactor, desParam, paramValue, i_SkillUseClientIdx);
}

BOOL CFieldIOCPSocket::UnsetParamFactor(DestParam_t desParam, float paramValue)				// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
{
	return UnsetParamFactor(&this->m_ParamFactor, desParam, paramValue);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			CParamFactor *CFieldIOCPSocket::GetParamFactor(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-11-22 ~ 2005-11-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CParamFactor *CFieldIOCPSocket::GetParamFactor(void)
{
	return &m_ParamFactor;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckSKILLInvincible(void)	
/// \brief		
/// \author		dhjin
/// \date		2006-11-27 ~ 2006-11-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckSKILLInvincible(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
	//if (TRUE == pParamFactor->pfb_SKILL_Invincible)
	if (TRUE == pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible)
	{
		return TRUE;
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckSKILLBarrier(void)
/// \brief		
/// \author		dhjin
/// \date		2006-11-27 ~ 2006-11-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckSKILLBarrier(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
	//if (TRUE == pParamFactor->pfb_SKILL_Barrier)
	if(pParamFactor->pfb_BitFlag.pfb_SKILL_Barrier)
	{
		return TRUE;
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckSKILLChainRolling(void)
/// \brief		
/// \author		dhjin
/// \date		2006-11-27 ~ 2006-11-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckSKILLChainRolling(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
	//if (TRUE == pParamFactor->pfb_SKILL_ROLLING_TIME)
	if(pParamFactor->pfb_BitFlag.pfb_SKILL_ROLLING_TIME)
	{
		return TRUE;
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsEnableRepairDP(void)
/// \brief		
/// \author		dhjin
/// \date		2006-11-27 ~ 2006-11-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsEnableRepairDP(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 기존 BOOL 변수를 비트구조체로 변경, 아래와 같이 수정
	//if (FALSE == pParamFactor->pfb_SKILL_SHIELD_PARALYZE)
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-18 by dhjin, 인피니티 - Debuff 체크도 추가 다음과 같이 수정
 	if(TRUE == pParamFactor->pfb_BitFlag.pfb_SKILL_SHIELD_PARALYZE)
 	{
 		return FALSE;
 	}
	if(TRUE == this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_SHIELD_PARALYZE)) {
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::CalcSKILLBigBoom(void)
/// \brief		
/// \author		dhjin
/// \date		2006-11-30 ~ 2006-11-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::CalcSKILLBigBoom(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_SKILL_Big_Boom_damage;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 
/// \author		cmkwon
/// \date		2009-08-17 ~ 2009-08-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsDamageDistributionToPartyMember(void)
{
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pfb_BitFlag.pfb_SKILL_DamageDistribution;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SetParamFactor_POS_ATTACHMENT(BYTE desParam, float paramValue)
/// \brief		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::SetParamFactor_POS_ATTACHMENT() 추가
/// \author		cmkwon
/// \date		2007-12-13 ~ 2007-12-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetParamFactor_POS_ATTACHMENT(BYTE desParam, float paramValue)
{
	if(DES_NULL == desParam)
	{
		return TRUE;	// 2007-12-13 by cmkwon, TRUE 를 리턴
	}

	switch(desParam)
	{
	case DES_HP:
	case DES_DP:
	case DES_EP:
		break;
	default:// 2006-04-04 by cmkwon, 무제한 액세서리는 DES_HP, DES_DP, DES_EP만 유효함
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SetParamFactor_POS_ATTACHMENT_ invalid DES_XXX !!, DES_XX(%d) ParamValue(%4.3f)\r\n", desParam, paramValue);
			return FALSE;
		}
	}

	return this->SetParamFactor(desParam, paramValue);	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::UnsetParamFactor_POS_ATTACHMENT(BYTE desParam, float paramValue)
/// \brief		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::UnsetParamFactor_POS_ATTACHMENT() 추가
/// \author		cmkwon
/// \date		2007-12-13 ~ 2007-12-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::UnsetParamFactor_POS_ATTACHMENT(BYTE desParam, float paramValue)
{
	if(DES_NULL == desParam)
	{
		return TRUE;	// 2007-12-13 by cmkwon, TRUE 를 리턴
	}

	switch(desParam)
	{
	case DES_HP:
	case DES_DP:
	case DES_EP:
		break;
	default:// 2006-04-04 by cmkwon, 무제한 액세서리는 DES_HP, DES_DP, DES_EP만 유효함
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::UnsetParamFactor_POS_ATTACHMENT_ invalid DES_XXX !!, DES_XX(%d) ParamValue(%4.3f)\r\n", desParam, paramValue);
			return FALSE;
		}
	}

	return this->UnsetParamFactor(desParam, paramValue);	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			USHORT CFieldIOCPSocket::GetParamValue_POS_ATTACHMENT(BYTE desParam)
/// \brief		// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - CFieldIOCPSocket::GetParamValue_POS_ATTACHMENT() 추가
/// \author		cmkwon
/// \date		2007-12-13 ~ 2007-12-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
USHORT CFieldIOCPSocket::GetParamValue_POS_ATTACHMENT(BYTE desParam)
{
	// 2010-06-15 by shcho&hslee 펫시스템
// 	if(0 == m_ItemAttachment.ItemNum
// 		|| ITEMKIND_ACCESSORY_UNLIMITED != m_ItemAttachment.Kind)
	if(0 == m_ItemAccessoryUnLimited.ItemNum
		|| ITEMKIND_ACCESSORY_UNLIMITED != m_ItemAccessoryUnLimited.Kind)
	{// 2007-12-13 by cmkwon, 장착아이템 체크
		return 0;
	}

	// 2010-06-15 by shcho&hslee 펫시스템
	return (USHORT)m_ItemAccessoryUnLimited.GetParameterValue(desParam);
}

// 2010-11-12 start by khkim 메모리핵:14(무게) 로그 오류 수정
BOOL CFieldIOCPSocket::ItemOptionInitialization(ITEM_GENERAL *pItemGeneral)
{
	if (NULL == pItemGeneral) 
	{						
		return FALSE; 
	}
	pItemGeneral->DesWeight			= 0.0f;
	return true;
}
// 2010-11-12 End by khkim 메모리핵(무게) 로그 오류 수정

BOOL CFieldIOCPSocket::ApplyRareFix(ITEM_GENERAL *pItemGeneral)
{
	if (NULL == pItemGeneral) {						return FALSE; }

	RARE_ITEM_INFO *pRareItemInfoPrefix = ms_pFieldIOCP->GetRareItemInfo(pItemGeneral->PrefixCodeNum);
	if (pRareItemInfoPrefix != NULL
		&& COMPARE_ITEMKIND(pRareItemInfoPrefix->ReqItemKind, pItemGeneral->Kind))
	{
		for (int i = 0; i < SIZE_DES_PARAM_PER_RARE_ITEM_INFO; i++)
		{
			if (pRareItemInfoPrefix->DesParameter[i] == DES_NULL) {				break; }

			// 2006-01-24 by cmkwon, 아이템 중량 인챈트 적용
			if(DES_WEIGHT_01 == pRareItemInfoPrefix->DesParameter[i] || DES_WEIGHT_02 == pRareItemInfoPrefix->DesParameter[i])
			{
				pItemGeneral->DesWeight		+= pRareItemInfoPrefix->ParameterValue[i];
			}

			SetParamFactor(pRareItemInfoPrefix->DesParameter[i], pRareItemInfoPrefix->ParameterValue[i]);
		}
	}

	RARE_ITEM_INFO *pRareItemInfoSuffix = ms_pFieldIOCP->GetRareItemInfo(pItemGeneral->SuffixCodeNum);
	if (pRareItemInfoSuffix != NULL
		&& COMPARE_ITEMKIND(pRareItemInfoSuffix->ReqItemKind, pItemGeneral->Kind))
	{
		for (int i = 0; i < SIZE_DES_PARAM_PER_RARE_ITEM_INFO; i++)
		{
			if (pRareItemInfoSuffix->DesParameter[i] == DES_NULL) {				break; }

			// 2006-01-24 by cmkwon, 아이템 중량 인챈트 적용
			if(DES_WEIGHT_01 == pRareItemInfoSuffix->DesParameter[i] || DES_WEIGHT_02 == pRareItemInfoSuffix->DesParameter[i])
			{
				pItemGeneral->DesWeight		+= pRareItemInfoSuffix->ParameterValue[i];
			}

			SetParamFactor(pRareItemInfoSuffix->DesParameter[i], pRareItemInfoSuffix->ParameterValue[i]);
		}
	}

	return TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_PREPARE_USE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_PREPARE_USE,
									MSG_FC_SKILL_PREPARE_USE, pMsgPrepareSkill);

// 2007-10-02 by cmkwon, 베트남 2차패스워드 수정 - 허가됨
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SKILL_PREPARE_USE 요청시 2차패스워드 체크
//	if(FALSE == this->CheckSecondaryPasswordLock())
//	{
//		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_SECPASS_LOCKED, pMsgPrepareSkill->SkillItemID.ItemNum);
//		return RES_BREAK;
//	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);			// lock m_mapItemGeneral, MSG_FC_SKILL_PREPARE_USE
	
	// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pMsgPrepareSkill->SkillItemID.ItemNum);
	if (pItemInfo == NULL)
	{
		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}
	ITEM_SKILL *pSkillItem
		= m_ItemManager.GetFirstSkillBySkillBaseNum(pItemInfo->NextSkill);
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	ITEM_SKILL *pSkillItem
		= m_ItemManager.GetFirstSkillBySkillBaseNum(pMsgPrepareSkill->SkillItemID.ItemNum);
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정

	if (pSkillItem == NULL)
	{
		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	// 2006-11-29 by dhjin, AttackTime이거나 SKILLTYPE_CHARGING은 FC_SKILL_PREPARE_USE를 사용함
//	if (pSkillItem->ItemInfo->SkillType != SKILLTYPE_CHARGING)
	if (0 >= pSkillItem->ItemInfo->AttackTime)
	{
		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_NO_SUCH_ITEM, pSkillItem->ItemNum);
		return RES_BREAK;
	}

	// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 중복 사용 방지
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	BYTE nOldSkillLevel = m_SkillManager.GetSkillActivatedLevelBySkillBaseNum(pItemInfo->NextSkill);
	if ( nOldSkillLevel >= pItemInfo->SkillLevel )
	{
		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_CANNOT_USE_SKILL, pSkillItem->ItemNum);
		return RES_BREAK;
	}
#endif
	// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 중복 사용 방지

	ATUM_DATE_TIME atBeforeUseTime = pSkillItem->UseTime;
	ATUM_DATE_TIME atCurTime(TRUE);

	//////////////////////////////////////////////////////////////////////////
	// 2006-12-18 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 UseTime 처리 
	// 2010. 08. 18. by hsLee. 관리자나 운영자도 스킬 재사용 시간 적용 하도록 수정.
	//if (FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION))
	//{// 2006-12-05 by dhjin, 관리자나 운영자이면 스킬 재사용 시간 없이 계속 사용가능
		if (FALSE == m_SkillManager.CheckUseSkillTime(pSkillItem, &atCurTime))
		{
			SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_NOT_ENOUGH_ELAPSE_TIME, pSkillItem->ItemNum); // 추가 에러 메세지
			return RES_BREAK;
		}
	//}

	// SP 확인
	if (pSkillItem->ItemInfo->ReqSP > m_character.CurrentSP)
	{
		SendErrorMessage(T_FC_SKILL_PREPARE_USE, ERR_PROTOCOL_NOT_ENOUGH_SP, pSkillItem->ItemNum);
		return RES_BREAK;
	}

	pSkillItem->UseTime		= atCurTime;

	// 2006-12-06 by dhjin, 시킬 사용 시간 DB에 저장
	m_SkillManager.SaveUseSkillTime(pSkillItem);	// 2006-12-18 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 UseTime 처리 

	// SP 감소
// 2009-02-18 by cmkwon, M기어 SmartSP 사용 후 적용 안되는 버그 수정 - 아래와 같이 DecreaseCurrentSP() 함수로 처리
// 	m_character.CurrentSP -= pSkillItem->ItemInfo->ReqSP;
// 	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTSP);
	// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	this->DecreaseCurrentSP(pSkillItem->ItemInfo->ReqSP, pSkillItem->ItemInfo->NextSkill);
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	this->DecreaseCurrentSP(pSkillItem->ItemInfo->ReqSP, SKILL_BASE_NUM(pSkillItem->ItemInfo->ReqSP));	// 2009-02-18 by cmkwon, M기어 SmartSP 사용 후 적용 안되는 버그 수정 -	
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정

	// 2014-03-31 by jekim, 스킬 사용 로그
#ifdef S_USE_SKILL_LOG_JEKIM
	CAtumLogSender::SendLogUseSkill(this,pSkillItem->ItemInfo->ItemNum,pSkillItem->ItemInfo->ItemAttribute,m_character.CurrentSP,pSkillItem->ItemInfo->ReqSP,0);
#endif
	// end 2014-03-31 by jekim, 스킬 사용 로그

	//////////////////////////////////////////////////////////////////////////
	// 2006-11-29 by dhjin, B기어의 BigBoom스킬이면 현재 HP를 데미지로
	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
	//if (IS_EXIST_DES_PARAM(pSkillItem->ItemInfo, DES_SKILL_BIG_BOOM))
	if (pSkillItem->ItemInfo->IsExistDesParam(DES_SKILL_BIG_BOOM))
	{
		CParamFactor *pParamFactor = this->GetParamFactor();
		pParamFactor->pf_SKILL_Big_Boom_damage	= m_character.CurrentHP;

		// 2007-07-11 by cmkwon, BigBoom이 PrepareUse 상태 여부 - TRUE로 설정
		m_SkillManager.SetPrepareUseBigBoom(TRUE);
	}

	// SP 회복 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);

	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_PREPARE_USE_OK, T_FC_SKILL_PREPARE_USE_OK, msgPrepareSkillOK, msgPrepareSkillOKBuf);
	msgPrepareSkillOK->ClientIndex = m_character.ClientIndex;
	msgPrepareSkillOK->SkillItemID = pMsgPrepareSkill->SkillItemID;
	SendInRangeMessageAroundMe(msgPrepareSkillOKBuf, MSG_SIZE(MSG_FC_SKILL_PREPARE_USE_OK), TRUE);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_CANCEL_PREPARE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_CANCEL_PREPARE,
									MSG_FC_SKILL_CANCEL_PREPARE, pMsgCancelPrepare);

	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_CANCEL_PREPARE_OK, T_FC_SKILL_CANCEL_PREPARE_OK, msgCancelPrepareOK, msgCancelPrepareOKBuf);
	msgCancelPrepareOK->ClientIndex = m_character.ClientIndex;
	msgCancelPrepareOK->SkillItemID = pMsgCancelPrepare->SkillItemID;
	SendInRangeMessageAroundMe(msgCancelPrepareOKBuf, MSG_SIZE(MSG_FC_SKILL_CANCEL_PREPARE_OK), TRUE);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_CONFIRM_USE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_CONFIRM_USE,
									MSG_FC_SKILL_CONFIRM_USE, pRMsg);

	return RES_RETURN_TRUE;		// 2009-04-06 by cmkwon, 콜오브 히어로 스킬 시스템 변경 - 
// 2009-04-06 by cmkwon, 콜오브 히어로 스킬 시스템 변경 - 시스템을 서버에서 자동으로 처리하는 것으로 수정함.
// 	if(FALSE == IsValidCharacter())
// 	{
// 		SendErrorMessage(T_FC_SKILL_CONFIRM_USE, ERR_INVALID_CHARACTER, pRMsg->TargetCharacterUID, pRMsg->UsingSkillItemNum);
// 		return RES_BREAK;
// 	}
// 
// 	CFieldIOCPSocket *pTargetFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->TargetCharacterUID);
// 	if(NULL == pTargetFISock
// 		|| FALSE == pTargetFISock->IsValidCharacter())
// 	{
// 		SendErrorMessage(T_FC_SKILL_CONFIRM_USE, ERR_INVALID_PEER_CHARACTER, pRMsg->TargetCharacterUID, pRMsg->UsingSkillItemNum);
// 		return RES_BREAK;
// 	}
// 
// 	CFieldMapProject *pFMPro = this->GetCurrentFieldMapProject();
// 	if(NULL == pFMPro
// 		|| ERR_NO_ERROR != pTargetFISock->IsEnableWarp(pFMPro->GetMapInfluenceType(), pFMPro->IsConflictAreaMap(), pFMPro->m_nQuestIndexForWarp))
// 	{
// 		SendErrorMessage(T_FC_SKILL_CONFIRM_USE, ERR_REQ_WARP_COMPLETIONQUEST_NOT_MATCHED, pRMsg->TargetCharacterUID, pRMsg->UsingSkillItemNum);
// 		return RES_BREAK;
// 	}
// 
// 	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_CONFIRM_USE, T_FC_SKILL_CONFIRM_USE, pSMsg, SendBuf);
// 	memcpy(pSMsg, pRMsg, sizeof(MSG_FC_SKILL_CONFIRM_USE));
// 	pTargetFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SKILL_CONFIRM_USE));
// 	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_CONFIRM_USE_ACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_CONFIRM_USE_ACK,
									MSG_FC_SKILL_CONFIRM_USE_ACK, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_SKILL_CONFIRM_USE_ACK, ERR_INVALID_CHARACTER, pRMsg->AttackCharacterUID, pRMsg->UsingSkillItemNum);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pAttackFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->AttackCharacterUID);
	if(NULL == pAttackFISock
		|| FALSE == pAttackFISock->IsValidCharacter(FALSE))	// 2009-04-06 by cmkwon, 콜오브 히어로 스킬 시스템 변경 - 시전자는 죽어도 상관 없음
	{
		SendErrorMessage(T_FC_SKILL_CONFIRM_USE_ACK, ERR_INVALID_PEER_CHARACTER, pRMsg->AttackCharacterUID, pRMsg->UsingSkillItemNum);
		return RES_BREAK;
	}

// 2009-04-06 by cmkwon, 콜오브 히어로 스킬 시스템 변경 - 아래와 같이 변경 함.
// 	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_CONFIRM_USE_ACK, T_FC_SKILL_CONFIRM_USE_ACK, pSMsg, SendBuf);
// 	memcpy(pSMsg, pRMsg, sizeof(MSG_FC_SKILL_CONFIRM_USE_ACK));
// 	pAttackFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SKILL_CONFIRM_USE_ACK));
	///////////////////////////////////////////////////////////////////////////////
	// 2009-04-06 by cmkwon, 콜오브 히어로 스킬 시스템 변경 - 
	SSKILL_CONFIRM_USE tmSkillConfirmUse;	
	MEMSET_ZERO(&tmSkillConfirmUse, sizeof(tmSkillConfirmUse));
	if(FALSE == pAttackFISock->m_SkillManager.PopSkillConfirmUse(pRMsg->SkillConfirmUseUID, pRMsg->TargetCharacterUID, pRMsg->UsingSkillItemNum, &tmSkillConfirmUse))
	{
		if(pRMsg->bYesOrNo)
		{// 2009-04-06 by cmkwon, 수락한 캐릭터에만 에러를 전송함.
			pAttackFISock->SendErrorMessage(T_FC_SKILL_CONFIRM_USE_ACK, ERR_PROTOCOL_CANNOT_USE_SKILL, pRMsg->AttackCharacterUID, pRMsg->UsingSkillItemNum);
		}
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_CONFIRM_USE_ACK, T_FC_SKILL_CONFIRM_USE_ACK, pSMsg, SendBuf);
	*pSMsg	= *pRMsg;
	pAttackFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SKILL_CONFIRM_USE_ACK));
	
	if(FALSE == pRMsg->bYesOrNo)
	{// 2009-04-06 by cmkwon, 콜오브 히어로 거부
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-29 by cmkwon, 콜오브히어로 승인시 워프 가능 체크(K0002789) - 
	CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(tmSkillConfirmUse.MapChannelIndex.MapIndex);
	
	if(NULL == pFMPro)
	{
		this->SendErrorMessage(T_FC_SKILL_CONFIRM_USE_ACK, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, this->GetCharacter()->CharacterUniqueNumber, tmSkillConfirmUse.UsingSkillItemNum);
		return RES_BREAK;
	}
	

	// 2010. 11. 24. by hsLee.	시전자가 버닝타임 맵일 경우 타겟의 버닝타임 맵 진입 조건 체크.
	if(NULL != this->ms_pFieldIOCP->GetBurningMapInfo(tmSkillConfirmUse.MapChannelIndex.MapIndex))
	{
		CFieldIOCPSocket *pTargetFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber ( pRMsg->TargetCharacterUID );

		if ( NULL == pTargetFISock 
			|| ERR_NO_ERROR != pTargetFISock->CheckPossibleBurningMapWarp ( tmSkillConfirmUse.MapChannelIndex.MapIndex ) )
		{
			this->SendErrorMessage ( T_FC_SKILL_CONFIRM_USE_ACK , ERR_PROTOCOL_NOT_WARP_BURNING_MAP , this->GetCharacter()->CharacterUniqueNumber , tmSkillConfirmUse.UsingSkillItemNum );
			return RES_BREAK;
		}
	}

	Err_t nErr = this->IsEnableWarp(pFMPro->GetMapInfluenceType(), pFMPro->IsConflictAreaMap(), pFMPro->m_nQuestIndexForWarp, FALSE, pFMPro);		// 2011-12-19 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	if(ERR_NO_ERROR != nErr)
	{// 2005-12-02 by cmkwon, 워프 불가
		this->SendErrorMessage(T_FC_SKILL_CONFIRM_USE_ACK, nErr, this->GetCharacter()->CharacterUniqueNumber, tmSkillConfirmUse.UsingSkillItemNum);
		return RES_BREAK;
	}

	EventResult_t nRetedResult = this->WarpToMap(tmSkillConfirmUse.MapChannelIndex, &(tmSkillConfirmUse.PositionVec3));
	if(EVENT_RESULT_CONTINUE != nRetedResult)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FC_SKILL_CONFIRM_USE_ACK# can't warp !! %s %d \r\n"
			, GetCharacterString(GetCharacter(), string()), nRetedResult);
		return RES_BREAK;
	}
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_TIMER_TIMEOUT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_TIMER_TIMEOUT,
									MSG_FC_TIMER_TIMEOUT, pMsgTimeOut);

	MEX_TIMER_EVENT	*pMexTimerEvent = &pMsgTimeOut->TimerEvent;
	TimeUnit_t		nCurrentServerTimeInMilliSeconds = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();

	// Valid한 타이머 이벤트인지 확인
	const MEX_TIMER_EVENT *pMexTimerEventServer = m_TimerManager.GetTimerEventByEventID(pMexTimerEvent->TimerUID);
	if (pMexTimerEventServer == NULL)
	{
		SendString128(STRING_128_DEBUG_L3, "INVALID %s uid(%d) interval(%d) gap(%d)",
			CAtumSJ::GetTimerTypeString(pMexTimerEvent->Type),
			(INT)pMexTimerEvent->TimerUID,
			(INT)pMexTimerEvent->TimeInterval,
			(INT)(nCurrentServerTimeInMilliSeconds - pMexTimerEvent->ExpireTime));
		return RES_BREAK;
	}

	if (pMexTimerEvent->bRepeatable)
	{
		SendString128(STRING_128_DEBUG_L3, "%s uid(%d) interval(%d) gap(%d)",
			CAtumSJ::GetTimerTypeString(pMexTimerEvent->Type),
			(INT)pMexTimerEvent->TimerUID,
			(INT)pMexTimerEvent->TimeInterval,
			(INT)(nCurrentServerTimeInMilliSeconds
				- (pMexTimerEvent->StartTimeStamp
					+ (pMexTimerEventServer->nRemainedRepeatCount - pMexTimerEvent->nRemainedRepeatCount)*pMexTimerEvent->TimeInterval)
			));
	}
	else
	{
		SendString128(STRING_128_DEBUG_L3, "%s uid(%d) interval(%d) gap(%d)",
			CAtumSJ::GetTimerTypeString(pMexTimerEvent->Type),
			(INT)pMexTimerEvent->TimerUID,
			(INT)pMexTimerEvent->TimeInterval,
			(INT)(nCurrentServerTimeInMilliSeconds - pMexTimerEvent->ExpireTime));
	}

	// event 발생
	switch (pMexTimerEvent->Type)
	{
		// check: 마인 지우기는 클라이언트에서 모두 관리하기로 하면서 제거함, 20041118, kelovon with dhkwon
//	case TE_TYPE_DELETE_MINE:
//		{
//			m_TimerManager.HandleTimerEventDeleteMine(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
//		}
//		break;
	case TE_TYPE_DELETE_DUMMY:
		{
			m_TimerManager.HandleTimerEventDeleteDummy(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DELETE_FIXER:
		{
			m_TimerManager.HandleTimerEventDeleteFixer(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DELETE_DECOY:
		{
			m_TimerManager.HandleTimerEventDeleteDecoy(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_RECOVER_HP:
		{
			m_TimerManager.HandleTimerEventRecoverHP(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_RECOVER_DP:
		{
			m_TimerManager.HandleTimerEventRecoverDP(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_RECOVER_SP:
		{
			m_TimerManager.HandleTimerEventRecoverSP(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DECREASE_SP:
		{
			m_TimerManager.HandleTimerEventDecreaseSP(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_GRADUAL_HP_UP:
	case TE_TYPE_GRADUAL_DP_UP:
	case TE_TYPE_GRADUAL_EP_UP:
	case TE_TYPE_GRADUAL_SHIELD_UP:
		{
			m_TimerManager.HandleTimerEventSequential(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_IMMEDIATE_HP_UP:
		{
			m_TimerManager.m_bImmediateHPTimerRunning	= FALSE;
		}
		break;
	case TE_TYPE_IMMEDIATE_DP_UP:
		{
			m_TimerManager.m_bImmediateDPTimerRunning	= FALSE;
		}
		break;
	case TE_TYPE_IMMEDIATE_SP_UP:
		{
			m_TimerManager.m_bImmediateSPTimerRunning	= FALSE;
		}
		break;
	case TE_TYPE_IMMEDIATE_EP_UP:
		{
			m_TimerManager.m_bImmediateEPTimerRunning	= FALSE;
		}
		break;
	case TE_TYPE_REQUEST_TIMEOUT:
		{
			m_TimerManager.HandleTimerEventRequestTimeOut(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_TEST:
		{
			m_TimerManager.HandleTimerEventTest(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DO_MINUTELY_WORK:
		{
			m_TimerManager.HandleTimerEventDoMinutelyWork(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
			//////////////////////////////////////////////////////////////////////
			// 2012-10-05 by jhseol, NPlay PC방 모듈 - 매 분마다 pc방 정보를 보내준다
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
			if( FALSE == g_pFieldGlobal->IsArenaServer() )
			{
				INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_PCBANG_PREMIUN_APPLY, T_FC_CHARACTER_PCBANG_PREMIUN_APPLY, pPremiun, SendBuf);
				pPremiun->PremiumApply = m_bIsPCBangClient;
				ms_pFieldIOCP->LoadGameEventMessage(this, &pPremiun->msg);
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_PCBANG_PREMIUN_APPLY));
			}
#endif
			// end 2012-10-05 by jhseol, NPlay PC방 모듈 - 매 분마다 pc방 정보를 보내준다

		}
		break;
		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	case TE_TYPE_DOTSKILL_STEALING:
		{
			m_TimerManager.HandleTimerEventDotSkillStealing(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DOTSKILL_DRAIN:
		{
			m_TimerManager.HandleTimerEventDotSkillDrain(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	case TE_TYPE_DOTSKILL_TIME_BOMB:
		{
			m_TimerManager.HandleTimerEventDotSkillTimeBomb(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
	case TE_TYPE_FIXED_TERM_SHAPE:
		{
			m_TimerManager.HandleTimerFixedTermShape(pMexTimerEvent, nCurrentServerTimeInMilliSeconds);
		}
		break;
	// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
	default:
		{
			SendErrorMessage(T_FC_TIMER_TIMEOUT, ERR_PROTOCOL_NO_SUCH_TIMER_EVENT_TYPE, pMexTimerEvent->Type);
			return RES_BREAK;
		}
	} // end - switch

	// 지우기
	if (pMexTimerEvent->bRepeatable && pMexTimerEvent->nRemainedRepeatCount > 0)
	{
		// Repeatable Timer Event
		SendString128(STRING_128_DEBUG_L3, "REPEAT TE, cnt: %d", pMexTimerEvent->nRemainedRepeatCount);
	}
	else
	{
		// 일회성 Timer Event
		if (!m_TimerManager.DeleteTimerEventByTimerUID(pMexTimerEvent->TimerUID))
		{
			// 비정상인 경우
			SendErrorMessage(T_FC_TIMER_TIMEOUT, ERR_PROTOCOL_NO_SUCH_TIME_LIMIT_EVENT_IN_BUCKET,
							pMexTimerEvent->Type, 0, (char*)CAtumSJ::GetTimerTypeString(pMexTimerEvent->Type));
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_USE_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_USE_SKILL,
									MSG_FC_SKILL_USE_SKILL,	pMsgUseSkill);

// 2007-10-02 by cmkwon, 베트남 2차패스워드 수정 - 허가됨
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SKILL_USE_SKILL 요청시 2차패스워드 체크
//	if(FALSE == this->CheckSecondaryPasswordLock())
//	{
//		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_SECPASS_LOCKED);
//		return RES_BREAK;
//	}

	BYTE SendBuf[SIZE_MAX_PACKET];

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);			// lock m_mapItemGeneral, MSG_FC_SKILL_USE_SKILL
	
	if(FALSE == IsValidCharacter())
	{// 2006-09-19 by cmkwon, 체크
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-01 by cmkwon, 모든 스킬을 투명상태에서 사용 불가 처리 - 
	if(this->IsInvisibleCharacter())
	{
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}
	
	ITEM_SKILL *pSkillItem = m_ItemManager.GetItemSkillByUID(pMsgUseSkill->SkillItemID.ItemUID);
	if (pSkillItem == NULL)
	{
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	ITEM_SKILL TempSkillItem = *pSkillItem;

	// start 2012-01-17 by hskim, EP4 [비분쟁 지역] - 유저간 공격 금지 구역
	if( TRUE == IS_MAP_INFLUENCE_NON_DISPUTE(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()) )
	{
		if( pMsgUseSkill->TargetIndex < MONSTER_CLIENT_INDEX_START_NUM && 0 != pMsgUseSkill->TargetIndex )
		{
			// 나한테 쓰는 스킬도 현제 체크하고 있음, 추후 유지 보수시 참고하세요.
			if( TempSkillItem.ItemInfo->IsExistDesParam(DES_SKILL_CANCELALL) ||
				TempSkillItem.ItemInfo->IsExistDesParam(DES_SKILL_SLOWMOVING) ||
				TempSkillItem.ItemInfo->IsExistDesParam(DES_SKILL_SHIELD_PARALYZE) ||
				TempSkillItem.ItemInfo->IsExistDesParam(DES_SKILL_STOPMAGIC) )
			{
				SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CANNOT_USE_SKILL, TempSkillItem.ItemNum, 0);
				return RES_BREAK;
			}
		}
	}
	// start 2012-01-17 by hskim, EP4 [비분쟁 지역] - 유저간 공격 금지 구역

	igLock.auto_unlock_cancel();
	
//	// SKILLTYPE_CHARGING은 SP 소모를 FC_SKILL_PREPARE_USE에서 수행함
//	if (pSkillItem->ItemInfo->SkillType != SKILLTYPE_CHARGING
//		&& pSkillItem->ItemInfo->ReqSP > m_character.CurrentSP)
	// 2006-12-08 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 sp 소모 하였기 때문에 체크하지 않는다 
	if (0 >= TempSkillItem.ItemInfo->AttackTime
		&& TempSkillItem.ItemInfo->ReqSP > m_character.CurrentSP)
	{// SP 확인

		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_NOT_ENOUGH_SP, TempSkillItem.ItemNum);
		return RES_BREAK;		
	}

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사일런트 디버프 체크, 상위에서 체크한다.
	if(this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_SILENCE_SKILL)) {
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_DEBUFF_SKILL_APPLYING_SLIENCE);
		return RES_BREAK;
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 스킬 추가
#ifdef S_EP4_HSKIM		// ON/OFF 기능 구현
	if(this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_STOPMAGIC)) {
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_DEBUFF_SKILL_APPLYING_STOPMAGIC);
		return RES_BREAK;
	}
#endif
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 스킬 추가

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 개인 상점 처리 - 구입/판매
	if(IS_BAZAAR_SKILL(TempSkillItem.ItemInfo))
	{
// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//		if(FALSE == this->IsValidGameUser())
//		{// 2006-08-09 by cmkwon, 베트남 정액제 처리 - 개인 상점 스킬 사용 불가
//			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_INVALID_GAMEUSER);
//			return RES_BREAK;
//		}

// 2006-11-14 by cmkwon, 한글버전도 멤버쉽과 상관없이 이용가능
//		if(FALSE == m_ItemManager.IsExistPremiumCard())
//		{// 2006-09-14 by dhjin, 맴버쉽 이용자가 아니면 개인 상점 스킬 사용 불가
//
//			if(LANGUAGE_TYPE_KOREAN == g_pFieldGlobal->GetLanguageType())
//			{// 2006-10-11 by cmkwon, 한글버전만 불가, 영어/베트남은 상관없이 이용가능 
//				SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_NO_MEMBERSHIP_USER, pSkillItem->ItemNum);
//				return RES_BREAK;
//			}
//		}
		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-01 by dhjin, 베트남 2차패스워드 적용 - 개인상점 시 체크
		if(FALSE == this->CheckSecondaryPasswordLock())
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_SECPASS_LOCKED);
			return RES_BREAK;
		}

		// 2007-07-09 by dhjin, 상점 들어가는 문제로 체크
		if(NULL != m_pCurrentBuildingNPC)
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_USING_SHOP, TempSkillItem.ItemNum);
			return RES_BREAK;
		}

// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//		if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
		if(this->IsInvisibleCharacter())
		{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_INVISIBLE_STATE, TempSkillItem.ItemNum);
			return RES_BREAK;
		}
		
// 2007-05-25 by dhjin, 퀘스트 진행중에도 개인 상점 개설 가능
//		if(this->GetCharacterQuestInProgress())
//		{// 2006-08-07 by cmkwon, 퀘스트 진행중에는 개인 상점 개설 불가
//			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_QUEST_IS_IN_PROGRESS, TempSkillItem.ItemNum);
//			return RES_BREAK;
//		}

		if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CANNOT_USE_SKILL, TempSkillItem.ItemNum, 0);
			return RES_BREAK;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-06-01 by dhjin, 마을에서 개인 상점 가능으로 변경
// 2008-02-12 by cmkwon, IS_CITY_MAP_INDEX() 매크로를 포괄적인 도시맵인지 여부를 리턴
// 		if(!(TRUE == IS_BAZAAR_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
// 			|| TRUE == IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex)) )
//		if(FALSE == IS_BAZAAR_MAP_INDEX(m_character.MapChannelIndex.MapIndex))

		if(FALSE == IS_INFLUENCE_CITY_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex)
			&& FALSE == IS_CONFERENCEROOM_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
		{// 2008-02-12 by cmkwon, 세력별도시맵과 회의룸만 가능, // 2006-07-31 by cmkwon
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CANNOT_USE_SKILL, TempSkillItem.ItemNum, 1);
			return RES_BREAK;
		}
//////////////////////////////////////////////////////////////////////////
// 2007-06-04 by dhjin, 바자맵 어느 곳에서나 사용가능.
//		if(IS_BAZAAR_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
//		{
//			EVENTINFO *pEvInfo = GetCurrentFieldMapChannel()->GetTileEventInfoW(&m_character.PositionVector);
//			if (EVENT_TYPE_ENTER_BUILDING_BAZAAR != pEvInfo->m_bEventType)
//			{
//				SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CANNOT_USE_SKILL, TempSkillItem.ItemNum, 2);
//				return RES_BREAK;
//			}
//		}

		if(NULL != m_pFieldParty)
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_IMPOSSIBLE_IN_PARTY, TempSkillItem.ItemNum);
			return RES_BREAK;
		}
		//////////////////////////////////////////////////////////////////////////
		// 2007-04-26 by dhjin, ARENA 상태에서는 바자스킬 사용 불가
		if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_ARENA_STATE, TempSkillItem.ItemNum);
			return RES_BREAK;
		}

		// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 인피 상태 값을 메인서버로 전송한다. 인피 상태 체크
		if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState ) {
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_INFINITY_STATE);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-06-04 by cmkwon, 바자상점은 캐릭터모드 상태에서만 가능
		if(FALSE == m_character.CharacterMode)
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED, TempSkillItem.ItemNum);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 거래 신청 후 개인상점을 여는 것을 막음
		if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_ITEM_TRADING, TempSkillItem.ItemNum);
			return RES_BREAK;
		}

		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
		//if(IS_EXIST_DES_PARAM(TempSkillItem.ItemInfo, DES_BAZAAR_SELL))
		if(TempSkillItem.ItemInfo->IsExistDesParam(DES_BAZAAR_SELL))
		{
			m_bazaarManager.SetBazaarTypeAndState(BAZAAR_TYPE_SELL, BAZAAR_STATE_READY);
		}
		else
		{
			m_bazaarManager.SetBazaarTypeAndState(BAZAAR_TYPE_BUY, BAZAAR_STATE_READY);
		}
	}


	ATUM_DATE_TIME atBeforeUseTime = TempSkillItem.UseTime;
	ATUM_DATE_TIME atCurTime(TRUE);

	//////////////////////////////////////////////////////////////////////////
	// 2006-12-05 by dhjin, 스킬 재사용 시간 체크
	// 2010. 08. 18. by hsLee. 관리자나 운영자도 스킬 재사용 시간 적용 하도록 수정.
	if ( /*FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION)
		&&*/ 0 >= TempSkillItem.ItemInfo->AttackTime	// 2006-12-18 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 UseTime 처리 
		&& FALSE == m_bNoCool)	// 2015-01-29 by shchoi 자살 명령어, 노쿨 명령어 추가
	{// 2006-12-05 by dhjin, 관리자나 운영자이면 스킬 재사용 시간 없이 계속 사용가능
	
		if (FALSE == m_SkillManager.CheckUseSkillTime(&TempSkillItem, &atCurTime))
		{
			SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_NOT_ENOUGH_ELAPSE_TIME, TempSkillItem.ItemNum); // 추가 에러 메세지
			return RES_BREAK;
		}
	}

	TempSkillItem.UseTime		= atCurTime;	// 2006-12-13 by dhjin, 관리자도 DB에 사용 시간 저장되게 수정.

	///////////////////////////////////////////////////////////////////////////////	
	// 스킬 사용
	if (!m_SkillManager.UseSkill(&TempSkillItem, pMsgUseSkill))
	{
		TempSkillItem.UseTime		= atBeforeUseTime;
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_CANNOT_USE_SKILL, TempSkillItem.ItemNum, 3);
		return RES_BREAK;
	}

	// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pMsgUseSkill->SkillItemID.ItemNum);
	if ( NULL == pItemInfo )
	{
		SendErrorMessage(T_FC_SKILL_USE_SKILL, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}
	// 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	if( AGEAR_SKILL_BASENUM_BARIAL == pItemInfo->NextSkill )
	{
		m_structUsingItemBitFlag.bUsingBarialSkill = TRUE;
	}
	// end 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	
	// 2013-02-06 by jhseol, M기억 무적스킬 이벡트 버그
	else if( MGEAR_SKILL_BASENUM_INVICIBLE == pItemInfo->NextSkill )
	{
		m_structUsingItemBitFlag.bUsingInvicibleSkill = TRUE;
	}
	// end 2013-02-06 by jhseol, M기억 무적스킬 이벡트 버그
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	if( AGEAR_SKILL_BASENUM_BARIAL == SKILL_BASE_NUM(pMsgUseSkill->SkillItemID.ItemNum) )
	{
		m_structUsingItemBitFlag.bUsingBarialSkill = TRUE;
	}
	// end 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그

	// 2013-02-06 by jhseol, M기억 무적스킬 이벡트 버그
	else if( MGEAR_SKILL_BASENUM_INVICIBLE == SKILL_BASE_NUM(pMsgUseSkill->SkillItemID.ItemNum) )
	{
		m_structUsingItemBitFlag.bUsingInvicibleSkill = TRUE;
	}
	// end 2013-02-06 by jhseol, M기억 무적스킬 이벡트 버그
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정

	// 2007-02-07 by dhjin, Lock관련해서 풀었던 pSkillItem을 다시 Lock잡고 스킬 사용 시간을 업데이트 한다.
	this->SetSkillUseTime(TempSkillItem.UniqueNumber, TempSkillItem.UseTime);

	// SP 감소
//	if (pSkillItem->ItemInfo->SkillType != SKILLTYPE_CHARGING)
	//////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 sp 소모 처리
	if (0 >= TempSkillItem.ItemInfo->AttackTime)
	{// SKILLTYPE_CHARGING은 T_FC_SKILL_PREPARE_USE에서 SP 소모를 처리한다.
// 2005-11-22 by cmkwon
//		ChangeCurrentSP(-pSkillItem->ItemInfo->ReqSP);
		
		// 2006-12-06 by dhjin, 시킬 사용 시간 DB에 저장
		m_SkillManager.SaveUseSkillTime(&TempSkillItem);	// 2006-12-18 by dhjin, attacktime이 존재하는 스킬은 T_FC_SKILL_PREPARE_USE에서 UseTime 처리 
		// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		DecreaseCurrentSP(TempSkillItem.ItemInfo->ReqSP, TempSkillItem.ItemInfo->NextSkill);
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		DecreaseCurrentSP(TempSkillItem.ItemInfo->ReqSP, SKILL_BASE_NUM(TempSkillItem.ItemInfo->ItemNum));
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
		// 2014-03-31 by jekim, 스킬 사용 로그
#ifdef S_USE_SKILL_LOG_JEKIM
		CAtumLogSender::SendLogUseSkill(this,TempSkillItem.ItemInfo->ItemNum,TempSkillItem.ItemInfo->ItemAttribute,m_character.CurrentSP,TempSkillItem.ItemInfo->ReqSP,0);
#endif
		// end 2014-03-31 by jekim, 스킬 사용 로그
	}

	// 컨트롤 스킬일 경우 NPC 서버로도 보냄
// 2005-11-22 by cmkwon
//	switch(pSkillItem->ItemInfo->ItemNum)
//	{
//	case BT_SKILL_QUICKTURN:
//	case BT_SKILL_REVERSETURN:
//	case BT_SKILL_COPTERFLIGHT:
//	case OT_SKILL_PARALLELMOVEMENT:
//	case OT_SKILL_SCREWPUSHING:
//	case OT_SKILL_OVERRISING:
//	case DT_SKILL_DASH:
//	case DT_SKILL_AUTODRIVING:
//	case ST_SKILL_YOYOSPINNING:
//	case ST_SKILL_OVERBOOST:
//	case ST_SKILL_COPTERFLIGHT:

	// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	switch(TempSkillItem.ItemInfo->NextSkill)
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	switch(SKILL_BASE_NUM(TempSkillItem.ItemInfo->ItemNum))
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
	{
	case BGEAR_SKILL_BASENUM_BACKMOVEMACH:
	case BGEAR_SKILL_BASENUM_TURNAROUND:
	case IGEAR_SKILL_BASENUM_BACKMOVEMACH:
	case IGEAR_SKILL_BASENUM_TURNAROUND:
		{
			INIT_MSG(MSG_FN_SKILL_USE_SKILL_OK, T_FN_SKILL_USE_SKILL_OK, pSendNPC, SendBuf);
			pSendNPC->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			pSendNPC->SkillItemID	= pMsgUseSkill->SkillItemID;
			pSendNPC->AttackIndex	= pMsgUseSkill->AttackIndex;
			pSendNPC->TargetIndex	= pMsgUseSkill->TargetIndex;
			m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_SKILL_USE_SKILL_OK));
		}
		break;
	default:
		{
			if(IS_MONSTER_CLIENT_INDEX(pMsgUseSkill->TargetIndex))
			{
				INIT_MSG(MSG_FN_SKILL_USE_SKILL_OK, T_FN_SKILL_USE_SKILL_OK, pSendNPC, SendBuf);
				pSendNPC->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
				pSendNPC->SkillItemID	= pMsgUseSkill->SkillItemID;
				pSendNPC->AttackIndex	= pMsgUseSkill->AttackIndex;
				pSendNPC->TargetIndex	= pMsgUseSkill->TargetIndex;
				m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_SKILL_USE_SKILL_OK));
			}
		}
	}

	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
	//if(IS_EXIST_DES_PARAM(TempSkillItem.ItemInfo, DES_SKILL_BIG_BOOM))
	if(TempSkillItem.ItemInfo->IsExistDesParam(DES_SKILL_BIG_BOOM))
	{// 2006-12-01 by dhjin
		
		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
		SATTACK_PARAMETER attParam;
		MEMSET_ZERO(&attParam, sizeof(attParam));
		attParam.pWeaponItemInfo	= TempSkillItem.ItemInfo;
		//attParam.MultiTargetIndex	= pMsgUseSkill->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가	// 임시 삭제 (클라에서 쓰는지 확인후 추후 살림)
		ProcessSplashDamageC2All(this, &attParam, TempSkillItem.ItemInfo->Range, &m_character.PositionVector);
		CharacterDeadRoutine(DAMAGE_BY_NA);

		// 2007-07-11 by cmkwon, BigBoom이 PrepareUse 상태 여부 - 빅붐 스킬이 사용됨, FALSE로 설정, 해제함
		m_SkillManager.SetPrepareUseBigBoom(FALSE);
	}

	CheckQuestUseItem(TempSkillItem.ItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인 - 특정 스킬레벨만 확인
	CheckQuestUseItem(TempSkillItem.ItemInfo->NextSkill);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인 - 모든 스킬레벨을 확인
	if ( 0 != TempSkillItem.ItemInfo->LinkItem ) CheckQuestUseItem(TempSkillItem.ItemInfo->LinkItem);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인 - 스킬카드 확인
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetSkillUseTime(UID64_t i_skillUID, ATUM_DATE_TIME i_atUseTime)
/// \brief		
/// \author		dhjin
/// \date		2007-02-07 ~ 2007-02-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetSkillUseTime(UID64_t i_skillUID, ATUM_DATE_TIME i_atUseTime)
{
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_SKILL *pSkillItem = m_ItemManager.GetItemSkillByUID(i_skillUID);
	if(pSkillItem)
	{
		pSkillItem->UseTime = i_atUseTime;
	}
}

ProcessResult CFieldIOCPSocket::Process_FC_SKILL_CANCEL_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SKILL_CANCEL_SKILL,
									MSG_FC_SKILL_CANCEL_SKILL, pMsgCancelSkill);

	ITEM *pSkillItemInfo = ms_pFieldIOCP->GetItemInfo(pMsgCancelSkill->SkillItemID.ItemNum);
	if (pSkillItemInfo == NULL)
	{
		SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgCancelSkill->SkillItemID.ItemNum);	// 2006-07-13 by cmkwon, 버그 수정
		return RES_BREAK;
	}

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	if(TRUE == IS_ORBIT_SKILL(pSkillItemInfo->OrbitType)) {
		// OrbitSkill 해제
		this->m_SkillManager.ReleaseOrbitSkill(pSkillItemInfo);
		if(NULL != this->m_pFieldParty) {
			INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_RELEASE, T_FC_CHARACTER_DEBUFF_DOT_RELEASE, pSendMsg, DebuffDotSendBuf);
			pSendMsg->CharacterUID		= this->m_character.CharacterUniqueNumber;
			pSendMsg->SkillItemNum		= pMsgCancelSkill->SkillItemID.ItemNum;
			this->m_pFieldParty->SendMsgToMembers(DebuffDotSendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_RELEASE), this->m_character.CharacterUniqueNumber);
		}
		return RES_RETURN_TRUE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 개인 상점 리셋
	if(IS_BAZAAR_SKILL(pSkillItemInfo))
	{
	 	m_bazaarManager.ResetBazaarManager();
	}

// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 아래와 같이 CFieldSkillManager::CancelSkill()로 처리
// 	// CANCEL_SKILL은 시간형(SKILLTYPE_TIMELIMIT), 토글형(SKILLTYPE_TOGGLE) 스킬에만 사용할 수 있다.
// 	switch(pSkillItemInfo->SkillType)
// 	{
// 	case SKILLTYPE_TIMELIMIT:
// 		{
// 			if (m_SkillManager.IsSkillActivatedByItemNum(pMsgCancelSkill->SkillItemID.ItemNum))
// 			{
// 				if (!m_SkillManager.DeactivateSkill(pSkillItemInfo, TRUE))
// 				{
// #ifdef _DEBUG
// 					SendString128(STRING_128_ADMIN_CMD, "ATTACKPROBABILITY01: %d @CancelSkill", m_ParamFactor.pfp_ATTACKPROBABILITY_01);
// #endif
// 					SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, ERR_PROTOCOL_NO_SUCH_SKILL, pSkillItemInfo->ItemNum);
// 					return RES_BREAK;
// 				}
// 			}
// 		}
// 		break;
// 	case SKILLTYPE_TOGGLE:
// 		{
// 			if (m_SkillManager.IsSkillActivatedByItemNum(pMsgCancelSkill->SkillItemID.ItemNum))
// 			{
// 				if (!m_SkillManager.DeactivateSkill(pSkillItemInfo, TRUE))
// 				{
// #ifdef _DEBUG
// 					SendString128(STRING_128_ADMIN_CMD, "ATTACKPROBABILITY01: %d @CancelSkill", m_ParamFactor.pfp_ATTACKPROBABILITY_01);
// #endif
// 					SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, ERR_PROTOCOL_NO_SUCH_SKILL, pSkillItemInfo->ItemNum);
// 					return RES_BREAK;
// 				}
// 			}
// 		}
// 		break;
// 	case SKILLTYPE_CLICK:
// 		{
// 			if (SKILL_KIND(pSkillItemInfo->ItemNum) == SKILL_KIND_CONTROL)
// 			{
// 				// 자신을 제외한 주위 유닛에게 뿌려주기만 한다.
// 				INIT_MSG_OF_SIZE(MSG_FC_SKILL_INVALIDATE_SKILL, T_FC_SKILL_INVALIDATE_SKILL, msgInvalidateSkill, msgInvalidateSkillBuf);
// 				msgInvalidateSkill->SkillItemID.ItemNum = pSkillItemInfo->ItemNum;
// 				msgInvalidateSkill->SkillItemID.ItemUID = 0;	// 클라이언트 불필요함
// 				msgInvalidateSkill->ClientIndex = m_character.ClientIndex;
// 				SendInRangeMessageAroundMe(msgInvalidateSkillBuf, MSG_SIZE(MSG_FC_SKILL_INVALIDATE_SKILL), TRUE);
// 			}
// 		}
// 		break;
// 	case SKILLTYPE_CHARGING:
// 		{// 2006-11-30 by dhjin, 차징 취소도 클라이언트로 전송한다
// 			m_SkillManager.ClearChargingSkill(pSkillItemInfo);			// 2006-12-06 by cmkwon, 취소된 차징스킬을 초기화 한다.
// 		}
// 		break;
// 	default:
// 		{
// 			SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, ERR_PROTOCOL_INVALID_SKILLTYPE, pSkillItemInfo->ItemNum);
// 		}
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldSkillManager::CancelSkill()로 처리
	if(COMPARE_BIT_FLAG(pSkillItemInfo->ItemAttribute, SKILL_ATTR_PARTY_FORMATION_SKILL))
	{// 2009-08-11 by cmkwon, 편대 스킬은 클라이언트에서 해제 불가
		SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, ERR_PROTOCOL_INVALID_SKILLTYPE, pSkillItemInfo->ItemNum);
		return RES_BREAK;
	}
	Err_t nErr = m_SkillManager.CancelSkill(pSkillItemInfo, pMsgCancelSkill);
	if(ERR_NO_ERROR != nErr)
	{
		SendErrorMessage(T_FC_SKILL_CANCEL_SKILL, nErr, pSkillItemInfo->ItemNum);
		return RES_BREAK;
	}

	// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	if( AGEAR_SKILL_BASENUM_BARIAL == pSkillItemInfo->NextSkill )
	{
		m_structUsingItemBitFlag.bUsingBarialSkill = FALSE;
	}
	// end 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	
	// 2013-02-06 by jhseol, M기어 무적스킬 이벡트 버그
	else if( MGEAR_SKILL_BASENUM_INVICIBLE == pSkillItemInfo->NextSkill )
	{
		m_structUsingItemBitFlag.bUsingInvicibleSkill = FALSE;
	}
	// 2013-02-06 by jhseol, M기어 무적스킬 이벡트 버그
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	if( AGEAR_SKILL_BASENUM_BARIAL == SKILL_BASE_NUM(pMsgCancelSkill->SkillItemID.ItemNum) )
	{
		m_structUsingItemBitFlag.bUsingBarialSkill = FALSE;
	}
	// end 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그

	// 2013-02-06 by jhseol, M기어 무적스킬 이벡트 버그
	else if( MGEAR_SKILL_BASENUM_INVICIBLE == SKILL_BASE_NUM(pMsgCancelSkill->SkillItemID.ItemNum) )
	{
		m_structUsingItemBitFlag.bUsingInvicibleSkill = FALSE;
	}
	// 2013-02-06 by jhseol, M기어 무적스킬 이벡트 버그
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
	// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정

	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-06 by cmkwon, 체프도 제거 해야함
	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
	//if(IS_EXIST_DES_PARAM(pSkillItemInfo, DES_SKILL_HALLUCINATION))
	if(pSkillItemInfo->IsExistDesParam(DES_SKILL_HALLUCINATION))
	{
		mt_auto_lock mtA(&m_mtvectFieldDummy);
		m_bDummyCheck			= FALSE;
		if(false == m_mtvectFieldDummy.empty())
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_DELETE_DUMMY_OK, T_FC_BATTLE_DELETE_DUMMY_OK, pSMsg, SendBuf);
			pSMsg->AttackIndex		= GetCharacter()->ClientIndex;
			mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
			for(; itr != m_mtvectFieldDummy.end(); itr++)
			{
				FIELD_DUMMY *pFDummy	= *itr;
				pSMsg->ItemFieldIndex	= pFDummy->ItemFieldIndex;

				// 2006-12-06 by cmkwon, 주위의 모든 캐릭터에게 전송
				this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_BATTLE_DELETE_DUMMY_OK), TRUE);
			}
			this->DeleteAllFieldDummy();			// 2006-12-06 by cmkwon, 모든 체프를 제거한다.
		}
	}

	if(SKILLTYPE_CHARGING == pSkillItemInfo->SkillType
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
//		|| IS_EXIST_DES_PARAM(pSkillItemInfo, DES_INVISIBLE)			// 2006-11-28 by dhjin, 인비지블 스킬이 취소 되면 주위 클라이언트에게 알린다
//		|| IS_EXIST_DES_PARAM(pSkillItemInfo, DES_SKILL_CAMOUFLAGE))	// 2006-11-28 by dhjin, 위장 스킬이 취소 되면 주위 클라이언트에게 알린다
		|| pSkillItemInfo->IsExistDesParam(DES_INVISIBLE)				// 2006-11-28 by dhjin, 인비지블 스킬이 취소 되면 주위 클라이언트에게 알린다
		|| pSkillItemInfo->IsExistDesParam(DES_SKILL_CAMOUFLAGE))		// 2006-11-28 by dhjin, 위장 스킬이 취소 되면 주위 클라이언트에게 알린다
	{
		INIT_MSG_OF_SIZE(MSG_FC_SKILL_CANCEL_SKILL_OK, T_FC_SKILL_CANCEL_SKILL_OK, msgCancelSkill, msgCancelSkillBuf);
		msgCancelSkill->SkillItemID.ItemNum		= pSkillItemInfo->ItemNum; 
		msgCancelSkill->ClientIndex				= m_character.ClientIndex;
		msgCancelSkill->AttackSkillItemNum0		= pMsgCancelSkill->AttackSkillItemNum0;		// 2006-12-12 by cmkwon, 추가함
		SendInRangeMessageAroundMe(msgCancelSkillBuf, MSG_SIZE(MSG_FC_SKILL_CANCEL_SKILL_OK), TRUE);	
	}
#ifdef _DEBUG
	SendString128(STRING_128_ADMIN_CMD, "ATTACKPROBABILITY01: %d @CancelSkill", m_ParamFactor.pfp_ATTACKPROBABILITY_01);
#endif

	return RES_RETURN_TRUE;
}

CFieldIOCPSocket* CFieldIOCPSocket::SendTradeCanceledAndReset(CFieldIOCPSocket *pPeerSocket, BOOL bSendToPeer)
{
	if (NULL == pPeerSocket && bSendToPeer)
	{
		pPeerSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
	}

	// 2009-02-05 by cmkwon, 전쟁시 강제 워프 관련 처리 수정 - 유효하지 않은 상태의 소켓이면 NULL로 설정.
	if(pPeerSocket && FALSE == pPeerSocket->IsValidCharacter(FALSE))
	{
		pPeerSocket	= NULL;
	}

	// Send MSG_FC_TRADE_CANCEL_TRADE_OK
	INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_CANCEL_TRADE_OK, T_FC_TRADE_CANCEL_TRADE_OK, msgCancelOK, SendBuf);

	// To Me
	msgCancelOK->CharacterUniqueNumber = m_peerTraderCharacterUniqueNumber;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_TRADE_OK));

	// To Peer
	if (pPeerSocket != NULL && bSendToPeer)
	{
		msgCancelOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		pPeerSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_TRADE_OK));
	}

	// reset trade
	m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	m_bOKTradeChecked = FALSE;
	m_mapTradeItem.clearLock();
	if (pPeerSocket != NULL)
	{
		pPeerSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
		pPeerSocket->m_bOKTradeChecked = FALSE;
		pPeerSocket->m_mapTradeItem.clearLock();
	}

	return pPeerSocket;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::TradeCheckEnableInsertItems(CFieldIOCPSocket *i_pPeerFISock)
/// \brief		
/// \author		cmkwon
/// \date		2006-05-11 ~ 2006-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::TradeCheckEnableInsertItems(CFieldIOCPSocket *i_pPeerFISock)
{
// 2006-05-11 by cmkwon, EPII 에서는 중량은 장착 아이템만 계산한다.
// 	if (GetCurrentLoadagePercentage(i_pPeerFISock->GetTradeItemWeight()) > 1.0f)
//	{
// 		return ERR_PROTOCOL_ITEM_OVER_WEIGHT;
// 	}

	int nInsertInventoryCnt = 0;
	mtmapUID2TradeItem::iterator itr = i_pPeerFISock->m_mapTradeItem.begin();
	for(; itr != i_pPeerFISock->m_mapTradeItem.end(); itr++)
	{
		TradeItem *pTItem = &itr->second;
		if(FALSE == IS_COUNTABLE_ITEM(pTItem->pStoreItem->Kind))
		{
			ITEM_GENERAL *pPeerItemG = i_pPeerFISock->m_ItemManager.GetItemGeneralByUID(pTItem->pStoreItem->UniqueNumber);
			if(NULL == pPeerItemG)
			{// 2006-05-12 by cmkwon, 주는 사람의 인벤에 아이템이 없다
				return ERR_PROTOCOL_NO_SUCH_ITEM;
			}
			nInsertInventoryCnt++;
		}
		else
		{
			ITEM_GENERAL *pPeerItemG = i_pPeerFISock->m_ItemManager.GetFirstItemGeneralByItemNum(pTItem->pStoreItem->ItemNum);
			if(NULL == pPeerItemG)
			{// 2006-05-12 by cmkwon, 주는 사람의 인벤에 아이템이 없다
				return ERR_PROTOCOL_NO_SUCH_ITEM;
			}
			else if(pTItem->Count > pPeerItemG->CurrentCount)
			{// 2006-05-12 by cmkwon, 주는 사람의 인벤 아이템 개수가 주려는 개수보다 작다
				return ERR_PROTOCOL_INVALID_ITEM_COUNT;
			}

			ITEM_GENERAL *pMeItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pTItem->pStoreItem->ItemNum);
			if(NULL == pMeItemG)
			{
				nInsertInventoryCnt++;
			}
			else if(MAX_ITEM_COUNTS < (INT64)pTItem->Count + (INT64)pMeItemG->CurrentCount)
			{// 2006-05-11 by cmkwon, 카운터블 아이템 최대 개수 초과
				return ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER;
			}
		}
		
		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
		if(m_ItemManager.GetMaxInventoryCount() < this->m_ItemManager.GetInventoryItemCounts() + nInsertInventoryCnt)
		{
			return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
		}
	}

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::TradeInsertItems(CFieldIOCPSocket *i_pPeerFISock)
/// \brief		
/// \author		cmkwon
/// \date		2006-05-11 ~ 2006-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::TradeInsertItems(CFieldIOCPSocket *i_pPeerFISock)
{
	mtmapUID2TradeItem::iterator itr = i_pPeerFISock->m_mapTradeItem.begin();
	for(; itr != i_pPeerFISock->m_mapTradeItem.end(); itr++)
	{
		TradeItem		*pTItem			= &itr->second;
		ITEM_GENERAL	*pTradeItemG	= pTItem->pStoreItem;
		if(FALSE == IS_COUNTABLE_ITEM(pTItem->pStoreItem->Kind))
		{
			///////////////////////////////////////////////////////////////////////////////
			// 1. 주는 사람 Log 남기기
			ITEM_GENERAL tmpItemOnlyForLog = *pTradeItemG;	// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
			tmpItemOnlyForLog.CurrentCount = 0;
			CAtumLogSender::SendLogMessageITEMTradeSend(i_pPeerFISock, &tmpItemOnlyForLog, 1, &this->m_character);	// 아이템 거래: 주기, non-countable

			///////////////////////////////////////////////////////////////////////////////
			// 2. 아이템 소유자의 인벤에서 삭제함 - DB에 업데이트 하지 않음, 메모리를 삭제하지 않음

			i_pPeerFISock->m_ItemManager.RemoveTimerFixedTermShape(pTradeItemG);		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

			if(FALSE == i_pPeerFISock->m_ItemManager.DeleteItemFromCharacterByUID(pTradeItemG->UniqueNumber, IUT_TRADE, ITEM_IN_CHARACTER, FALSE, TRUE, FALSE))
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-23 by cmkwon, 아이템 복사 버그 체크 추가
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] DeleteItemFromCharacterByUID error !!, CharInfo(%s) ItemInfo(%s) PeerCharInfo(%s)\r\n"
					, GetCharacterString(i_pPeerFISock->GetCharacter(), string()), GetItemGeneralString(pTradeItemG, string()), GetCharacterString(GetCharacter(), string()));
			}

			///////////////////////////////////////////////////////////////////////////////
			// 3. 내 인벤에 아이템 추가 - DB에 업데이트 하지 않음
			pTradeItemG->Wear				= FALSE;
			pTradeItemG->ItemWindowIndex	= POS_INVALID_POSITION;
			this->m_ItemManager.InsertItemGeneralByPointer(pTradeItemG, IUT_TRADE, FALSE, ITEM_IN_CHARACTER, FALSE);

			this->m_ItemManager.RegisterTimerFixedTermShape(pTradeItemG);		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

			///////////////////////////////////////////////////////////////////////////////
			// 4. 인챈트 처리
			vectENCHANT tmvectEnchant;
			if(i_pPeerFISock->PopAllEnchantByItemUID(&tmvectEnchant, pTradeItemG->UniqueNumber))
			{
				this->DeleteAllEnchantToItem(pTradeItemG->UniqueNumber);		// 2006-05-11 by cmkwon, 만약을 위해 초기화
				this->InsertEnchantToItem(pTradeItemG, &tmvectEnchant);
			}

			///////////////////////////////////////////////////////////////////////////////
			// 5. 펫 데이터 처리
			// 2010-06-15 by shcho&hslee 펫시스템 - 거래 시 펫 정보 처리
			if(pTradeItemG->Kind == ITEMKIND_PET_ITEM)
			{
				TradePetData( pTradeItemG->UniqueNumber, i_pPeerFISock );
			}
			// END 2010-06-15 by shcho&hslee 펫시스템 - 거래 시 펫 정보 처리

			///////////////////////////////////////////////////////////////////////////////
			// 6. DB로 전송
			QPARAM_TRADE_MOVEITEM	*pMoveItem = new QPARAM_TRADE_MOVEITEM;
			pMoveItem->ToAccountUID		= GetCharacter()->AccountUniqueNumber;
			pMoveItem->ToCharacterUID	= GetCharacter()->CharacterUniqueNumber;
			pMoveItem->FromCharacterUID	= i_pPeerFISock->GetCharacter()->CharacterUniqueNumber;
			pMoveItem->MoveItemUID		= pTItem->pStoreItem->UniqueNumber;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_TradeMoveItem, this, m_character.AccountUniqueNumber, pMoveItem);

			///////////////////////////////////////////////////////////////////////////////
			// 7. 받는 사람 로그 남기기
			CAtumLogSender::SendLogMessageITEMTradeRecv(this, pTradeItemG, 1, &i_pPeerFISock->m_character);	// 아이템 거래: 받기, non-countable
		}
		else
		{
			int nTradeItemNum = pTradeItemG->ItemNum;

			///////////////////////////////////////////////////////////////////////////////
			// 1. 내 인벤토리에 아이템 추가함
			m_ItemManager.InsertItemGeneralByItemNum(pTradeItemG->ItemNum, pTItem->Count, IUT_TRADE, ITEM_IN_CHARACTER, TRUE, TRUE, i_pPeerFISock->GetCharacter()->CharacterUniqueNumber);

			///////////////////////////////////////////////////////////////////////////////
			// 2. 받는 사람 로그 남기기
			ITEM_GENERAL *pMeItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pTradeItemG->ItemNum);
			if(NULL == pMeItemG)
			{// 2006-05-15 by cmkwon, 아이템이 추가되는 경우, DB에 추가중, 로그도 DB 추가 후 남긴다.
				char szSysLog[1024];
				wsprintf(szSysLog, "[Notify] CFieldIOCPSocket::TradeInsertItems_ Insert to DB CharacterInfo(%s:%d), PeerCharacterInfo(%s:%d), ItemNum(%d), ItemCount(%d)\r\n"
					, m_character.CharacterName, m_character.CharacterUniqueNumber
					, i_pPeerFISock->GetCharacter()->CharacterName, i_pPeerFISock->GetCharacter()->CharacterUniqueNumber
					, pTItem->pStoreItem->ItemNum, pTItem->Count);
				DbgOut(szSysLog);
				g_pFieldGlobal->WriteSystemLog(szSysLog);
			}
			else
			{
				CAtumLogSender::SendLogMessageITEMTradeRecv(this, pMeItemG, pTItem->Count, &i_pPeerFISock->m_character);
			}
			
			///////////////////////////////////////////////////////////////////////////////
			// 3. 주는 사람 인벤에서 아이템 개수 줄임 혹은 제거
			ITEM_GENERAL tmpItemOnlyForLog = *pTradeItemG;	// 주의: only 로그용!
			i_pPeerFISock->m_ItemManager.UpdateItemCountByPointer(pTItem->pStoreItem, -pTItem->Count, IUT_TRADE);// start 2012-11-21 by khkim, GLog 2차

			///////////////////////////////////////////////////////////////////////////////
			// 4. 주는 사람 로그
			ITEM_GENERAL *pPeerItemG = i_pPeerFISock->m_ItemManager.GetFirstItemGeneralByItemNum(nTradeItemNum);
			if(NULL == pPeerItemG)
			{
				tmpItemOnlyForLog.CurrentCount	= 0;
				CAtumLogSender::SendLogMessageITEMTradeSend(i_pPeerFISock, &tmpItemOnlyForLog, pTItem->Count, &this->m_character);	// 아이템 거래: 주기
			}
			else
			{
				CAtumLogSender::SendLogMessageITEMTradeSend(i_pPeerFISock, pPeerItemG, pTItem->Count, &this->m_character);	// 아이템 거래: 주기
			}
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::TradePetData(UID64_t i_tradeUniqeNum, CFieldIOCPSocket *i_pPeerFISock)
/// \brief		// 2010-06-15 by shcho&hslee 펫시스템 - 거래 시 펫 정보 처리		
/// \author		shcho & jskim
/// \date		2006-08-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::TradePetData(UID64_t i_tradeUniqeNum, CFieldIOCPSocket *i_pPeerFISock)
{
	// 변수 정의 ////////
	vecPetCurrentInfo::iterator Mypetiter = this->m_ItemManager.m_vectPetCurrentInfo.begin();
	vecPetCurrentInfo::iterator Peerpetiter = i_pPeerFISock->m_ItemManager.m_vectPetCurrentInfo.begin();
	/////////////////////

	for( ; Mypetiter != this->m_ItemManager.m_vectPetCurrentInfo.end() ; ++Mypetiter)
	{
		// 정보가 없을 경우 루프를 빠져나옴
		if( Mypetiter == this->m_ItemManager.m_vectPetCurrentInfo.end() )
		{
			break;
		}
		if( i_tradeUniqeNum == (*Mypetiter)->CreatedPetUID )
		{ // 자신의 펫이면 삭제
			this->m_ItemManager.DeleteItemPetFromCharacterByUID((*Mypetiter)->CreatedPetUID); // 함수 내부에서 삭제 전송.
			break;
		}
	}

	//자신의 펫이 아니라면 추가
	for( ; Peerpetiter != i_pPeerFISock->m_ItemManager.m_vectPetCurrentInfo.end() ; ++Peerpetiter )
 	{
		if( i_tradeUniqeNum == (*Peerpetiter)->CreatedPetUID )
 		{
 			this->m_ItemManager.m_vectPetCurrentInfo.push_back( (*Peerpetiter) );
			//추가된 팻 정보 전송
			INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_PET_BASEDATA, T_FC_TRADE_INSERT_CURRENT_PET_DATA, Petcurrentmsg, sendPetbuff);

			///////////////////////////////////////////////////////////////////////////////////////
			// start 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
			//
			// 기존 
			//

// 			Petcurrentmsg->CreatedPetUID		= (*Peerpetiter)->CreatedPetUID;
// 			Petcurrentmsg->EnableEditPetName	= (*Peerpetiter)->EnableEditPetName;
// 			Petcurrentmsg->EnableLevelUp		= (*Peerpetiter)->EnableLevelUp;
// 			Petcurrentmsg->PetExp				= (*Peerpetiter)->PetExp;
// 			Petcurrentmsg->PetIndex				= (*Peerpetiter)->PetIndex;
// 			Petcurrentmsg->PetLevel				= (*Peerpetiter)->PetLevel;
// 			Petcurrentmsg->SourceIndex_City		= (*Peerpetiter)->SourceIndex_City;
// 			Petcurrentmsg->SourceIndex_Field	= (*Peerpetiter)->SourceIndex_Field;
// 			Petcurrentmsg->Stamina				= (*Peerpetiter)->Stamina;
// 
// 			for ( int i = 0 ; i < SIZE_MAX_PETSKILLITEM ; ++i )
// 			{
// 				if ( (*Peerpetiter)->pItem_PetSkill[i] )
// 					Petcurrentmsg->ItemIndex_PetSkill[i] = (*Peerpetiter)->pItem_PetSkill[i]->ItemNum;
// 			}
// 			
// 			memcpy(Petcurrentmsg->szPetName,(*Peerpetiter)->szPetName,SIZE_MAX_PET_NAME);

			/////////
			// 수정

			Petcurrentmsg->CreatedPetUID		= (*Peerpetiter)->CreatedPetUID;
			Petcurrentmsg->PetExp				= (*Peerpetiter)->PetExp;
			Petcurrentmsg->PetIndex				= (*Peerpetiter)->PetIndex;
			Petcurrentmsg->PetLevel				= (*Peerpetiter)->PetLevel;
			Petcurrentmsg->PetExpRatio			= (*Peerpetiter)->PetExpRatio;
			Petcurrentmsg->PetEnableSocketCount	= (*Peerpetiter)->PetEnableSocketCount;

			memcpy(Petcurrentmsg->PetName, (*Peerpetiter)->PetName, SIZE_MAX_PET_NAME);

			memcpy(&Petcurrentmsg->PetSocketItemUID, &((*Peerpetiter)->PetSocketItemUID), sizeof(Petcurrentmsg->PetSocketItemUID));
			memcpy(&Petcurrentmsg->PetKitHP, &((*Peerpetiter)->PetKitHP), sizeof(Petcurrentmsg->PetKitHP));
			memcpy(&Petcurrentmsg->PetKitShield, &((*Peerpetiter)->PetKitShield), sizeof(Petcurrentmsg->PetKitShield));
			memcpy(&Petcurrentmsg->PetKitSP, &((*Peerpetiter)->PetKitSP), sizeof(Petcurrentmsg->PetKitSP));
			memcpy(&Petcurrentmsg->PetAutoSkill, &((*Peerpetiter)->PetAutoSkill), sizeof(Petcurrentmsg->PetAutoSkill));

			// end 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
			///////////////////////////////////////////////////////////////////////////////////////

			this->SendAddData( sendPetbuff, MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA) ); // 펫 정보 전송
			break;
 		}
 	}
}

CFieldIOCPSocket* CFieldIOCPSocket::SendP2PPKEndAndReset(CFieldIOCPSocket *pPeerSocket, BOOL bSendToPeer)
{
	if (NULL == pPeerSocket && bSendToPeer)
	{
		pPeerSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
	}

	// Send MSG_FC_BATTLE_END_P2P_PK
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_END_P2P_PK, T_FC_BATTLE_END_P2P_PK, pMsgEnd, pMsgEndBuf);
	pMsgEnd->EndType = BATTLE_END_END;

	// To Me
	pMsgEnd->PeerClientIndex = m_peerP2PPKClientIndex;
	SendAddData(pMsgEndBuf, MSG_SIZE(MSG_FC_BATTLE_END_P2P_PK));

	// To Peer
	if (pPeerSocket != NULL && bSendToPeer)
	{
		pMsgEnd->PeerClientIndex = m_character.ClientIndex;
		pPeerSocket->SendAddData(pMsgEndBuf, MSG_SIZE(MSG_FC_BATTLE_END_P2P_PK));
	}

	// reset P2P PK
	m_peerP2PPKClientIndex = INVALID_CLIENT_INDEX;
	m_bP2PPKStarted = FALSE;
	if (pPeerSocket != NULL)
	{
		pPeerSocket->m_peerP2PPKClientIndex = INVALID_CLIENT_INDEX;
		pPeerSocket->m_bP2PPKStarted = FALSE;
	}

	return pPeerSocket;
}

void CFieldIOCPSocket::OnP2PPKEnd(CFieldIOCPSocket *pWinnerSocket, CFieldIOCPSocket *pLoserSocket)
{
	if (pWinnerSocket != NULL && IS_VALID_CLIENT_INDEX(pWinnerSocket->m_character.ClientIndex)
		&& pLoserSocket != NULL && IS_VALID_CLIENT_INDEX(pLoserSocket->m_character.ClientIndex))
	{
		// 일대일 PK 가 시작되었으면 승패처리
		if (pLoserSocket->m_bP2PPKStarted && pWinnerSocket->m_bP2PPKStarted)
		{
			// 2005-11-03 by cmkwon, 도시맵일 경우 승리한 유저는 캐릭터모드로 변경시 시킨다.
			if(pWinnerSocket->IsCityCurrentFieldMapChannel())
			{
				pWinnerSocket->WarpToCityMap();
			}
			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_END_P2P_PK, T_FC_BATTLE_END_P2P_PK, pMsgEndPK, pMsgEndPKBuf);
			// To Loser
			pMsgEndPK->EndType = BATTLE_END_DEFEAT;
			pMsgEndPK->PeerClientIndex = pWinnerSocket->m_character.ClientIndex;
			pLoserSocket->SendAddData(pMsgEndPKBuf, MSG_SIZE(MSG_FC_BATTLE_END_P2P_PK));
			// send log
			CAtumLogSender::SendLogMessagePKLOSS(pLoserSocket, pWinnerSocket->m_character.CharacterUniqueNumber);
			// To Winner
			pMsgEndPK->EndType = BATTLE_END_WIN;
			pMsgEndPK->PeerClientIndex = pLoserSocket->m_character.ClientIndex;
			pWinnerSocket->SendAddData(pMsgEndPKBuf, MSG_SIZE(MSG_FC_BATTLE_END_P2P_PK));
			// send log
			CAtumLogSender::SendLogMessagePKWIN(pWinnerSocket, pLoserSocket->m_character.CharacterUniqueNumber);

			// PK 수치 조정
			// Winner
			pWinnerSocket->m_character.PKWinPoint += 1;
// 2005-12-27 by cmkwon, 1:1 PK로 명성치를 올리지 않는다 - 명성치는 타세력을 죽였을 때만 증가된다.
//			pWinnerSocket->m_character.Propensity += max(0, (10 + pLoserSocket->m_character.Level - pWinnerSocket->m_character.Level));
			pWinnerSocket->CheckAndUpdateStatus();
			pWinnerSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
			// DB에 저장
			QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointWinner = new QPARAM_CHARACTER_CHANGE_PKPOINT;
			pQChangePKPointWinner->CharacterUniqueNumber = pWinnerSocket->m_character.CharacterUniqueNumber;
			pQChangePKPointWinner->Propensity = pWinnerSocket->m_character.Propensity;
			pQChangePKPointWinner->PKWinPoint = pWinnerSocket->m_character.PKWinPoint;
			pQChangePKPointWinner->PKLossPoint = pWinnerSocket->m_character.PKLossPoint;
			pWinnerSocket->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, pWinnerSocket, pWinnerSocket->m_character.AccountUniqueNumber, pQChangePKPointWinner);
			// Loser
			pLoserSocket->m_character.PKLossPoint += 1;
// 2005-11-08 by cmkwon and 기획, 패배자의 명성치 다운은 없다
//			pLoserSocket->m_character.Propensity -= (5 + max(pLoserSocket->m_character.Level - pWinnerSocket->m_character.Level, 0));
			pLoserSocket->CheckAndUpdateStatus();
			pLoserSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
			// DB에 저장
			QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointLoser = new QPARAM_CHARACTER_CHANGE_PKPOINT;
			pQChangePKPointLoser->CharacterUniqueNumber = pLoserSocket->m_character.CharacterUniqueNumber;
			pQChangePKPointLoser->Propensity = pLoserSocket->m_character.Propensity;
			pQChangePKPointLoser->PKWinPoint = pLoserSocket->m_character.PKWinPoint;
			pQChangePKPointLoser->PKLossPoint = pLoserSocket->m_character.PKLossPoint;
			pLoserSocket->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, pLoserSocket, pLoserSocket->m_character.AccountUniqueNumber, pQChangePKPointLoser);
		}
		
		// PK Reset
		pLoserSocket->m_peerP2PPKClientIndex	= INVALID_CLIENT_INDEX;
		pLoserSocket->m_bP2PPKStarted			= FALSE;
		pWinnerSocket->m_peerP2PPKClientIndex	= INVALID_CLIENT_INDEX;
		pWinnerSocket->m_bP2PPKStarted			= FALSE;
	}
}

ProcessResult CFieldIOCPSocket::Process_FC_CLIENT_REPORT(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;
	MSG_FC_CLIENT_REPORT		*pMsgClientReport;

	nRecvTypeSize = sizeof(MSG_FC_CLIENT_REPORT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_CLIENT_REPORT, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14053);
		return RES_RETURN_FALSE;
	}
	pMsgClientReport = (MSG_FC_CLIENT_REPORT*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// start 2011-10-28 by hskim, 사설 서버 방지
	MSG_FC_CLIENT_REPORT Temp;

	STRNCPY_MEMSET(Temp.ClientPrivateIP, pMsgClientReport->ClientPrivateIP, SIZE_MAX_IPADDRESS);
	STRNCPY_MEMSET(Temp.CharacterName, pMsgClientReport->CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(Temp.Message, pMsgClientReport->Message, SIZE_MAX_CLIENT_REPORT);
	// end 2011-10-28 by hskim, 사설 서버 방지

	char szSystemLog[sizeof(MSG_FC_CLIENT_REPORT)+100];
	sprintf(szSystemLog, "CLIENT REPORT from %s(%s): %s\r\n",
		Temp.CharacterName, Temp.ClientPrivateIP, Temp.Message);
	g_pFieldGlobal->WriteSystemLog(szSystemLog);		// 2011-10-28 by hskim, 사설 서버 방지
	DBGOUT(szSystemLog);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ADMIN_GET_SERVER_STAT(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(FALSE == IsValidCharacter(FALSE))
	{// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
		return RES_BREAK;
	}

	if (NULL == m_pCurrentFieldMapChannel
		|| FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))		// 2005-12-22 by cmkwon, 게임 마스터 추가
	{
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_ADMIN_GET_SERVER_STAT_OK, T_FC_ADMIN_GET_SERVER_STAT_OK, pStatOK, pStatOKBuf);
	pStatOK->CurrentMapChannelIndex = m_character.MapChannelIndex;
	pStatOK->CurrentUserCount = m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.size();

	SendAddData(pStatOKBuf, MSG_SIZE(MSG_FC_ADMIN_GET_SERVER_STAT_OK));

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FM_PRINTMAP(const char* pPacket, int nLength, int &nBytesUsed)
{
	int					nRecvTypeSize = 0;
	MSG_FM_PRINTMAP		*pRePrintMap = NULL;

	nRecvTypeSize = sizeof(MSG_FM_PRINTMAP);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FM_PRINTMAP, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14056);
		return RES_RETURN_FALSE;
	}
	pRePrintMap = (MSG_FM_PRINTMAP*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldMapProject *pFMPro = (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(pRePrintMap->MapChannelIndex.MapIndex);
	if(NULL == pFMPro){				return RES_BREAK;}

	CFieldMapChannel * pFMChann = pFMPro->GetFieldMapChannelByIndex(pRePrintMap->MapChannelIndex.ChannelIndex);
	if(NULL == pFMChann){			return RES_BREAK;}

#ifdef _DEBUG
	pFMChann->printUnitCountsPerBlock();
#endif
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_SAVE_MAPBLOCK_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FM_SAVE_MAPBLOCK_INFO	*pRecvMapBlockInfo = NULL;

	nRecvTypeSize = sizeof(MSG_FM_SAVE_MAPBLOCK_INFO);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FM_SAVE_MAPBLOCK_INFO, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14056);
		return RES_RETURN_FALSE;
	}
	pRecvMapBlockInfo = (MSG_FM_SAVE_MAPBLOCK_INFO*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldMapProject *pFMPro = (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(pRecvMapBlockInfo->MapChannelIndex.MapIndex);
	if(NULL == pFMPro){				return RES_BREAK;}

	CFieldMapChannel * pFMChann = pFMPro->GetFieldMapChannelByIndex(pRecvMapBlockInfo->MapChannelIndex.ChannelIndex);
	if(NULL == pFMChann){			return RES_BREAK;}

	pFMChann->SaveUnitCountsPerBlock();
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_GET_MAP_USER_COUNTS(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FM_GET_MAP_USER_COUNTS	*pRecvMapUserCounts = NULL;

	nRecvTypeSize = sizeof(MSG_FM_GET_MAP_USER_COUNTS);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FM_GET_MAP_USER_COUNTS, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14056);
		return RES_RETURN_FALSE;
	}
	pRecvMapUserCounts = (MSG_FM_GET_MAP_USER_COUNTS*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	CFieldMapProject *pFMapPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pRecvMapUserCounts->MapChannIndex.MapIndex);
	if(NULL == pFMapPro){				return RES_BREAK;}

	CFieldMapChannel *pFMapChann = pFMapPro->GetFieldMapChannelByIndex(pRecvMapUserCounts->MapChannIndex.ChannelIndex);
	if(NULL == pFMapChann){				return RES_BREAK;}

	INIT_MSG_WITH_BUFFER(MSG_FM_GET_MAP_USER_COUNTS_ACK, T_FM_GET_MAP_USER_COUNTS_ACK, pSendUserCountsAck, SendB);
	pSendUserCountsAck->MapChannIndex = pRecvMapUserCounts->MapChannIndex;
	pSendUserCountsAck->AccumulatedUserCounts		= pFMapChann->m_uiAccumulatedUserCountsInChannel;
	pSendUserCountsAck->CurrentUserCounts			= pFMapChann->GetNumClients();
	pFMapChann->UpdateMaxUserCounts(pSendUserCountsAck->CurrentUserCounts);
	pSendUserCountsAck->MaxUserCounts				= pFMapChann->m_uiMaxUserCountsInChannel;
	pSendUserCountsAck->AccumulatedMonsterCounts	= pFMapChann->m_uiAccumulatedMonsterCountsInChannel;
	pSendUserCountsAck->CurrentMonsterCounts		= pFMapChann->GetNumMonsters();
// 2013-11-04 by jekim, 툴에 맵별로 각 세력별 접속 유저 수 추가.
	pSendUserCountsAck->NumOfANI                    = pFMapChann->GetUserCounts(INFLUENCE_TYPE_ANI,0,0);
	pSendUserCountsAck->NumOfBCU                    = pFMapChann->GetUserCounts(INFLUENCE_TYPE_VCN,0,0);
// end 2013-11-04 by jekim, 툴에 맵별로 각 세력별 접속 유저 수 추가.
	SendAddData(SendB, MSG_SIZE(MSG_FM_GET_MAP_USER_COUNTS_ACK));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_SET_SERVICE_STATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FM_SET_SERVICE_STATE,
									MSG_FM_SET_SERVICE_STATE, pMsgSetServiceState);

	switch(pMsgSetServiceState->ServiceType)
	{
	case SERVER_SERVICE_TYPE_QUEST:
		ms_pFieldIOCP->m_ServicePauseManager.SetQuestServiceState(pMsgSetServiceState->ServiceState);
		break;
	default:
		// no such server service type
		break;
	}

	SendAddMessageType(T_FM_SET_SERVICE_STATE_OK);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_RELOAD_SERVER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FM_RELOAD_SERVER_INFO,
									MSG_FM_RELOAD_SERVER_INFO, pMsgReloadInfo);

	switch(pMsgReloadInfo->InfoType)
	{
	case SERVER_INFO_TYPE_QUEST:
		{
			if (!ms_pFieldIOCP->LoadQuestInfo(TRUE))
			{
				DBGOUT(STRERR_S_F2NOTIFY_0015);
			}
		}
		break;
	default:
		// no such server info type
		break;
	}

	SendAddMessageType(T_FM_RELOAD_SERVER_INFO_OK);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_INCREASE_CHANNEL(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FM_INCREASE_CHANNEL,
									MSG_FM_INCREASE_CHANNEL, pMsgIncreaseChannel);

	// 2004-10-07 by cmkwon, 채널 실시간 증가는 없다
	return RES_BREAK;
	
//	CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pMsgIncreaseChannel->MapIndex);
//	if (pMapProject == NULL)
//	{
//		SendErrorMessage(T_FM_INCREASE_CHANNEL, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, pMsgIncreaseChannel->MapIndex);
//		return RES_BREAK;
//	}
//
//	BOOL bRet = pMapProject->IncreaseMapChannels(1);
//
//	if (!bRet)
//	{
//		// error
//		return RES_BREAK;
//	}
//
//	BYTE SendBuf[SIZE_MAX_PACKET];
//
//	INIT_MSG(MSG_FM_SEND_CHANNEL_INFO, T_FM_SEND_CHANNEL_INFO, pSendProjectInfo, SendBuf);
//	pSendProjectInfo->ChannelIndex = pMapProject->GetLastFieldMapChannel(FALSE)->m_MapChannelIndex.ChannelIndex;
//	pSendProjectInfo->projectInfo = *((PROJECTINFO*)pMapProject);
//	SendAddData(SendBuf, MSG_SIZE(MSG_FM_SEND_CHANNEL_INFO));
//
//	// NPC 서버에 전송
//	INIT_MSG(MSG_FN_CONNECT_INCREASE_CHANNEL, T_FN_CONNECT_INCREASE_CHANNEL, pFNIncreaseChannel, SendBuf);
//	pFNIncreaseChannel->MapIndex = pMapProject->m_nMapIndex;
//	pFNIncreaseChannel->TotalChannelCount = pMapProject->GetNumberOfMapChannels(FALSE);
//	pMapProject->Send2NPCServer(SendBuf, MSG_SIZE(MSG_FN_CONNECT_INCREASE_CHANNEL));
//
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FM_SET_CHANNEL_STATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FM_SET_CHANNEL_STATE,
									MSG_FM_SET_CHANNEL_STATE, pMsgSetChannelState);

	CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pMsgSetChannelState->MapChannelIndex.MapIndex);
	if (pMapProject == NULL)
	{
		SendErrorMessage(T_FM_SET_CHANNEL_STATE, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, pMsgSetChannelState->MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	CFieldMapChannel *pMapChannel = pMapProject->GetFieldMapChannelByIndex(pMsgSetChannelState->MapChannelIndex.ChannelIndex);
	if (pMapChannel == NULL)
	{
		SendErrorMessage(T_FM_SET_CHANNEL_STATE, ERR_PROTOCOL_NO_SUCH_CHANNEL, pMsgSetChannelState->MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}

	pMapChannel->SetChannelState(pMsgSetChannelState->EnableChannel);

	INIT_MSG_WITH_BUFFER(MSG_FM_SET_CHANNEL_STATE_OK, T_FM_SET_CHANNEL_STATE_OK, pMsgSetStateOK, SendBuf);
	pMsgSetStateOK->MapChannelIndex = pMsgSetChannelState->MapChannelIndex;
	pMsgSetStateOK->IsEnabled = pMapChannel->IsEnabled();
	SendAddData(SendBuf, MSG_SIZE(MSG_FM_SET_CHANNEL_STATE_OK));

	// NPC 서버에 전송
	INIT_MSG(MSG_FN_CONNECT_SET_CHANNEL_STATE, T_FN_CONNECT_SET_CHANNEL_STATE, pFNSetState, SendBuf);
	pFNSetState->MapChannelIndex = pMsgSetChannelState->MapChannelIndex;
	pFNSetState->EnableChannel = pMapChannel->IsEnabled();
	pMapProject->Send2NPCServer(SendBuf, MSG_SIZE(MSG_FN_CONNECT_SET_CHANNEL_STATE));

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FM_CITYWAR_CHANGE_WAR_TIME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FM_CITYWAR_CHANGE_WAR_TIME,
									MSG_FM_CITYWAR_CHANGE_WAR_TIME, pRWarTime);

	CCityWar *pCityWar = ms_pFieldIOCP->m_cityWarManager.GetCityWarPtrByCityWarMapIndex(pRWarTime->MapChannelIndex.MapIndex);
	if(NULL == pCityWar)
	{
		return RES_BREAK;
	}

	if(FALSE == pCityWar->ChangeWarTimeCityWar(&pRWarTime->CityWarATimeDefault, &pRWarTime->CityWarATimeSetting))
	{
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 모니터로 변경 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FM_CITYWAR_CHANGED_OCCUPY_INFO, T_FM_CITYWAR_CHANGED_OCCUPY_INFO, pSMsg, SendBuf);
	pSMsg->MapChannelIndex.MapIndex		= pCityWar->MapIndex;	
	pSMsg->MapChannelIndex.ChannelIndex	= 0;
	pSMsg->cityWarOccupyInfo			= *pCityWar->GetCITY_OCCUPY_INFO();
	ms_pFieldIOCP->SendMessageToMonitor(SendBuf, MSG_SIZE(MSG_FM_CITYWAR_CHANGED_OCCUPY_INFO));
	return RES_RETURN_TRUE;
}
BOOL CFieldIOCPSocket::CheckCommandExecutability(USHORT i_nAllowedRace, BOOL i_bAllowAdminTool /* = FALSE */)
{
	BOOL bRet = COMPARE_RACE(m_character.Race, i_nAllowedRace)
				|| (i_bAllowAdminTool && m_PeerSocketType == ST_ADMIN_TOOL);

	return bRet;


}

BOOL CFieldIOCPSocket::HandleAdminCommands(const char *cmd)
{
	char *token;
	char seps[] = " ";
	char buffer[SIZE_MAX_CHAT_MESSAGE];

	STRNCPY_MEMSET(buffer, cmd, SIZE_MAX_CHAT_MESSAGE);
	token = strtok(buffer, seps);

	// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 추가 명령문 삭제
	if( CheckAdminCommand(token) )
		return FALSE;

	if (0 == stricmp(token, STRCMD_CS_COMMAND_MENT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MENT_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MENT_2))
	{
		if(FALSE == GCheckLimitLevel(CHECK_TYPE_CHARACTER_MENT, m_character.Level))
		{
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED, CHECK_TYPE_CHARACTER_MENT, 0);
			return FALSE;
		}

		// format: "/멘트 [String]" - 캐릭터의 멘트로 설정함

		token = strtok(NULL, "");		// 공백도 포함해야 하므로 seps를 사용하지 않는다
		if(NULL == token)
		{
			MEMSET_ZERO(this->m_szCharacterMent, SIZE_STRING_32);
		}
		else
		{
			memcpy(this->m_szCharacterMent, token, SIZE_STRING_32-1);
		}
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_CHARACTER_MENT, T_FC_CHARACTER_CHANGE_CHARACTER_MENT
			, pS2CMent, SendBuf);		
		pS2CMent->ClientIdx = m_character.ClientIndex;
		memcpy(pS2CMent->szCharacterMent1, this->m_szCharacterMent, SIZE_STRING_32);
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf
			, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_CHARACTER_MENT), m_pCurrentFieldMapChannel);

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_MOVE)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MOVE_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_DEMO|RACE_MONITOR) )
		{// 2008-09-09 by cmkwon, 모니터 권한 계정에 사용 권한 추가 - STRCMD_CS_COMMAND_MOVE, // 2006-04-13 by cmkwon, 관리자/운영자/DEMO만 사용 가능
			return FALSE;
		}

		// format: "/이동 [MapIndex] [ChannelIndex]" - 해당 맵으로 이동
		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MOVE_HELP);
			return FALSE;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-05-22 by dhjin, 아레나 맵에서 사용시 아레나 대전 중이면 팀에서 탈퇴 처리 한다.
		if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())
			&& m_ArenaInfo.IsValidArenaState() )
		{
			if(m_ArenaInfo.WatchState)
			{// 2007-06-21 by dhjin, 관전자이면 관전 정보를 초기화한다.
				this->WatchEnd();
			}
			else
			{
				this->ms_pFieldIOCP->m_ArenaManager.DeleteMember(this);		// 2007-04-23 by dhjin, 팀원 삭제
				this->m_ArenaInfo.ResetArenaInfo();		
				this->SendAddMessageType(T_FC_ARENA_REAVE_TEAM_OK);			// 2007-05-03 by dhjin, 아레나에서 떠난 상태 정보 전송

				// 2008-01-15 by dhjin, 아레나 통합 - 필드 서버로 강제 종료 전송하여 처리
				this->SendArenaCharacterDisConnect();
//				// 2007-06-07 by dhjin, 강제 종료 1증가
//				this->m_character.ArenaDisConnect += 1;
//				QPARAM_UPDATE_ARENA_DISCONNECT *pQparam = new QPARAM_UPDATE_ARENA_DISCONNECT;
//				pQparam->CharacterUID			= this->m_character.CharacterUniqueNumber;
//				pQparam->AccountUID				= this->m_character.AccountUniqueNumber;
//				pQparam->ArenaDisConnect		= this->m_character.ArenaDisConnect;
//				this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateArenaDisConnect, this, 0, pQparam);
			}
		}
// 2007-10-23 by cmkwon, 아래와 같이 수정함
//		MAP_CHANNEL_INDEX tmpMapChannelIndex;
//
//		CFieldMapProject *pMapProject
//			= (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(atoi(token));
//		if (pMapProject != NULL)
//		{
//			tmpMapChannelIndex.MapIndex = atoi(token);
//
//			// 채널 결정
//			token = strtok(NULL, seps);
//			if (token != NULL) { tmpMapChannelIndex.ChannelIndex = atoi(token); }
//			else
//			{
//				CFieldMapChannel *pFieldMapChannel = pMapProject->GetFirstFieldMapChannel(TRUE);
//				if (pFieldMapChannel == NULL)
//				{
//					return FALSE;
//				}
//				else
//				{
//					tmpMapChannelIndex.ChannelIndex = pFieldMapChannel->GetMapChannelIndex().ChannelIndex;
//				}
//			}
//
//			EventResult_t ret = WarpToMap(tmpMapChannelIndex);
//
//			// event result에 대한 작업
//			if (ret == EVENT_RESULT_BREAK)
//			{
//#ifdef _DEBUG
//				DBGOUT(STRERR_S_F2NOTIFY_0016,
//					token, GetCharacterString(&m_character, string()));
//#endif
//				return TRUE;
//			}
//			else if (ret == EVENT_RESULT_CONTINUE)
//			{
//				return TRUE;
//			}
//		}
		CFieldMapProject *pMapProject = (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(atoi(token));
		if (NULL == pMapProject)
		{
			SendString128(STRING_128_ADMIN_CMD, "Invalid MapIndex(%d) !!", atoi(token));
			return FALSE;
		}

		MAP_CHANNEL_INDEX tmpMapChannelIndex(atoi(token),0);	// 2007-10-23 by cmkwon, 기본 0번 채널		
		token = strtok(NULL, seps);
		if (token != NULL) 
		{
			tmpMapChannelIndex.ChannelIndex = max(0, atoi(token));	// 채널 결정
		}		
		CFieldMapChannel *pFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(tmpMapChannelIndex);
		if(NULL == pFMChann
			|| FALSE == pFMChann->IsEnabled())
		{// 2007-10-23 by cmkwon, 이동 요청한 맵채널을 체크한다
			SendString128(STRING_128_ADMIN_CMD, "Invalid ChannelIndex or is not enalbe channel !!, MapChannel(%d:%d)", tmpMapChannelIndex.MapIndex, tmpMapChannelIndex.ChannelIndex);
			return FALSE;
		}

// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 - 체크 필요 없음
//		if(m_character.MapChannelIndex.MapIndex == tmpMapChannelIndex.MapIndex
//			&& m_character.MapChannelIndex.ChannelIndex != tmpMapChannelIndex.ChannelIndex)
//		{
//			SendString128(STRING_128_ADMIN_CMD, "can't warp !!, MapChannel(%d:%d)", tmpMapChannelIndex.MapIndex, tmpMapChannelIndex.ChannelIndex);
//			return FALSE;
//		}

		EventResult_t ret = WarpToMap(tmpMapChannelIndex);		
		if (ret != EVENT_RESULT_CONTINUE)
		{// event result에 대한 작업
			g_pFieldGlobal->WriteSystemLogEX(TRUE, STRERR_S_F2NOTIFY_0016, token, GetCharacterString(&m_character, string()));
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_COORDINATE) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_COORDINATE_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		D3DXVECTOR3 newPos;

		// format: "/좌표 [X] [Y]" - 현재 맵의 해당 좌표로 이동
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_COORDINATE_HELP);
			return TRUE;
		}
		newPos.x = atof(token)*SIZE_MAP_TILE_SIZE;
		token = strtok(NULL, seps);
		if (token == NULL){							return FALSE;}
		newPos.z = atof(token)*SIZE_MAP_TILE_SIZE;
		// 2013-06-26 by jhseol, 좌표명령어 높이값 지원
		token = strtok(NULL, seps);
		float PosY = 100.0f;
		if (token != NULL)
		{
			PosY = atof(token)*SIZE_MAP_TILE_SIZE;
		}
		// end 2013-06-26 by jhseol, 좌표명령어 높이값 지원
		if (!IS_IN_RANGE(5*SIZE_MAP_TILE_SIZE, newPos.x, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_fSizeMap_X-5*SIZE_MAP_TILE_SIZE)
			|| !IS_IN_RANGE(5*SIZE_MAP_TILE_SIZE, newPos.z, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_fSizeMap_Z-5*SIZE_MAP_TILE_SIZE))
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0084,
				(int)m_pCurrentFieldMapChannel->m_pFieldMapProject->m_fSizeMap_X/SIZE_MAP_TILE_SIZE - 5,
				(int)m_pCurrentFieldMapChannel->m_pFieldMapProject->m_fSizeMap_Z/SIZE_MAP_TILE_SIZE - 5);
			return FALSE;
		}

		newPos.y = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetMapHeightIncludeWater(&newPos) + PosY;		// 2013-06-26 by jhseol, 좌표명령어 높이값 지원
		WarpToMap(m_pCurrentFieldMapChannel->m_MapChannelIndex, &newPos);
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_LIST) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_LIST_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// format: "/리스트" - 현재 맵의 사용자 리스트 출력(최대 20명)

		int nCount = 0;
		string strUserList = STRMSG_S_F2NOTIFY_0085;
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.lock();

		// 맵의 전체 사용자 수 전송, check: 요구하면 살리자, kelovon
//		SendString128(STRING_128_ADMIN_CMD, "맵 \'%s\'의 전체 접속자: %d명", m_character.MapName, m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.size());

		// 각 사용자 정보 정송
		mtmapUID2FieldIOCPSocket::iterator itrChar = m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.begin();
		while (itrChar != m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.end())
		{
			// 카운트 증가
			nCount++;

			CFieldIOCPSocket *pSocket = itrChar->second;
/*
			SendString128(STRING_128_ADMIN_CMD, "%d: %s(계정: %s, 맵: %s, 레벨: %d)",
								nCount,
								pSocket->m_character.CharacterName,
								pSocket->m_character.AccountName,
								pSocket->m_character.MapName,
								pSocket->m_character.Level);
*/
			strUserList += pSocket->m_character.CharacterName;

			if (nCount%5 == 0)
			{
				SendString128(STRING_128_ADMIN_CMD, (char*)strUserList.c_str());
				strUserList = STRMSG_S_F2NOTIFY_0085;
			}
			else
			{
				strUserList += " ";
			}

			if (nCount == 25)
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0086);
				break;
			}

			itrChar++;
		}
		// 남은 떨거지들 전송
		SendString128(STRING_128_ADMIN_CMD, (char*)strUserList.c_str());

		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.unlock();

		return TRUE;
	}
	else if (stricmp(token, STRCMD_CS_COMMAND_USERSEND) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERSEND_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// 2008-02-21 by dhjin, 아레나 통합 - 아레나 서버에서 사용 불가
		if(g_pFieldGlobal->IsArenaServer())
		{
			return FALSE;
		}

		// format: "/보내기 [character name] [map name]" - 해당 캐릭터를 명시된 맵으로 이동시킴
		token = strtok(NULL, seps);		// character name
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_USERSEND_HELP);
			return TRUE;
		}
		char *CharacName = token;

		char tmCharacterName[SIZE_MAX_CHARACTER_NAME];		
		CFieldIOCPSocket *pCharacSocket = ms_pFieldIOCP->m_mapCharacterName.findLock(GGetLowerCase(tmCharacterName, CharacName, SIZE_MAX_CHARACTER_NAME));

		if (pCharacSocket != NULL)
		{
			// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 인피 상태 값을 메인서버로 전송한다. 인피 상태 체크
			if(INFINITY_STATE_NONE != pCharacSocket->m_InfinityPlayingInfo.InfinityState ) {
				return FALSE;
			}

			token = strtok(NULL, seps);		// map name
			if (token != NULL)
			{
				CMapProject *pMapProject = ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(atoi(token));
				if (pMapProject != NULL)
				{
					//////////////////////////////////////////////////////////////////////////
					// 2007-05-22 by dhjin, 아레나 맵에서 사용시 아레나 대전 중이면 팀에서 탈퇴 처리 한다.
					if(IS_MAP_INFLUENCE_ARENA(pCharacSocket->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())
						&& pCharacSocket->m_ArenaInfo.IsValidArenaState() )
					{
						if(pCharacSocket->m_ArenaInfo.WatchState)
						{// 2007-06-21 by dhjin, 관전자이면 관전 정보를 초기화한다.
							pCharacSocket->WatchEnd();
						}
						else
						{
							ms_pFieldIOCP->m_ArenaManager.DeleteMember(pCharacSocket);			// 2007-04-23 by dhjin, 팀원 삭제
							pCharacSocket->m_ArenaInfo.ResetArenaInfo();		
							pCharacSocket->SendAddMessageType(T_FC_ARENA_REAVE_TEAM_OK);			// 2007-05-03 by dhjin, 아레나에서 떠난 상태 정보 전송
						}
					}

					EventResult_t ret = pCharacSocket->WarpToMap(atoi(token), 0);

					// event result에 대한 작업
					if (ret == EVENT_RESULT_BREAK)
					{
#ifdef _DEBUG
						DBGOUT(STRERR_S_F2NOTIFY_0017,
							token, GetCharacterString(&pCharacSocket->m_character, string()));
#endif
						return FALSE;
					}
					else if (ret == EVENT_RESULT_CONTINUE)
					{
						return TRUE;
					}
				}
				return FALSE;
			}
			else
			{
				return FALSE;
			}
		}
		else
		{
			SendString128(STRING_128_ADMIN_CMD, "%s NOT PLAYING", CharacName);
			return FALSE;
		}
		return FALSE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_INFObyNAME) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFObyNAME_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/정보' 운영자도 사용 가능, // 2006-10-23 by cmkwon, 관리자만 허용하도록 수정
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// format: "/정보 [monster name|item name]" - 이름에 해당 스트링이 포함되는 몬스터나 아이템의 정보를 출력
		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_INFObyNAME_HELP);
			return TRUE;			
		}
		char *pName = token;

		// 몬스터 정보 검색
		ez_map<int, MONSTER_INFO>::iterator itrMon = ms_pFieldIOCP->m_mapMonsterInfo.begin();
		while(itrMon != ms_pFieldIOCP->m_mapMonsterInfo.end())
		{
			MONSTER_INFO *pMonsterInfo = &(itrMon->second);
			if (strstr(pMonsterInfo->MonsterName, pName) != NULL)
			{
				SendString128(STRING_128_ADMIN_CMD, "[Monster]%d:%s, Lv %d",
					pMonsterInfo->MonsterUnitKind, pMonsterInfo->MonsterName, (INT)pMonsterInfo->Level);
			}
			itrMon++;
		}

		// 아이템 정보 검색
		ez_map<int, ITEM*>::iterator itrItem = ms_pFieldIOCP->m_mapItemInfo.begin();
		while(itrItem != ms_pFieldIOCP->m_mapItemInfo.end())
		{
			ITEM *pItem = itrItem->second;
			if (strstr(pItem->ItemName, pName) != NULL)
			{
				SendString128(STRING_128_ADMIN_CMD, "[Item]%d:%s,Lv %d~%d, %s",
					pItem->ItemNum, pItem->ItemName, (INT)pItem->ReqMinLevel, (INT)pItem->ReqMaxLevel,
					CAtumSJ::GetItemKindName(pItem->Kind));
			}
			itrItem++;
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_QUESTINFO) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_QUESTINFO_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/퀘스트' 운영자 사용 불가
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}
		
		token = strtok(NULL, seps);		// 2009-10-15 by cmkwon, 퀘스트리스트 보내기시에 퀘스트명으로 검색 기능 추가 - 

		// format: "/퀘스트" - 캐릭터의 퀘스트 정보 출력
		ms_pFieldIOCP->SendAllQuestList(this, m_character.InfluenceType, token);		// 2006-08-08 by cmkwon, 모든 퀘스트 리스트를 전송한다.

		mt_auto_lock mqLock(&m_mapQuest);
		mtmapQuestIndex2FieldCharacterQuest::iterator itr_quest = m_mapQuest.begin();
		while(itr_quest != m_mapQuest.end())
		{
			CFieldCharacterQuest *tmFCharQuest = &itr_quest->second;
			CQuest *pQuestInfo = tmFCharQuest->GetQuestInfo();
			if(COMPARE_INFLUENCE(m_character.InfluenceType, pQuestInfo->ReqInfluenceType))
			{
				if(token
					&& NULL == strstr(pQuestInfo->QuestName, token))
				{// 2009-10-15 by cmkwon, 퀘스트리스트 보내기시에 퀘스트명으로 검색 기능 추가 - 
					itr_quest++;
					continue;
				}
				SendString128 (STRING_128_ADMIN_CMD, "IDX(%d) QNAME(%s) STATE(%d)",
					tmFCharQuest->QuestIndex, pQuestInfo->QuestName, tmFCharQuest->QuestState);
			}

			itr_quest++;
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_QUESTDEL) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_QUESTDEL_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/퀘스트지우기 [퀘스트번호]" - 캐릭터의 퀘스트 삭제
		int nQuestIndex = 0;
		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_QUESTDEL_HELP);
			return TRUE;
		}
			
		nQuestIndex = atoi(token);		

		mt_auto_lock mqLock(&m_mapQuest);
		mtmapQuestIndex2FieldCharacterQuest::iterator itr_quest = m_mapQuest.begin();
		while(itr_quest != m_mapQuest.end())
		{
			CFieldCharacterQuest *tmFCharQuest = &itr_quest->second;

			if (nQuestIndex != 0 && tmFCharQuest->QuestIndex != nQuestIndex)
			{
				itr_quest++;
				continue;
			}

			CQuest *pQuestInfo = tmFCharQuest->GetQuestInfo();
			if (pQuestInfo == NULL)
			{
				SendString128 (STRING_128_ADMIN_CMD, "IDX(%d) NAME(N/A) STATE(%d) - deleted",
					tmFCharQuest->QuestIndex, tmFCharQuest->QuestState);
			}
			else
			{
				SendString128 (STRING_128_ADMIN_CMD, "IDX(%d) QNAME(%s) STATE(%d) - deleted",
					tmFCharQuest->QuestIndex,
					pQuestInfo->QuestName, tmFCharQuest->QuestState);
			}

			INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_DISCARD_QUEST_OK, T_FC_QUEST_DISCARD_QUEST_OK, pMsgDiscard, pMsgDiscardBuf);
			pMsgDiscard->QuestIndex = tmFCharQuest->QuestIndex;
			pMsgDiscard->IsDiscarded = TRUE;
			SendAddData(pMsgDiscardBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));

			// 퀘스트 지우기 - DB
			QPARAM_DELETE_QUEST *pQDeleteQuest = new QPARAM_DELETE_QUEST;
			pQDeleteQuest->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			pQDeleteQuest->QuestIndex = tmFCharQuest->QuestIndex;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);

			m_mapQuest.erase(itr_quest++);
		}

//		SendString128(STRING_128_ADMIN_CMD, "캐릭터 재접속(선택창에서 재선택)하면 모든 퀘스트가 지워집니다.");

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINFObyKIND) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINFObyKIND_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// format: "/종류 [item kind(0~53)]" - 해당 종류의 아이템을 출력
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			// 아이템 종류 검색
			int nCnts = 0;
			ez_map<int, ITEM*>::iterator itrItem = ms_pFieldIOCP->m_mapItemInfo.begin();
			while(itrItem != ms_pFieldIOCP->m_mapItemInfo.end())
			{
				ITEM *pItem = itrItem->second;
				if (pItem->Kind == atoi(token))
				{
					SendString128(STRING_128_ADMIN_CMD, "[Item]%s(MinLv%d, MaxLv%d): %d, %s",
						pItem->ItemName, (INT)pItem->ReqMinLevel, (INT)pItem->ReqMaxLevel,
						pItem->ItemNum, CAtumSJ::GetItemKindName(pItem->Kind));
					nCnts++;
				}
				itrItem++;
			}

			// 2007-12-13 by cmkwon, 설명 추가
			if(0 >= nCnts)
			{
				SendString128(STRING_128_ADMIN_CMD, "Nothing item of ItemKind(%d) !!", atoi(token));
			}
		}
		else
		{
			for (int i = 0; i < ITEMKIND_FOR_MON_PRIMARY; i++)
			{
				if (stricmp(CAtumSJ::GetItemKindName(i), STRCMD_CS_ITEMKIND_UNKNOWN) != 0)
				{
					SendString128(STRING_128_ADMIN_CMD, "%3d -> %s", i, CAtumSJ::GetItemKindName(i));
				}
			}
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyKIND) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyKIND_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/종류아템 [item kind(0~53)]" - 해당 종류의 아이템을 추가
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ITEMINSERTbyKIND_HELP);
			return TRUE;
		}
		// 아이템 종류 검색
		ez_map<int, ITEM*>::iterator itrItem = ms_pFieldIOCP->m_mapItemInfo.begin();
		while(itrItem != ms_pFieldIOCP->m_mapItemInfo.end())
		{
			ITEM *pItem = itrItem->second;
			if (IS_GENERAL_ITEM(pItem->Kind)
				&& (m_character.UnitKind&pItem->ReqUnitKind) != 0
				&& pItem->Kind == atoi(token))
			{
				m_ItemManager.InsertItemBaseByItemNum(pItem->ItemNum, 1, IUT_ADMIN);
			}

			itrItem++;
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUMRANGE) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUMRANGE_1))
	{
		return FALSE;		// 2006-04-13 by cmkwon, 사용 불가 명령어

		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/범위아템 [from itemnum] ~ [to itemnum]" - 해당 범위의 아이템을 추가
		int nFromItemNum = 0;
		int nToItemNum = 0;

		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUMRANGE_HELP);
			return TRUE;
		}
		nFromItemNum = atoi(token);
		if (nFromItemNum == 0){					return FALSE;}
		
		token = strtok(NULL, seps);
		if (token == NULL){						return FALSE;}
		if (strncmp(token, "~", 1) != 0){		return FALSE;}
		
		token = strtok(NULL, seps);
		if (token == NULL){						return FALSE;}
		
		nToItemNum = atoi(token);
		if (nToItemNum == 0){					return FALSE;}

		// 아이템 삽입
		if (nFromItemNum != 0 && nToItemNum != 0)
		{
			// 아이템 종류 검색
			ez_map<int, ITEM*>::iterator itrItem = ms_pFieldIOCP->m_mapItemInfo.begin();
			while(itrItem != ms_pFieldIOCP->m_mapItemInfo.end())
			{
				ITEM *pItem = itrItem->second;
				if (IS_GENERAL_ITEM(pItem->Kind)
					&& (m_character.UnitKind&pItem->ReqUnitKind) != 0
					&& IS_IN_RANGE(nFromItemNum, pItem->ItemNum, nToItemNum))
				{
					m_ItemManager.InsertItemBaseByItemNum(pItem->ItemNum, 1, IUT_ADMIN);
				}

				itrItem++;
			}
		}

		return TRUE;
	}
	else if (stricmp(token, STRCMD_CS_COMMAND_STATINIT) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_STATINIT_1)
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_STATINIT_2))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		CFieldIOCPSocket *pSocket = NULL;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (pSocket == NULL
				|| FALSE == pSocket->IsUsing())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0087, token);
				return FALSE;
			}
		}
		else
		{
			pSocket = this;
		}

		if (pSocket == NULL)
		{
			return FALSE;
		}

		// format: "/스탯초기화" - 스탯을 초기화 함
		if (ERR_NO_ERROR != pSocket->ResetStat(STAT_ALL_PART))
		{
			// 2009-02-04 by cmkwon, 추가
			SendString128(STRING_128_ADMIN_CMD, "%s's Stat initialing failed !!", pSocket->GetCharacter()->CharacterName);
			return FALSE;
		}
		
		return TRUE;
	}
	else if (stricmp(token, STRCMD_CS_COMMAND_PARTYINFO) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_PARTYINFO_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/파티" - 파티 정보를 출력
		CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if (pMeFParty != NULL)
		{
			pMeFParty->Print(this);
			return TRUE;
		}
		else
		{
			SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0088);
			return TRUE;
		}
	}
	else if (stricmp(token, STRCMD_CS_COMMAND_GAMETIME) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_GAMETIME_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/시간' 운영자 사용 불가, // 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		// format: "/시간 [더할 시간량(0~23)]" - 현재 시간을 변경(자기 자신의 시간만 바뀜)
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			int timeToAdd = atoi(token);
			if (timeToAdd < 0 || timeToAdd > 24)
			{
				return FALSE;
			}

			// 시간을 전송
			time_t ltime;
			struct tm *today = NULL;
			time(&ltime);
			today = localtime(&ltime);
			INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_SYNC_TIME, T_FC_CONNECT_SYNC_TIME, pSyncTime, pSyncTimeBuf);
			// 4시간 기준으로 지난 초
			AtumTime aTime(0, 10*timeToAdd);
			AtumTime rTime(today->tm_hour, today->tm_min);

			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0089,
				rTime.Hour, rTime.Minute, (rTime*6).Hour%24, (rTime*6).Minute);

			rTime += aTime;

			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0090
				, rTime.Hour, rTime.Minute, (rTime*6).Hour%24, (rTime*6).Minute);

			pSyncTime->CurrentTime
				= (rTime.Hour%4)*3600 + rTime.Minute*60;

			SendAddData(pSyncTimeBuf, MSG_SIZE(MSG_FC_CONNECT_SYNC_TIME));
			SendString128(STRING_128_ADMIN_CMD, "synctime: %d", pSyncTime->CurrentTime);
		}
		else
		{
			// 시간을 전송
			time_t ltime;
			struct tm *today = NULL;
			time(&ltime);
			today = localtime(&ltime);
			// 4시간 기준으로 지난 초
			AtumTime rTime(today->tm_hour, today->tm_min);

			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0089
				, rTime.Hour, rTime.Minute, (rTime*6).Hour%24, (rTime*6).Minute);

			return FALSE;
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_STRINGLEVEL_0) == 0
		||  stricmp(token, STRCMD_CS_COMMAND_STRINGLEVEL_1) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_STRINGLEVEL_2))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/스트링 [0~5]" - 디버그 메세지를 출력하는 level을 결정
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_STRINGLEVEL_HELP);
			return TRUE;
		}
		int level = atoi(token);
		if (level >= STRING_128_DEBUG_L1 && level <= STRING_128_USER_NOTICE)
		{
			m_STRING_128_print_level = level;
		}
		else
		{
			return FALSE;
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_MONSUMMON) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MONSUMMON_1))
	{
		// 2009-02-04 by cmkwon, "/Summon" 명령어 GameMaster도 가능하게 수정 - 아래와 같이 수정
		//if ( !CheckCommandExecutability(RACE_OPERATION) )
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2008-08-18 by dhjin, 관리자만 사용가능 변경 // 2007-11-08 by cmkwon, GM 명령어 정리 - '/소환' 관리자도 사용 가능, // 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-04-19 by cmkwon, Gameforge4D GM은 소환 명령어 사용 불가(E0044590) - 
#if defined(_DEFINED_GAMEFORGE4D_)
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2010-04-19 by cmkwon, Gameforge4D GM은 소환 명령어 사용 불가(E0044590) - 
			return FALSE;
		}
#endif // END - #if defined(_DEFINED_GAMEFORGE4D_)

		//////////////////////////////////////////////////////////////////////////
		// 2007-06-22 by dhjin, 아레나 맵에서는 사용 불가
		if(IS_MAP_INFLUENCE_ARENA(this->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{
			return FALSE;
		}

		// format: "/소환 [monster number|monster name] [# of monsters]" - 몬스터를 소환(몬스터 이름에 공백이 있는 경우 대신 '_'를 사용하면 됨)
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MONSUMMON_HELP);
			return TRUE;			
		}
		INIT_MSG_WITH_BUFFER(MSG_FN_ADMIN_SUMMON_MONSTER, T_FN_ADMIN_SUMMON_MONSTER, pMsgSummonMonster, pMsgSummonMonsterBuf);
		pMsgSummonMonster->ChannelIndex		= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		STRNCPY_MEMSET(pMsgSummonMonster->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		pMsgSummonMonster->MonsterUnitKind	= atoi(token);
		pMsgSummonMonster->MonsterTargetType1	= MONSTER_TARGETTYPE_NORMAL;
		pMsgSummonMonster->TargetTypeData1		= 0;
		pMsgSummonMonster->CltIdxForTargetType1	= 0;
		if (0 == pMsgSummonMonster->MonsterUnitKind
			|| NULL == ms_pFieldIOCP->GetMonsterInfo(pMsgSummonMonster->MonsterUnitKind))
		{
			pMsgSummonMonster->MonsterUnitKind = 0;
			Underbar2Space(token);	// '_'를 space로 변경

			MONSTER_INFO *pMonInfo = ms_pFieldIOCP->GetMonsterInfo(token);
			if(NULL == pMonInfo)
			{
				return FALSE;
			}

			pMsgSummonMonster->MonsterUnitKind = pMonInfo->MonsterUnitKind;			
		}

		// 2010. 07. 05 by hsLee. 몬스터 소환 관련. (밸런스 데이터 누락 수정.)
		pMsgSummonMonster->MonsterBalanceData.Init(0);


		token = strtok(NULL, seps);
		if (pMsgSummonMonster->MonsterUnitKind != 0 && token != NULL)
		{
			pMsgSummonMonster->NumOfMonster = atoi(token);
			pMsgSummonMonster->Position = m_character.PositionVector;

			if (m_pCurrentFieldMapChannel->m_pFieldMapProject->GetNPCServerStartFlag() == FALSE)
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0091);
				return FALSE;
			}

			m_pCurrentFieldMapChannel->Send2NPCServerW(pMsgSummonMonsterBuf, MSG_SIZE(MSG_FN_ADMIN_SUMMON_MONSTER));
			return TRUE;
		}

		return FALSE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_SKILLALL) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_SKILLALL_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/모든스킬 [level]" - 해당되는 모든 스킬을 삽입
		int nSkillLevel = 1;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			nSkillLevel = atoi(token);
		}
		nSkillLevel = max(1, nSkillLevel);

		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);			// lock m_mapItemGeneral, "/모든스킬"

		ez_map<int, ITEM*>::iterator itrSkill = ms_pFieldIOCP->m_mapItemInfo.begin();
		while (itrSkill != ms_pFieldIOCP->m_mapItemInfo.end())
		{
			ITEM *pItemSkill = itrSkill->second;
			if (IS_SKILL_ITEM(pItemSkill->Kind)
				&& FALSE == COMPARE_BIT_FLAG(pItemSkill->ItemAttribute, SKILL_ATTR_PARTY_FORMATION_SKILL)		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 편대 대형 스킬 제외
				&& (m_character.UnitKind&pItemSkill->ReqUnitKind) != 0
				&& pItemSkill->SkillLevel == nSkillLevel
				&& FALSE == pItemSkill->IsExistDesParam(DES_SKILLTYPE_CONSECUTIVE_VICTORIES)	// 2014-02-11 by jhseol, 명령어로 세력버프스킬 배워지는 현상 수정
				&& FALSE == pItemSkill->IsExistDesParam(DES_SKILLTYPE_TRUN_AROUND)				// 2014-02-11 by jhseol, 명령어로 세력버프스킬 배워지는 현상 수정
#if defined(WIKIGAMES_ENG)	// 2014-03-24 by bckim, 해당 사항 버젼별 nextskill에 따르는 DB값 차이로 인하여 캐나다에만 반영
				&& 0 !=  pItemSkill->NextSkill													// 2014-03-14 by bckim, 명령어로 세력버프스킬 배워지는 현상 수정 보완 				
				&& FALSE == COMPARE_BIT_FLAG(ms_pFieldIOCP->GetItemInfo(pItemSkill->NextSkill)->ItemAttribute, SKILL_ATTR_PARTY_FORMATION_SKILL) // 2014-03-05 by bckim, 명령어로 세력버프스킬 배워지는 현상 수정				
#endif
				)
			{
				m_ItemManager.InsertItemBaseByItemNum(pItemSkill->ItemNum, 1, IUT_ADMIN);
			}

			itrSkill++;
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTALL) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTALL_1))
	{
		return FALSE;		// 2006-04-13 by cmkwon, 사용불가 명령어

		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/모든아템" - 해당되는 모든 아이템을 삽입, 스킬 및 Countable아이템 제외

		// lock , "/모든아템"
		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

		ez_map<int, ITEM*>::iterator itrItemInfo = ms_pFieldIOCP->m_mapItemInfo.begin();
		while (itrItemInfo != ms_pFieldIOCP->m_mapItemInfo.end())
		{
			ITEM *pItem = itrItemInfo->second;
			if (IS_GENERAL_ITEM(pItem->Kind)
				&& (m_character.UnitKind&pItem->ReqUnitKind) != 0
				&& !IS_COUNTABLE_ITEM(pItem->Kind)
			)
			{
				m_ItemManager.InsertItemBaseByItemNum(pItem->ItemNum, 1, IUT_ADMIN);
			}

			itrItemInfo++;
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTWEAPON) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTWEAPON_1))
	{
		return FALSE;		// 2006-04-13 by cmkwon, 사용 불가 명령어

		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/모든무기" - 해당되는 모든 무기류를 삽입

		// lock , "/모든무기"
		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

		ez_map<int, ITEM*>::iterator itrItemInfo = ms_pFieldIOCP->m_mapItemInfo.begin();
		while (itrItemInfo != ms_pFieldIOCP->m_mapItemInfo.end())
		{
			ITEM *pItem = itrItemInfo->second;
			if (IS_WEAPON(pItem->Kind)
				&& (m_character.UnitKind&pItem->ReqUnitKind) != 0
				&& !IS_COUNTABLE_ITEM(pItem->Kind)
			)
			{
				m_ItemManager.InsertItemBaseByItemNum(pItem->ItemNum, 1, IUT_ADMIN);
			}

			itrItemInfo++;
		}

		return TRUE;
	}
	else if (stricmp(token, STRCMD_CS_COMMAND_ITEMDELALL_0) == 0
			|| stricmp(token, STRCMD_CS_COMMAND_ITEMDELALL_1) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMDELALL_2))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/모든아템버리기" - 해당되는 모든 비장착 아템을 버림(스킬 제외)
		BOOL bDeleted = m_ItemManager.DeleteAllItemGeneralFromCharacter();

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUM) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUM_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/아템 [item number] [# of items]" - 아이템을 습득함, [# of items]가 없으면 1개로 취급됨
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ITEMINSERTbyITEMNUM_HELP);
			return TRUE;
		}
		ITEM *pItem = ms_pFieldIOCP->GetItemInfo(atoi(token));
		if (pItem == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0092, atoi(token));
			return FALSE;
		}

		// start 2011-09-30 by hskim, 파트너 시스템 2차
		if( ITEMKIND_PET_ITEM == pItem->Kind && g_pFieldGlobal->IsArenaServer() )
		{
			// 파트너 아레나에서 생성 금지
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0150);

			return FALSE;
		}
		// end 2011-09-30 by hskim, 파트너 시스템 2차

		int count = 1;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			count = atoi(token);
			if (!IS_COUNTABLE_ITEM(pItem->Kind) && count >= 10)
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0093);
				count = 10;
			}
		}
		else
		{
			count = 1;
		}

		// InsertItemBaseByItemNum 내부에서 lock 처리
		if (!m_ItemManager.InsertItemBaseByItemNum(pItem->ItemNum, count, IUT_ADMIN))
		{
			return FALSE;
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_ITEMDROP) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMDROP_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/드랍 [item number] [|# of items]" - 아이템을 드랍함, [# of items]가 없으면 1개로 취급됨
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ITEMDROP_HELP);
			return TRUE;
		}
		int nItemNum = atoi(token);
		int count = 1;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			count = atoi(token);
		}
		else
		{
			count = 1;
		}

		return ms_pFieldIOCP->m_DropItemManager.DropItemInRandomRadius(m_pCurrentFieldMapChannel, &m_character.PositionVector, DROP_ITEM_RADIUS, nItemNum, count, TRUE);		// 2013-04-10 by hskim, 어드민 명령에 의한 드랍 아이템은 대기 시간 2초 적용
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERSINFOTOTAL) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERSINFOTOTAL_1))
	{
		// format: "/서버" - 서버의 정보를 출력함
		if (!CheckCommandExecutability(RACE_OPERATION|RACE_MONITOR, TRUE))
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/서버' 운영자 불가, // 2006-04-13 by cmkwon, 관리자/운영자/SCMonitor/SCAdminTool만 사용 가능
			return FALSE;
		}

		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0094,
			GET_MAP_STRING(m_character.MapChannelIndex),
			m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.size());

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERSINFOperMAP) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERSINFOperMAP_1))
	{
		// format: "/서버맵" - 모든 맵의 정보를 출력함
		if (!CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		int			nClientCount;
		CFieldMapChannel *pFMapChann = NULL;
		CFieldMapWorkspace *pFieldMapWorkspace = ms_pFieldIOCP->GetMapWorkspace();

		for (int i = 0; i < pFieldMapWorkspace->m_vectorPtrMapProject.size(); i++)
		{
			int nChannCounts = pFieldMapWorkspace->m_vectorPtrMapProject[i]->GetNumberOfMapChannels();
			for(int k = 0; k < nChannCounts; k++)
			{
				pFMapChann = (CFieldMapChannel*)pFieldMapWorkspace->m_vectorPtrMapProject[i]->GetMapChannelByIndex(k);
				if (NULL == pFMapChann)
				{
					continue;
				}

				nClientCount = pFMapChann->GetNumClients();
				pFMapChann->UpdateMaxUserCounts(nClientCount);

				if (pFMapChann->m_MapChannelIndex == m_character.MapChannelIndex)
				{
					SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0095,
						GET_MAP_STRING(pFMapChann->m_MapChannelIndex),
						(pFMapChann->IsEnabled()?"O":"X"),
						nClientCount,
						CAtumSJ::GetMapName(pFMapChann->m_MapChannelIndex.MapIndex));
				}
				else
				{
					SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0096,
						GET_MAP_STRING(pFMapChann->m_MapChannelIndex),
						(pFMapChann->IsEnabled()?"O":"X"),
						nClientCount,
						CAtumSJ::GetMapName(pFMapChann->m_MapChannelIndex.MapIndex));
				}
			}
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_CHANNELINFO) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_CHANNELINFO_1))
	{
		// format: "/채널" - 현재 채널의 정보를 출력함
		if (!CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0097,
			CAtumSJ::GetMapName(m_character.MapChannelIndex.MapIndex),
			m_character.MapChannelIndex.MapIndex,
			m_character.MapChannelIndex.ChannelIndex);

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_DEBUGPRINTDBG) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_DEBUGPRINTDBG_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// 2008-02-14 by cmkwon, 해당 캐릭터 소켓의 PRINT_DEBUG_MESSAGE() 를 호출한다.
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			CFieldIOCPSocket *pFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (NULL == pFISoc
				|| FALSE == pFISoc->IsValidCharacter(FALSE))
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0102, token);
				return FALSE;
			}

// 2008-03-19 by cmkwon, 현재는 필요 없음
// 			char *dpm = NULL;
// 			pFISoc->PRINT_DEBUG_MESSAGE(dpm);
		
			// 2008-03-19 by cmkwon, 대규모 전쟁시 클라이언트 랙(lack) 현상 수정 - 임시용, 해당 유저의 WirteBuf를 파일로 저장한다. 향후 해결되면 필요 없음
			pFISoc->SaveDataOfWriteBufList();
		}

		return TRUE;
	}
	else if ( strcmp(token, STRCMD_CS_COMMAND_DEBUGSETPARAMF) == 0)
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/testf [Param1] [Param2] [Param3]" - 디버깅용 테스트
		int nParam1 = 0, nParam2 = 0, nParam3 = 0;
		const char *szParam1 = NULL, *szParam2 = NULL, *szParam3 = NULL;

		// Param 1
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_DEBUGSETPARAMF_HELP);
			return TRUE;
		}
		nParam1 = atoi(token);
		szParam1 = token;

		// Param 2
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_DEBUGSETPARAMF_HELP);
			return TRUE;
		}
		nParam2 = atoi(token);
		szParam2 = token;

		// Param 3
		token = strtok(NULL, seps);
		if (token == NULL)		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 기존 버그 수정
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_DEBUGSETPARAMF_HELP);
			return TRUE;
		}
		nParam3 = atoi(token);
		szParam3 = token;
		StartTestDBG(nParam1, nParam2, nParam3, szParam1, szParam2, szParam3);
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_BULLETCHARGE) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BULLETCHARGE_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		
		mt_auto_lock mtig(&m_ItemManager.m_mapItemGeneral);		// 2007-10-15 by cmkwon, 필요함

		ITEM_GENERAL *pPriItem = (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
		ITEM_GENERAL *pSecItem = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;

		// format: "/총알 [1형 총알 수] [2형 총알 수]"
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			if (m_ItemProwOut.ItemNum != 0)
			{
				RechargeBullet(pPriItem, FALSE, BULLET_RECHARGE_TYPE_ADMIN_COMMAND);	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
			}

			if (m_ItemWingOut.ItemNum != 0)
			{
				RechargeBullet(pSecItem, FALSE, BULLET_RECHARGE_TYPE_ADMIN_COMMAND);	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
			}
		}
		else
		{
			/////////////////////////////////////
			// 1형 무기 처리
			/////////////////////////////////////
			int nTargetCount = atoi(token);

			// 구경에 따른 탄알 정보 찾기
			multimap<BYTE, ITEM*>::iterator itrBullet = ms_pFieldIOCP->m_multiMapCaliber2Bullet.find((m_ItemProwOut.ItemNum==0?0:m_ItemProwOut.Caliber));
			if (itrBullet == ms_pFieldIOCP->m_multiMapCaliber2Bullet.end() || !IS_PRIMARY_WEAPON_1(m_ItemProwOut.Kind))
			{
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0098);
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0099, m_ItemProwOut.ItemName, m_ItemProwOut.Caliber);
			}
			else
			{
				if (nTargetCount < 0)
				{
					return FALSE;
				}

				nTargetCount = min(nTargetCount, pPriItem->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout())); // 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
				// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 위와 같이 수정함
				//if (nTargetCount >= m_ItemProwOut.Charging)
				//{
				//	nTargetCount = m_ItemProwOut.Charging;
				//}

				int nRechargeCount = nTargetCount - pPriItem->CurrentCount;
				m_ItemManager.UpdateItemCountByPointer(pPriItem, nRechargeCount, IUT_BULLET, ITEM_IN_CHARACTER, TRUE, FALSE);

				INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_PRI_BULLET_RELOADED, T_FC_BATTLE_PRI_BULLET_RELOADED, pPriBulletReloded, pPriBulletRelodedBuf);
				pPriBulletReloded->BulletCount = pPriItem->CurrentCount;
				SendAddData(pPriBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_PRI_BULLET_RELOADED));
// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//				m_PrimaryShotNumCount = CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor);
			}

			/////////////////////////////////////
			// 2형 무기 처리
			/////////////////////////////////////
			token = strtok(NULL, seps);
			if (token != NULL)
			{
				nTargetCount = atoi(token);

				multimap<BYTE, ITEM*>::iterator itrBullet = ms_pFieldIOCP->m_multiMapCaliber2Bullet.find((m_ItemWingOut.ItemNum==0?0:m_ItemWingOut.Caliber));
				if (itrBullet == ms_pFieldIOCP->m_multiMapCaliber2Bullet.end() || m_ItemWingOut.Kind == ITEMKIND_SHIELD)
				{
					SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0100);
					SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0101, m_ItemWingOut.ItemName, m_ItemWingOut.Caliber);
				}
				else
				{
					if (nTargetCount < 0)
					{
						return TRUE;
					}

					nTargetCount = min(nTargetCount, pSecItem->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout()));	// 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
					// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 위와 같이 수정함
					//if (nTargetCount >= m_ItemWingOut.Charging)
					//{
					//	nTargetCount = m_ItemWingOut.Charging;
					//}

					int nRechargeCount = nTargetCount - pSecItem->CurrentCount;
					m_ItemManager.UpdateItemCountByPointer(pSecItem, nRechargeCount, IUT_BULLET, ITEM_IN_CHARACTER, TRUE, FALSE);

					INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SEC_BULLET_RELOADED, T_FC_BATTLE_SEC_BULLET_RELOADED, pSecBulletReloded, pSecBulletRelodedBuf);
					pSecBulletReloded->BulletCount = pSecItem->CurrentCount;
					SendAddData(pSecBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_SEC_BULLET_RELOADED));
// check: 그냥 쏘게 하기 하면서 같이 삭제, 20041030, kelovon with ClientTeam
//					m_SecondaryShotNumCount = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);
				}
			}
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_REPAIRALL) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_REPAIRALL_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/만피 [character name]" - HP, UTC, FUEL을 100% 채움, [character name]이 없으면 자기 자신
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			CFieldIOCPSocket *pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (pSocket == NULL
				|| FALSE == pSocket->IsUsing())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0102, token);
				return FALSE;
			}
			if(FALSE == pSocket->IsValidCharacter())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0103, token);
				return FALSE;
			}

			pSocket->m_character.CurrentHP = pSocket->m_character.HP;
			pSocket->m_character.CurrentDP = pSocket->m_character.DP;
			pSocket->m_character.CurrentSP = pSocket->m_character.SP;
			pSocket->m_character.CurrentEP = pSocket->m_character.EP;
			pSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
		}
		else
		{
			if(FALSE == this->IsValidCharacter())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0103, m_character.CharacterName);
				return FALSE;
			}

			// 자기 자신
			this->m_character.CurrentHP = this->m_character.HP;
			this->m_character.CurrentDP = this->m_character.DP;
			this->m_character.CurrentSP = this->m_character.SP;
			this->m_character.CurrentEP = this->m_character.EP;
			this->SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_REPAIRbyPARAM) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_REPAIRbyPARAM_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/반피 [줄일 양%] [character name]" - HP, UTC, FUEL을 [줄일 얄%]으로 함, [줄일 양%]이 없으면 50%, [character name]이 없으면 자기 자신
		float ratioOfP = 0.5f;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			int percentage = atoi(token);

			// 범위 확인 및 오류 수정
			if (percentage <= 0) percentage = 50;
			else if (percentage >= 100) percentage = 100;

			ratioOfP = ((float)percentage)/100.0f;
		}
		else
		{
			ratioOfP = 0.5f;
		}

		CFieldIOCPSocket *pSocket = this;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (pSocket == NULL
				|| FALSE == pSocket->IsUsing())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0104, token);
				return FALSE;
			}
		}
		else
		{
			pSocket = this;
		}

//#ifdef _DEBUG
		if (pSocket == NULL
			|| FALSE == pSocket->IsUsing())
		{
			return FALSE;
		}
		if(FALSE == pSocket->IsValidCharacter())
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0103, pSocket->GetCharacter()->CharacterName);
			return FALSE;
		}
//#endif

		pSocket->m_character.CurrentHP = pSocket->m_character.HP*ratioOfP;
		pSocket->m_character.CurrentDP = pSocket->m_character.DP*ratioOfP;
		pSocket->m_character.CurrentSP = pSocket->m_character.SP*ratioOfP;
		pSocket->m_character.CurrentEP = pSocket->m_character.EP*ratioOfP;
		pSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

		pSocket->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
		pSocket->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
		pSocket->m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERNORMALIZE) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERNORMALIZE_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/일반" - 운영자나 게임 마스터 계정인 경우, 일반 계정으로 바꿈

		// 백업
		m_backupRace = m_character.Race;

		// 설정
		m_character.Race &= (~(RACE_OPERATION|RACE_GAMEMASTER|RACE_DEMO));

		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0105);

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERSPECIALIZE) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERSPECIALIZE_1))
	{
		if ( !COMPARE_RACE(m_backupRace, RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/특권" - 운영자나 게임 마스터 계정인 경우, 일반 계정에서 다시 특수 계정으로 바꿈

		// 설정
		m_character.Race = m_backupRace;

		// 초기화
		m_backupRace = 0;

		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0106);

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERINVINCIBILITY) == 0
			|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERINVINCIBILITY_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2006-04-13 by cmkwon, 관리자/운영자/DEMO만 사용 가능
			return FALSE;
		}

//		return FALSE;		// 테스트를 위해

		// format: "/무적" - 운영자나 게임 마스터 계정인 경우, 데미지를 입지 않음

		if (!m_bNoDamage)
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0107);
			m_bNoDamage = TRUE;
		}
		else
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0108);
			m_bNoDamage = FALSE;
		}

		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_POWERUP) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_POWERUP_1))
	{
		// 2012-09-11 by jhseol, 게임포지 명렁어 GM권한 포함 및 "/누구" 명령어 활성화
#ifdef _DEFINED_GAMEFORGE4D_
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
#else
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
#endif
		// end 2012-09-11 by jhseol, 게임포지 명렁어 GM권한 포함 및 "/누구" 명령어 활성화

//		return FALSE;		// 테스트를 위해

		// format: "/사기 [공격력 증가량(%)]" - 무기에 일시적으로 사기성을 띄게 한다

		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_POWERUP_HELP);
			return TRUE;
		}
		float fTemp = min(atof(token), 100000000.0f);
		fTemp = fTemp / 100.0f;
		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0109, fTemp*100.0f);
		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0111);
		m_ParamFactor.pfm_MINATTACK_01 += fTemp;
		m_ParamFactor.pfm_MAXATTACK_01 += fTemp;
		m_ParamFactor.pfm_MINATTACK_02 += fTemp;
		m_ParamFactor.pfm_MAXATTACK_02 += fTemp;
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_VARIABLESET) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_VARIABLESET_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		CFieldIOCPSocket *pSocket = this;
		// format: "/변수 [변수값]" - (일반)변수 조정
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			int nVariable = atoi(token);

			///////////////////////////////////////////////////////////////////
			// 여기 변수 설정하시오
			///////////////////////////////////////////////////////////////////
			//g_pFieldGlobal->m_bEventActivated = (nVariable==0?FALSE:TRUE);
			pSocket->m_defaultaddInvTime = nVariable;
			///////////////////////////////////////////////////////////////////
			// 여기 변수 설정하시오
			///////////////////////////////////////////////////////////////////

			return TRUE;
		}
		else
		{
			return FALSE;
		}

		return FALSE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_LEVELSET) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_LEVELSET_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/레벨 [level] [percentage of exp] [character name]" - 레벨을 조정함
		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_LEVELSET_HELP);			
			return TRUE;
		}

		int nLevel = atoi(token);

		if (nLevel > CHARACTER_MAX_LEVEL || nLevel <= 0)
		{
			return FALSE;
		}

		// percentage of exp
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			// 더 이상의 파라미터가 없으면, 자기 자신에 대해 경혐치 0%
			this->ChangeLevel(nLevel-m_character.Level);
			return TRUE;
		}

		int percentageOfExp = atoi(token);
		// character name
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			// 자기 자신
			this->ChangeLevel(nLevel-m_character.Level, percentageOfExp);
			return TRUE;
		}
		else
		{
			CFieldIOCPSocket *pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (pSocket == NULL
				|| FALSE == pSocket->IsUsing())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0112, token);
				return FALSE;
			}

			pSocket->ChangeLevel(nLevel-pSocket->m_character.Level, percentageOfExp);
			return TRUE;
		}

		return TRUE;
	}
	/////////////////////////////////////////////////
	// start 2011-09-05 by hskim, 파트너 시스템 2차	
	else if ( stricmp(token, STRCMD_CS_COMMAND_PARTNERLEVELSET) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_PARTNERLEVELSET_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/파트너레벨 [level] [percentage of exp] [partner UID]" - 레벨을 조정함
		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_PARTNERLEVELSET_HELP);
			return TRUE;
		}

		int nLevel = atoi(token);

		if (nLevel > PET_LEVEL_MAX || nLevel <= 0)
		{
			return FALSE;
		}

		token = strtok(NULL, seps);
		if (token == NULL)
		{
			this->PetChangeLevel(nLevel);

			return TRUE;
		}

		int percentageOfExp = atoi(token);
		token = strtok(NULL, seps);
		this->PetChangeLevel(nLevel, percentageOfExp);

		return TRUE;
	}
	// end 2011-09-05 by hskim, 파트너 시스템 2차
	/////////////////////////////////////////////////
	else if ( stricmp(token, STRCMD_CS_COMMAND_USERINVISIABLE) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_USERINVISIABLE_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		// format: "/투명" - 자신이 다른 캐릭터에게 보이지 않는다

// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
//		{
//			ClearBodyConditionBit(m_character.BodyCondition, BODYCON_STEALTH_MASK);
//			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0113);
//		}
//		else
//		{
//			SetBodyConditionBit(m_character.BodyCondition, BODYCON_STEALTH_MASK);
//			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0114);
//		}
		if(FALSE == this->IsInvisibleCharacter())
		{
			m_bIsInvisibleCharacter				= TRUE;
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0114);
		}
		else
		{
			m_bIsInvisibleCharacter				= FALSE;
			SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0113);
		}
		return TRUE;
	}
	else if ( stricmp(token, STRCMD_CS_COMMAND_DEBUGPRINTMSGF_0) == 0 
		|| stricmp(token, STRCMD_CS_COMMAND_DEBUGPRINTMSGF_1) == 0 )
	{
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: "/messagef" - 클라이언트와 필드 서버가 주고 받는 프로토콜을 모두 출력함

		if (m_bSendMessgeTypeDBG)
		{
			m_bSendMessgeTypeDBG = FALSE;
		}
		else
		{
			m_bSendMessgeTypeDBG = TRUE;
		}
		return TRUE;
	}
	else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_1))
	{
		// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 임시로 사용 안되는 명령어
		return FALSE;

// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 사용하지 않는 부분임
// 		if ( !CheckCommandExecutability(RACE_OPERATION) )
// 		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
// 			return FALSE;
// 		}
// 
// 		// format: "/이벤트 [경치|스피|경치복구|아템|레어아템|전쟁포인트] [배수 %f] [시간(분)]		- [경험치|스피|아이템드랍|레어아이템드랍|전쟁포인트] 이벤트 시작
// 		// format: "/이벤트 [경치|스피|경치복구|아템|레어아템|전쟁포인트] 종료						- [경치|스피|경치복구|아템|레어아템|전쟁포인트] 이벤트 종료
// 		// format: "/이벤트 [경치|스피|경치복구|아템|레어아템|전쟁포인트]							- [경치|스피|경치복구|아템|레어아템|전쟁포인트] 이벤트 정보 전송
// 		token = strtok(NULL, seps);
// 		if (token == NULL)
// 		{// 다음 인자가 없음
// 			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_GAMEEVENT_HELP);			
// 			return TRUE;
// 		}
// 
// 		if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1EXP) == 0
// 			|| stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1SPI) == 0
// 			|| stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1EXPR) == 0
// 			|| stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1ITEM) == 0
// 			|| stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1RARE) == 0
// 			|| stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1WARPOINT) == 0)			// 2007-06-27 by dhjin, WarPoint 이벤트 추가
// 		{
// 			EN_GAME_EVENT_TYPE enGEventType;
// 			if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1EXP) == 0)			enGEventType = GAME_EVENT_TYPE_EXP;
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1SPI) == 0)		enGEventType = GAME_EVENT_TYPE_SPI;
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1EXPR) == 0)	enGEventType = GAME_EVENT_TYPE_EXP_NO_DOWN;
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1ITEM) == 0)	enGEventType = GAME_EVENT_TYPE_DROP_ITEM;
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1RARE) == 0)	enGEventType = GAME_EVENT_TYPE_DROP_REAR_ITEM;
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P1WARPOINT) == 0)	enGEventType = GAME_EVENT_TYPE_WARPOINT;		// 2007-06-27 by dhjin, WarPoint 이벤트 추가
// 	
// 			token = strtok(NULL, seps);
// 			if(NULL == token)
// 			{// 다음 인자가 없음 - 경치 이벤트 정보를 리턴한다
// 
// 				char szTemp[1024];
// 				if(FALSE == ms_pFieldIOCP->m_gameEventManager.GetGameEventInfoString(szTemp, NULL, enGEventType, TRUE))
// 				{
// 					return FALSE;
// 				}
// 				
// 				this->SendString128(STRING_128_USER_NOTICE, szTemp);
// 				return TRUE;
// 			}
// 			else if(stricmp(token, STRCMD_CS_COMMAND_GAMEEVENT_P2END) == 0)
// 			{
// 				char szTemp[1024];
// 				BYTE byInflMask	 = INFLUENCE_TYPE_ALL_MASK;
// 				token = strtok(NULL, seps);
// 				if(token)
// 				{
// 					byInflMask = (BYTE)atoi(token);
// 					switch(byInflMask)
// 					{
// 					case INFLUENCE_TYPE_NORMAL:
// 					case INFLUENCE_TYPE_VCN:
// 					case INFLUENCE_TYPE_ANI:
// 					case INFLUENCE_TYPE_ALL_MASK:
// 						break;
// 					default:
// 						{
// 							return FALSE;
// 						}
// 					}
// 				}
// 
// 				if(FALSE == ms_pFieldIOCP->m_gameEventManager.EndGameEvent(enGEventType, TRUE, byInflMask))
// 				{
// 					sprintf(szTemp, STRMSG_S_F2NOTIFY_0115
// 						, CGameEventManager::GetGameEventTypeString(enGEventType));
// 					this->SendString128(STRING_128_USER_NOTICE, szTemp);					
// 				}
// 				else
// 				{
// 					BYTE byInflMask = INFLUENCE_TYPE_UNKNOWN;
// 					if(ms_pFieldIOCP->m_gameEventManager.GetGameEventInfoString(szTemp, &byInflMask, enGEventType, TRUE))
// 					{
// 						ms_pFieldIOCP->SendString128ToAllClients(STRING_128_USER_NOTICE, szTemp, TRUE, byInflMask);
// 					}
// 				}
// 
// 				return TRUE;
// 			}
// 
// 			float fExpRate = atof(token);
// 			if(fExpRate <= 0.0f)
// 			{// 경험치배수 오류
// 
// 				return FALSE;
// 			}
// 
// 			token = strtok(NULL, seps);
// 			if(NULL == token)
// 			{// 시간 정보가 없음
// 
// 				return FALSE;
// 			}
// 
// 			int nLimitMinute = atoi(token);
// 			if(nLimitMinute <= 0)
// 			{// 시간 정보 오류
// 
// 				return FALSE;
// 			}
// 
// 			BYTE byInflMask	 = INFLUENCE_TYPE_ALL_MASK;
// 			token = strtok(NULL, seps);
// 			if(token)
// 			{
// 				byInflMask = (BYTE)atoi(token);
// 				switch(byInflMask)
// 				{
// 				case INFLUENCE_TYPE_NORMAL:
// 				case INFLUENCE_TYPE_VCN:
// 				case INFLUENCE_TYPE_ANI:
// 				case INFLUENCE_TYPE_ALL_MASK:
// 					break;
// 				default:
// 					{
// 						return FALSE;
// 					}
// 				}
// 			}
// 
// 			///////////////////////////////////////////////////////////////////////////////
// 			// 2007-09-17 by cmkwon, StartGameEvent 에러 발생시 응답 메시지 추가
// 			if(FALSE == ms_pFieldIOCP->m_gameEventManager.StartGameEvent(enGEventType, fExpRate, nLimitMinute, 1, CHARACTER_MAX_LEVEL, byInflMask))	// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
// 			{
// 				char szTemp[1024];
// 				if(FALSE == ms_pFieldIOCP->m_gameEventManager.GetGameEventInfoString(szTemp, NULL, enGEventType, TRUE))
// 				{
// 					return FALSE;
// 				}				
// 				this->SendString128(STRING_128_USER_NOTICE, "StartGameEvent error !!, %s", szTemp);
// 				return FALSE;
// 			}
// 
// 			char szTemp[1024];
// 			sprintf(szTemp, STRMSG_S_F2NOTIFY_0116
// 				, CGameEventManager::GetGameEventTypeString(enGEventType), fExpRate, nLimitMinute);
// 			ms_pFieldIOCP->SendString128ToAllClients(STRING_128_USER_NOTICE, szTemp, TRUE, byInflMask);
// 			return TRUE;
//		}
		
		return FALSE;				// 이벤트 명령어가 없음		
	}// end_else if(stricmp(token, "/이벤트") == 0)
	else if(stricmp(token, STRCMD_CS_COMMAND_PREMEUM) == 0
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_PREMEUM_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION))
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}

		// format: /프리미엄 [일반|슈퍼] [종료]
		token = strtok(NULL, seps);
		if(NULL == token)
		{// 다음 인자가 없음 - 경치 이벤트 정보를 리턴한다

			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_PREMEUM_HELP);
			return TRUE;
		}

		if(0 == stricmp(token, STRCMD_CS_COMMAND_PREMEUM_PNORMAL))
		{
			token = strtok(NULL, seps);
			if(NULL == token)
			{
				Err_t nRetedErr = this->m_ItemManager.CashInsertPremiumCard(ms_pFieldIOCP->GetItemInfo(ITEM_NUM_CASH_NORMAL_PREMIUM_CARD));

				if(0 == nRetedErr)
				{
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0117);
				}
				else
				{
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0118);
				}
				return TRUE;
			}			
		}
		else if(0 == stricmp(token, STRCMD_CS_COMMAND_PREMEUM_PSUPER))
		{
			token = strtok(NULL, seps);
			if(NULL == token)
			{
				Err_t nRetedErr = this->m_ItemManager.CashInsertPremiumCard(ms_pFieldIOCP->GetItemInfo(ITEM_NUM_CASH_NORMAL_PREMIUM_CARD));
				if(0 == nRetedErr)
				{
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0119);
				}
				else
				{
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0118);
				}
				return TRUE;
			}
		}
// 2006-07-05 by cmkwon, 프리미엄 카드 시스템을 MonthlyPay로 변경, 업그레이드 기능은 필요없음
// 		else if(0 == stricmp(token, STRCMD_CS_COMMAND_PREMEUM_PUPGRADE))
// 		{
// 			token = strtok(NULL, seps);
// 			if(NULL == token)
// 			{
// 				Err_t nRetedErr = this->m_ItemManager.CashInsertPremiumCard(ms_pFieldIOCP->GetItemInfo(ITEM_NUM_CASH_UPGRADE_PREMIUM_CARD));
// 				if(0 == nRetedErr)
// 				{
// 					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0119);
// 				}
// 				else
// 				{
// 					this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0118);
// 				}
// 				return TRUE;
// 			}
// 		}
		else if(0 == stricmp(token, STRCMD_CS_COMMAND_PREMEUM_PEND))
		{
			this->m_ItemManager.CashCheckPremiumCardExpire(TRUE);
			return TRUE;
		}
	}// end_else if(stricmp(token, "/프리미엄") == 0)
// 2008-02-14 by cmkwon, 도시점령전 명령어 제거
// 	else if(stricmp(token, STRCMD_CS_COMMAND_CITYWAR) == 0
// 		|| 0 == stricmp(token, STRCMD_CS_COMMAND_CITYWAR_1))
// 	{
// 		
// 		if ( !CheckCommandExecutability(RACE_OPERATION))
// 		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
// 			return FALSE;
// 		}
// 
// 		if(NULL == m_pCurrentFieldMapChannel->m_pRefCityWar1
// 			|| FALSE == IS_CITYWAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
// 		{
// 			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0120);
// 			return TRUE;
// 		}
// 
// 		// format: /도시점령전 [시작|종료]
// 		token = strtok(NULL, seps);
// 		if(NULL == token)
// 		{// 다음 인자가 없음 - 경치 이벤트 정보를 리턴한다
// 
// 			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CITYWAR_HELP);
// 			return TRUE;
// 		}
// 
// 		if(0 == stricmp(token, STRCMD_CS_COMMAND_CITYWAR_PSTART))
// 		{
// 			if(FALSE == m_pCurrentFieldMapChannel->m_pRefCityWar1->SetStartState())
// 			{
// 				this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0121);
// 				return TRUE;
// 			}
// 			ms_pFieldIOCP->OnCityWarStartFieldIOCP(m_pCurrentFieldMapChannel->m_pRefCityWar1);
// 			return TRUE;
// 		}
// 		else if(0 == stricmp(token, STRCMD_CS_COMMAND_CITYWAR_PEND))
// 		{
// 			vectCITYWAR_QUEST tmVectCITYWAR_QUEST;
// 			tmVectCITYWAR_QUEST.clear();
// 			if(FALSE == m_pCurrentFieldMapChannel->m_pRefCityWar1->SetEndState(&tmVectCITYWAR_QUEST))
// 			{
// 				this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0122);
// 				return TRUE;
// 			}
// 			ms_pFieldIOCP->OnCityWarEndFieldIOCP(m_pCurrentFieldMapChannel->m_pRefCityWar1, &tmVectCITYWAR_QUEST);			
// 			return TRUE;
// 		}
// 	}// end_else if(stricmp(token, "/도시점령전") == 0)
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_STEALTH)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_STEALTH_1))
	{
		// "format: /스텔스 - 선공형 몬스터가 먼저 공격하지 않는다"
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}
		this->m_bStealthState = !this->m_bStealthState;
		if(FALSE == this->m_bStealthState)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0123);
		}
		else
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0124);
		}

		INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);
		pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
		pSMsg->ClientIndex		= m_character.ClientIndex;
		pSMsg->bStealthState2	= this->GetStealthState();		// 2013-05-09 by hskim, 세력 포인트 개선
		m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
		return TRUE;
	}// end_else if(0 == stricmp(token, "/스텔스"))
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_RETURNALL)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_RETURNALL_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// format: /모두귀환
// 2006-07-24 by cmkwon, 아래와 같이 세력별 도시맵으로 이동으로 변경함
// 		token = strtok(NULL, seps);
// 		if(NULL == token)
// 		{// 다음 인자가 없음
// 			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_RETURNALL_HELP);
// 			return TRUE;
// 		}
// 		int MapIndex = atoi(token);
// 		if(FALSE == m_pCurrentFieldMapChannel->WarpToCityMapFieldMapChannel(MapIndex, this->GetCharacter()->GuildUniqueNumber))
// 		{
// 			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0125);
// 		}

		GetCurrentFieldMapChannel()->WarpToCityMap(this->GetCharacter()->CharacterUniqueNumber);
		return TRUE;
	}// end_else if(0 == stricmp(token, "/모두귀환"))
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_HAPPYHOUREVENT)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_HAPPYHOUREVENT_1))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
		
		// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 명령어 형식 수정됨
		//// format: /해피아워이벤트 [시작|종료] [진행시간(단위:분)]
		// "format: /해피아워이벤트 [255(모든세력)|0(일반세력)|2(VCN)|4(ANI)] [시작|종료] [진행시간(단위:분)]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_HAPPYHOUREVENT_HELP);
			return TRUE;
		}

		// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 세력 파라미터 추가됨
		BYTE byInflTy = atoi(token);
		switch(byInflTy)
		{
		case INFLUENCE_TYPE_NORMAL:
		case INFLUENCE_TYPE_VCN:
		case INFLUENCE_TYPE_ANI:
		case INFLUENCE_TYPE_ALL_MASK:
			break;
		default:
			{
				this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_HAPPYHOUREVENT_HELP);
				return TRUE;
			}
		}

		token = strtok(NULL, seps);
		if(NULL ==  token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_HAPPYHOUREVENT_HELP);
			return TRUE;
		}
		if(0 == stricmp(token, STRCMD_CS_COMMAND_HAPPYHOUREVENT_PSTART))
		{
			token = strtok(NULL, seps);
			if(NULL == token)
			{
				this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_HAPPYHOUREVENT_HELP);
				return TRUE;
			}
			
			int nEventTime = max(10, atoi(token));
			ATUM_DATE_TIME aStartTime, aEndTime;
			aStartTime.SetCurrentDateTime(TRUE);
			aEndTime = aStartTime;
			aEndTime.AddDateTime(0, 0, 0, 0, nEventTime, 0);

			// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 -
			//ms_pFieldIOCP->m_pHappyHourEventManager->SetHappyHourEventTime(aStartTime, aEndTime, TRUE);
			ms_pFieldIOCP->m_pHappyHourEventManager->SetHappyHourEventPeriod(byInflTy, aStartTime, aEndTime, TRUE);
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0126, nEventTime);
			return TRUE;
		}
		else if(0 == stricmp(token, STRCMD_CS_COMMAND_HAPPYHOUREVENT_PEND))
		{
			ATUM_DATE_TIME aStartTime, aEndTime;
			aStartTime.SetCurrentDateTime(TRUE);
			aEndTime = aStartTime;
			// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 -
			//ms_pFieldIOCP->m_pHappyHourEventManager->SetHappyHourEventTime(aStartTime, aEndTime, TRUE);
			ms_pFieldIOCP->m_pHappyHourEventManager->SetHappyHourEventPeriod(byInflTy, aStartTime, aEndTime, TRUE);
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0127);
			return TRUE;
		}
	}// end_else if(0 == stricmp(token, "/해피아워이벤트"))
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_2))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2006-04-13 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
		
		// format: /BonusStat [Bonus Counts] [|character name] - 보너스 스탯 증가
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_BONUSSTAT_HELP);
			return TRUE;
		}
		int nBonus = min(255, atoi(token));
		if(nBonus <= 0)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_BONUSSTAT_HELP);
			return TRUE;
		}
		CFieldIOCPSocket *pFISock = this;
		token = strtok(NULL, seps);
		if(token)
		{
			pFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (pFISock == NULL
				|| FALSE == pFISock->IsUsing())
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0112, token);
				return FALSE;
			}
		}

		pFISock->m_character.BonusStat = min(255, pFISock->m_character.BonusStat+nBonus);		// 2007-06-19 by cmkwon, 버그 수정
		CAtumLogSender::SendLogMessageSTAT(pFISock, STAT_BONUS, m_character.BonusStat);			// 2007-06-20 by cmkwon, 보너스 스탯 증가 로그 남기기
		pFISock->SendStat_UpdateDB(TRUE, FALSE, TRUE);		// 2010-05-12 by cmkwon, 인피1차 발동류 적용 이후 퀘스트 보상 보너스 스탯 버그 수정(K0002932) - 
		pFISock->UpdateDBtoBonusStatPoint();
		return TRUE;
	}// end_else if(0 == stricmp(token, "/보너스스탯"))
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_POINT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_POINT_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_POINT_2))
	{// 2007-01-08 by dhjin, 보너스스텟포인트를 DB에 저장 시킨다. (신규 케릭터 생성시 보너스 스텟 포인트 DB에 업데이트 안되는 문제 수정)
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2007-01-10 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
		
		// "format: /BonusStatPoint [BonusStatPoint Counts] [|character name] - BonusStatPoint를 DB에 UPDATE"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "BonusStatPoint:[%3d]", m_character.BonusStatPoint);
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_BONUSSTAT_POINT_HELP);
			return TRUE;
		}
		int nBonus = min(255, atoi(token));
		if(nBonus <= 0)
		{
			this->SendString128(STRING_128_USER_NOTICE, "BonusStatPoint:[%3d]", m_character.BonusStatPoint);
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_BONUSSTAT_POINT_HELP);
			return TRUE;
		}
		CFieldIOCPSocket *pFISock = this;
		token = strtok(NULL, seps);
		if(token)
		{
			pFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (NULL == pFISock
				|| FALSE == pFISock->IsValidCharacter(FALSE))
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0112, token);
				return FALSE;
			}
		}

		pFISock->m_character.BonusStatPoint	= nBonus;
		CAtumLogSender::SendLogMessageSTAT(pFISock, STAT_BONUS_STAT_POINT, m_character.BonusStatPoint);			// 2007-06-20 by cmkwon, 보너스 스탯 증가 로그 남기기
		pFISock->SendStat_UpdateDB(TRUE, FALSE);
		pFISock->UpdateDBtoBonusStatPoint();			// 보너스 스탯 포인트를 DB에 증가
		return TRUE;
	}// end_else if(0 == stricmp(token, "/보너스스탯DB업데이트"))	
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_QUESTCOMPLETION_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_QUESTCOMPLETION_1))
// 2007-06-19 by cmkwon, 버그 수정
//		|| 0 == stricmp(token, STRCMD_CS_COMMAND_BONUSSTAT_2))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/퀘스트완료' 운영자 사용 불가, // 일반 사용자는 무시(운영자, 관리자 가능)
			return FALSE;
		}

		// "format: /퀘스트완료 [퀘스트인덱스]"
		int nReqQuestIndex = -1;
		token = strtok(NULL, seps);
		if(token)
		{
			nReqQuestIndex	= atoi(token);
		}
		if(FALSE == this->GMQuestCompletion(nReqQuestIndex))
		{
			SendString128(STRING_128_ADMIN_CMD, "Quest cannot be completed.");
			return FALSE;
		}
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_INFLDITRIBUTION_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFLDITRIBUTION_1))
	{// 2006-02-08 by cmkwon, 모든 사용자 가능

		int nVCNDistPercent = ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_VCN);
		// "format: /세력분포"
		// 2007-11-08 by cmkwon, GM 명령어 정리 - 관리자만 유저수를 보여준다.
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 일반 사용자
		//	  '바이제니유 정규군:55%'
		//	  '알링턴 정규군:45%'
			SendString128(STRING_128_USER_NOTICE, "  %s:%d%%"
				, STRCMD_CS_INFLUENCE_TYPE_VCN, ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_VCN));
			SendString128(STRING_128_USER_NOTICE, "  %s:%d%%"
				, STRCMD_CS_INFLUENCE_TYPE_ANI, ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_ANI));
		}
		else
		{// 운영자, 관리자
		//	  '바이제니유 정규군:55%(550)'
		//	  '알링턴 정규군:45%(450)'
			SendString128(STRING_128_USER_NOTICE, "  %s:%d%%(%d)"
				, STRCMD_CS_INFLUENCE_TYPE_VCN, ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_VCN), ms_pFieldIOCP->m_nVCNInfluenceCount);
			SendString128(STRING_128_USER_NOTICE, "  %s:%d%%(%d)"
				, STRCMD_CS_INFLUENCE_TYPE_ANI, ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_ANI), ms_pFieldIOCP->m_nANIInfluenceCount);
		}

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_CHANGEINFL_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_CHANGEINFL_1))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-05-10 by dhjin, ARENA 상태에서는 세력 변경이 불가능하다
		if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
		{
			return FALSE;
		}
		
		// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 인피 상태 값을 메인서버로 전송한다. 인피 상태 체크
		if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState ) {
			return FALSE;
		}

		// "format: /세력변경 [|1(Normal)|2(VCN)|4(ANI)]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CHANGEINFL_HELP);
			this->SendString128(STRING_128_USER_NOTICE, "Your nation is %s(%d)."
				, CAtumSJ::GetInfluenceTypeString(m_character.InfluenceType), m_character.InfluenceType);
			return TRUE;
		}

		BYTE byChangeInfl = atoi(token);		// 2006-02-08 by cmkwon
		if(FALSE == IS_VALID_INFLUENCE_TYPE(byChangeInfl)
			|| m_character.InfluenceType == byChangeInfl)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CHANGEINFL_HELP);
			this->SendString128(STRING_128_USER_NOTICE, "Your nation is %s(%d)."
				, CAtumSJ::GetInfluenceTypeString(m_character.InfluenceType), m_character.InfluenceType);
			return TRUE;
		}

		this->ChangeCharacterInfluenceType(byChangeInfl, TRUE);		// 세력변경 처리

		this->GMQuestAdjustByInfluenceType(byChangeInfl);			// 2006-08-08 by cmkwon, 세력변경 후 세력별 퀘스트 정리
		return TRUE;
	}
	// 2013-07-26 by jhseol, 타 계정 세력변경
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ACCOUNT_CHANGEINFL_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ACCOUNT_CHANGEINFL_1))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2006-04-13 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}
		
		//////////////////////////////////////////////////////////////////////////
		// 2007-05-10 by dhjin, ARENA 상태에서는 세력 변경이 불가능하다
		if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
		{
			return FALSE;
		}
		
		// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 인피 상태 값을 메인서버로 전송한다. 인피 상태 체크
		if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState ) {
			return FALSE;
		}
		
		// "format: /계정세력변경 [계정UID] [2(BCU)|4(ANI)]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ACCOUNT_CHANGEINFL_HELP);
			return TRUE;
		}
		
		UID32_t UserAccountUID = atoi(token);
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ACCOUNT_CHANGEINFL_HELP);
			return TRUE;
		}

		BYTE byChangeInfl = atoi(token);
		if( INFLUENCE_TYPE_VCN == byChangeInfl || INFLUENCE_TYPE_ANI == byChangeInfl)
		{
			// 세력변경 처리
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AccountInflChange, this, 0, NULL, NULL, (INT64)UserAccountUID, (INT64)byChangeInfl);
			return TRUE;
		}
		else
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ACCOUNT_CHANGEINFL_HELP);
			return TRUE;
		}
	}
	// end 2013-07-26 by jhseol, 타 계정 세력변경
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_GOMONSTER_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_GOMONSTER_1))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 일반 사용자는 무시(운영자, 관리자 가능)
			return FALSE;
		}

		// "format: /가기몹 [MonsterName|MonsterNumber]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_GOMONSTER_HELP);
			return TRUE;
		}

		MONSTER_INFO *pMonInfo = ms_pFieldIOCP->GetMonsterInfo(atoi(token));
		if(NULL == pMonInfo)
		{
			pMonInfo = ms_pFieldIOCP->GetMonsterInfo(token);
			if(NULL == pMonInfo)
			{
				return FALSE;
			}
		}

		CFieldMonster *pFMon = (CFieldMonster*)m_pCurrentFieldMapChannel->GetMonsterByMonsterUnitKind(pMonInfo->MonsterUnitKind);
		if(NULL == pFMon)
		{
			return FALSE;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-05-22 by dhjin, 아레나 맵에서 사용시 아레나 대전 중이면 팀에서 탈퇴 처리 한다.
		if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())
			&& m_ArenaInfo.IsValidArenaState() )
		{
			if(m_ArenaInfo.WatchState)
			{// 2007-06-21 by dhjin, 관전자이면 관전 정보를 초기화한다.
				this->WatchEnd();
			}
			else
			{
				this->ms_pFieldIOCP->m_ArenaManager.DeleteMember(this);		// 2007-04-23 by dhjin, 팀원 삭제
				this->m_ArenaInfo.ResetArenaInfo();		
				this->SendAddMessageType(T_FC_ARENA_REAVE_TEAM_OK);			// 2007-05-03 by dhjin, 아레나에서 떠난 상태 정보 전송

				// 2008-01-15 by dhjin, 아레나 통합 - 필드 서버로 강제 종료 전송하여 처리
				this->SendArenaCharacterDisConnect();
//				// 2007-06-07 by dhjin, 강제 종료 1증가
//				this->m_character.ArenaDisConnect += 1;
//				QPARAM_UPDATE_ARENA_DISCONNECT *pQparam = new QPARAM_UPDATE_ARENA_DISCONNECT;
//				pQparam->CharacterUID			= this->m_character.CharacterUniqueNumber;
//				pQparam->AccountUID				= this->m_character.AccountUniqueNumber;
//				pQparam->ArenaDisConnect		= this->m_character.ArenaDisConnect;
//				this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateArenaDisConnect, this, 0, pQparam);
		    }
        }
		
		WarpToMap(m_pCurrentFieldMapChannel->m_MapChannelIndex, &pFMon->PositionVector);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_SIGNBOARD_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_SIGNBOARD_1))
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_INFLUENCE_LEADER))
		{// 2006-04-20 by cmkwon, 관리자/운영자/세력리더만 사용 가능
			return FALSE;
		}
		// "format: /전광판 [지속시간(단위:분)] [공지 사항 내용]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_HELP);
			return TRUE;
		}

		int nUpkeepMinute = atoi(token);
		if(0 >= nUpkeepMinute)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_HELP);
			return FALSE;
		}

		token = strtok(NULL, "");
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_HELP);
			return FALSE;
		}

		MSG_SIGN_BOARD_STRING	tmSignBoardString;
		MEMSET_ZERO(&tmSignBoardString, sizeof(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING));
		if(COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
		{
			tmSignBoardString.InfluenceMask0	= m_character.InfluenceType;
			tmSignBoardString.IsInfluenceLeader	= TRUE;
		}
		else
		{
			tmSignBoardString.InfluenceMask0	= INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI;
			tmSignBoardString.IsInfluenceLeader	= FALSE;
		}
		tmSignBoardString.SignBoardExprieATime.SetCurrentDateTime(TRUE);
		tmSignBoardString.SignBoardExprieATime.AddDateTime(0, 0, 0, 0, nUpkeepMinute, 0);
		STRNCPY_MEMSET(tmSignBoardString.SingBoardString, token, SIZE_MAX_SIGN_BOARD_STRING);
		if(FALSE == ms_pFieldIOCP->SignBoardInsertString(&tmSignBoardString))
		{
			this->SendString128(STRING_128_USER_NOTICE, "SignBoard String Buffer overflow!!");
			return FALSE;
		}
		
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING, T_FC_WAR_SIGN_BOARD_INSERT_STRING, pSSignBoardString, SendBuf);
		pSSignBoardString->IsInfluenceLeader	= tmSignBoardString.IsInfluenceLeader;
		pSSignBoardString->StringIndex			= tmSignBoardString.StringIndex;
		pSSignBoardString->SignBoardExprieATime	= tmSignBoardString.SignBoardExprieATime;
		STRNCPY_MEMSET(pSSignBoardString->SingBoardString, tmSignBoardString.SingBoardString, SIZE_MAX_SIGN_BOARD_STRING);
		if(FALSE == tmSignBoardString.IsInfluenceLeader)
		{
			if(FALSE == this->IsCityCurrentFieldMapChannel())
			{
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING));
			}
			ms_pFieldIOCP->SendMessageToCityClients(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING), INFLUENCE_TYPE_VCN);
			ms_pFieldIOCP->SendMessageToCityClients(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING), INFLUENCE_TYPE_ANI);
		}
		else
		{
			if(FALSE == this->IsCityCurrentFieldMapChannel())
			{
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING));
			}
			ms_pFieldIOCP->SendMessageToCityClients(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_INSERT_STRING), GetCharacter()->InfluenceType);
		}
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_SIGNBOARD_DEL_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_SIGNBOARD_DEL_1))
	{

		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_INFLUENCE_LEADER))
		{// 관리자, 운영자, 세력지도자 사용 가능 명령어
			return FALSE;
		}
		// "format: /전광판삭제 [삭제 할 공지사항 인덱스]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_DEL_HELP);
			return TRUE;
		}

		int nStrIdx = atoi(token);
		if(0 >= nStrIdx)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_DEL_HELP);
			return FALSE;
		}
		BOOL bInflLeader = COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER);
		if(FALSE == ms_pFieldIOCP->SignBoardDeleteString(nStrIdx, bInflLeader))
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SIGNBOARD_DEL_HELP);
			return FALSE;
		}
				
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_SIGN_BOARD_DELETE_STRING, T_FC_WAR_SIGN_BOARD_DELETE_STRING, pSDelString, SendBuf);
		pSDelString->DeleteStringIndex			= nStrIdx;
		if(FALSE == bInflLeader)
		{
			ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_DELETE_STRING));
		}
		else
		{
			ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_SIGN_BOARD_DELETE_STRING), m_character.InfluenceType);
		}
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_CONPOINT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_CONPOINT_1))
	{// 2006-04-24 by cmkwon
// 2006-05-22 by cmkwon, Gala-Net 요청으로 수정
// 		if(FALSE == g_pFieldGlobal->InMasangServer())
// 		{// 2006-04-24 by cmkwon, 마상 내부에서만 사용 가능 명령어
// 			return FALSE;
// 		}
		if (FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 관리자만 사용 가능 명령어
			return FALSE;
		}
		// "format: /기여도 [세력(2:VCN, 4:ANI)] [증가분] - 특정 세력의 기여도를 증가시킨다"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CONPOINT_HELP);
			this->SendString128(STRING_128_USER_NOTICE, "ContributionPoint VCN:%5d, ANI:%5d"
				, ms_pFieldIOCP->m_InflWarManager.GetContributionPoint(INFLUENCE_TYPE_VCN)
				, ms_pFieldIOCP->m_InflWarManager.GetContributionPoint(INFLUENCE_TYPE_ANI));
			return TRUE;
		}

		int nInflTy = atoi(token);
		if(INFLUENCE_TYPE_VCN != nInflTy
			&& INFLUENCE_TYPE_ANI != nInflTy)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CONPOINT_HELP);
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CONPOINT_HELP);
			return FALSE;
		}

		int nAddPoint = atoi(token);

		if(0 >= nAddPoint
			|| 100000 < nAddPoint)
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ContributionPoint");
			return FALSE;
		}

// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(nInflTy, nAddPoint, 0);
#else
		ms_pFieldIOCP->m_InflWarManager.AddContributionPoint(nInflTy, nAddPoint);
#endif
// end 2013-05-09 by hskim, 세력 포인트 개선
		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_COMEONINFL_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_COMEONINFL_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_COMEONINFL_2))
	{// 2006-07-18 by cmkwon
		// 2012-09-11 by jhseol, 게임포지 명렁어 GM권한 포함 및 "/누구" 명령어 활성화
#ifdef _DEFINED_GAMEFORGE4D_
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/세력오기' 운영자 사용 불가, // 2006-07-18 by cmkwon, 관리자/운영자만 사용 가능
			return TRUE;
		}
#else
		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/세력오기' 운영자 사용 불가, // 2006-07-18 by cmkwon, 관리자/운영자만 사용 가능
			return TRUE;
		}
#endif
		// end 2012-09-11 by jhseol, 게임포지 명렁어 GM권한 포함 및 "/누구" 명령어 활성화

		//////////////////////////////////////////////////////////////////////////
		// 2007-06-22 by dhjin, 아레나 맵에서는 사용 불가
		if(IS_MAP_INFLUENCE_ARENA(this->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{
			return FALSE;
		}

		// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
		// "format: /ComeOnInfl [1(Normal)|2(VCN)|4(ANI)|255(All)] [최대인원] [0|최소레벨] [0|최대레벨] [1(B)|16(M)|256(A)|4096] [유저에게 보내는 메시지] - 임의의 지정한 세력, 지정한 레벨의 유저들에게 이벤트맵으로 이동을 요청한다"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}

		SCALL_WARP_EVENT tmCallWarpEvent;
		MEMSET_ZERO(&tmCallWarpEvent, sizeof(SCALL_WARP_EVENT));
		tmCallWarpEvent.byPermissionInfluenceMask	= (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(tmCallWarpEvent.byPermissionInfluenceMask, INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}
		
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}
		tmCallWarpEvent.nPermissionUserCnts			= min(1000, atoi(token));
		if(0 == tmCallWarpEvent.nPermissionUserCnts)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}
		tmCallWarpEvent.byPermissionMinLevel		= atoi(token);

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}
		tmCallWarpEvent.byPermissionMaxLevel		= atoi(token);
		if(0 != tmCallWarpEvent.byPermissionMaxLevel
			&& tmCallWarpEvent.byPermissionMinLevel > tmCallWarpEvent.byPermissionMaxLevel)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}

		// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 기어타입 설정
		USHORT usReqUnitKind = atoi(token);
		if(IS_BGEAR(usReqUnitKind)){		tmCallWarpEvent.usReqUnitKind |= UNITKIND_BGEAR_MASK;}
		if(IS_MGEAR(usReqUnitKind)){		tmCallWarpEvent.usReqUnitKind |= UNITKIND_MGEAR_MASK;}
		if(IS_AGEAR(usReqUnitKind)){		tmCallWarpEvent.usReqUnitKind |= UNITKIND_AGEAR_MASK;}
		if(IS_IGEAR(usReqUnitKind)){		tmCallWarpEvent.usReqUnitKind |= UNITKIND_IGEAR_MASK;}
		if(0 == tmCallWarpEvent.usReqUnitKind)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}

		token = strtok(NULL, "");
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_COMEONINFL_HELP2);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
			return FALSE;
		}
		tmCallWarpEvent.dwCallWarpEventID		= timeGetTime();
		tmCallWarpEvent.dwSupportTermTick		= 12000;			// 2006-07-21 by cmkwon, 12초
		tmCallWarpEvent.vWarpPosition			= m_character.PositionVector;
		tmCallWarpEvent.CallMapChannelIndex		= GetCurrentFieldMapChannel()->GetMapChannelIndex();
		ms_pFieldIOCP->AddCallWarpEventRequest(&tmCallWarpEvent);

		INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_CALL_WARP_EVENT_REQUEST, T_FC_EVENT_CALL_WARP_EVENT_REQUEST, pSCallWarp, SendBuf);
		pSCallWarp->dwCallWarpEventID0			= tmCallWarpEvent.dwCallWarpEventID;
		pSCallWarp->dwSupportTermTick0			= tmCallWarpEvent.dwSupportTermTick-2000;	// 2006-07-24 by cmkwon, 10초
		STRNCPY_MEMSET(pSCallWarp->szUserMessage, token, SIZE_STRING_128);
		ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_EVENT_CALL_WARP_EVENT_REQUEST), tmCallWarpEvent.byPermissionInfluenceMask
			, tmCallWarpEvent.byPermissionMinLevel, tmCallWarpEvent.byPermissionMaxLevel, &tmCallWarpEvent.CallMapChannelIndex, FALSE, TRUE, tmCallWarpEvent.usReqUnitKind);	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - , // 2007-06-22 by dhjin, 아레나 진행중인 유저에게는 전송하지 않는다.
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINMAP_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINMAP_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMINMAP_2))
	{// 2006-07-24 by cmkwon
		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2006-10-23 by cmkwon, 관리자만 허용하도록 수정
			return TRUE;
		}

		// "format: /InsertItemInMap [1(Normal)|2(VCN)|4(ANI)|3|5|6|7] [Item Number] [# of items] - 현재맵의 지정한 세력 유저에게 지정한 아이템을 지급한다"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;
		}

		BYTE byInflTyMask = (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(byInflTyMask, INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid IfluenceTypeMask");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "ItemNum error");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;
		}

		int nInsertItemNum = atoi(token);
		if(NULL == ms_pFieldIOCP->GetItemInfo(nInsertItemNum))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ItemNum");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;			
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "ItemCount error");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;
		}

		int nInsertItemCnts = atoi(token);
		if(0 >= nInsertItemCnts)
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ItemCount");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMINMAP_HELP);
			return FALSE;
		}
		
		GetCurrentFieldMapChannel()->InsertItemInMap(nInsertItemNum, nInsertItemCnts, byInflTyMask);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_DISTRIBUTIONLEVEL_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_DISTRIBUTIONLEVEL_1))
	{// 2006-08-09 by dhjin. /레벨분포 명령어 처리.
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/레벨분포' 운영자 사용 불가, // 2006-08-08 by dhjin, 관리자/운영자만 사용 가능
			return FALSE;
		}
		int UserDistributionLevel[10];
		
		ms_pFieldIOCP->GetUserLevelList(UserDistributionLevel);
	
		SendString128(STRING_128_ADMIN_CMD, "Lv1~10:%d,Lv11~20:%d,Lv21~30:%d,Lv31~40:%d,Lv41~50:%d,Lv51~60:%d,Lv61~70:%d,Lv71~80:%d,Lv81~90:%d,Lv91~:%d"
			,UserDistributionLevel[0],UserDistributionLevel[1]
			,UserDistributionLevel[2],UserDistributionLevel[3],UserDistributionLevel[4],UserDistributionLevel[5]
			,UserDistributionLevel[6],UserDistributionLevel[7],UserDistributionLevel[8],UserDistributionLevel[9]);

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_MARKET_ACTIVATION_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MARKET_ACTIVATION_1))
	{// 2014-03-18 by bckim, 마켓 ON/OFF
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}

#ifdef SC_MARKET_JHSEOL_BCKIM_SSJUNG
		ms_pFieldIOCP->m_bMarketActivation = !(ms_pFieldIOCP->m_bMarketActivation);
		SendString128(STRING_128_ADMIN_CMD, "Market Activation State [%s]",(ms_pFieldIOCP->m_bMarketActivation)?("TRUE"):("FALSE"));
#endif
		return TRUE;
	}// End. 2014-03-18 by bckim, 마켓 ON/OFF
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_PCBANGUSERCOUNT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_PCBANGUSERCOUNT_1))
	{// 2007-01-25 by dhjin, /PCBang 명령어 처리.
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/PCBang' 운영자 사용 불가, // 2007-01-25 by dhjin, 관리자/운영자만 사용 가능
			return FALSE;
		}
		int PCBangUserCount = ms_pFieldIOCP->GetPCBangUserCount();
	
		SendString128(STRING_128_ADMIN_CMD, "TotalPCBangUserCount:%d", PCBangUserCount);

		return TRUE;
	}	
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_1))
	{// 2006-11-17 by cmkwon, format: /시간제한시스템 [on|off] - 오늘 하루 게임 접속 시간을 보여준다

		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 2006-11-17 by cmkwon, 관리자/운영자만 사용 가능
			return FALSE;
		}

		if(LANGUAGE_TYPE_VIETNAMESE != g_pFieldGlobal->GetLanguageType())
		{// 2006-11-17 by cmkwon, 일반 유저는 베트남에서 사용 가능
			return FALSE;
		}
	
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_HELP);
			return FALSE;
		}

		if(0 == stricmp(token, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_P2ON))
		{// 2006-11-17 by cmkwon, 시간제한시스템 켜기
			ms_pFieldIOCP->m_bUseTimeLimiteSysteOfToday		= TRUE;
		}
		else if(0 == stricmp(token, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_P2OFF))
		{// 2006-11-17 by cmkwon, 시간제한시스템 끄기
			ms_pFieldIOCP->m_bUseTimeLimiteSysteOfToday		= FALSE;
		}
		else
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TIMELIMITSYSTEM_HELP);
			return FALSE;
		}		

		this->SendString128(STRING_128_USER_NOTICE, "%s ==> [%s]", STRCMD_CS_COMMAND_TIMELIMITSYSTEM_1, token);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_PLAYTIME_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_PLAYTIME_1))
	{// 2006-11-17 by cmkwon, format: /이용시간 - 오늘 하루 게임 접속 시간을 보여준다

// 2007-06-27 by cmkwon, 중국 Playtime 명령어 일반 유저 가능 
//		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
//		{// 2006-11-17 by cmkwon, 관리자/운영자는 테스트용
//
//			if(LANGUAGE_TYPE_VIETNAMESE != g_pFieldGlobal->GetLanguageType())
//			{// 2006-11-17 by cmkwon, 일반 유저는 베트남에서 사용 가능
//				return FALSE;
//			}
//		}

		// 2008-03-28 by cmkwon, 관리자만 PlayTime 설정도 가능하게 수정
		token = strtok(NULL, seps);
		if(token
			&& CheckCommandExecutability(RACE_OPERATION))
		{
			int nSetContinueTimeSec = atoi(token);
			if(IS_IN_RANGE(0, nSetContinueTimeSec, 86400))		// 86400초 = 24시간
			{
				this->GPInitGameStartTime();			// 계산기준시간 초기화
				this->m_nGameContinueTimeInSecondOfToday		= nSetContinueTimeSec;	// 오늘 진행시간 설정
				this->m_nGameContinueTimeInSecondOfToday4Viet	= nSetContinueTimeSec;	// 오늘 진행시간 설정
			}
		}

		char szTemp[1024];
		this->GetPlayTimeInfoString(szTemp);

		this->SendString128(STRING_128_USER_NOTICE, "Playtime: %s", szTemp);
		return TRUE;
	}
	//////////////////////////////////////////////////////////////////////////
	// 2007-02-15 by dhjin, 클라이언트에서 처리
	//	else if(0 == stricmp(token, STRCMD_CS_COMMAND_SUBLEADER_0)
	//		|| 0 == stricmp(token, STRCMD_CS_COMMAND_SUBLEADER_1))
	//	{// 2007-02-13 by dhjin, format: /부지도자 [CharacterName] - 부지도자 설정
	//		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_INFLUENCE_LEADER))
	//		{// 관리자, 세력지도자 사용 가능 명령어
	//			return FALSE;
	//		}
	//		
	//		token = strtok(NULL, seps);
	//		if(NULL == token)
	//		{
	//			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_SUBLEADER_HELP);
	//			return TRUE;
	//		}		
	//		
	//		return TRUE;
	//	}

	else if(0 == stricmp(token, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_1))
	{// 2007-02-23 by dhjin, format: /거점정보 - 현재 거점 진행 정보를 보여준다

		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		if(ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.empty())
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_EMPTY);
		}
		else
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_EXIST);
		
			mt_auto_lock mtA(&(ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo));	// 2007-10-08 by cmkwon, lock 필요

			mtvectorSSUMMON_STRATEGYPOINT_INFO::iterator	itr = ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.begin();
			while(itr != ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.end())
			{
				this->SendString128(STRING_128_USER_NOTICE, "%s  :  %s(%d)"
									, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_ZONE, itr->MapName, itr->MapIndex);
				this->SendString128(STRING_128_USER_NOTICE, "%s  :  %s"
									, STRCMD_CS_COMMAND_STRATEGYPOINTINFO_STARTTIME, itr->SummonStrategyPointTime.GetDateTimeString(STRNBUF(SIZE_MAX_SQL_DATETIME_STRING), TRUE));
				itr++;
			}
		}
		
		return TRUE;
	}
	
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_OBSERVER_REG_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_OBSERVER_REG_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_OBSERVER_REG_HELP);
			return TRUE;
		}

		int nRegNum = atoi(token);
		
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_OBSERVER_REG_HELP);
			return FALSE;
		}

		CFieldIOCPSocket *pOTFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
		if (NULL == pOTFISoc)
		{
			SendString128(STRING_128_ADMIN_CMD, "%s NOT PLAYING", token);
			return TRUE;		// 필드 서버로 추가 전송 필요 없음
		}

		if(this == pOTFISoc)
		{
			this->SendString128(STRING_128_USER_NOTICE, "Cann't myself");
			return FALSE;
		}

		if(FALSE == this->ObserverTargetCharacterCheck(pOTFISoc))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid Character !!");
			return FALSE;
		}

		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_OBSERVER_REG, T_FC_CHARACTER_OBSERVER_REG, pMsg, SendBuf);
		pMsg->ClientIndex	=	pOTFISoc->GetCharacter()->ClientIndex;
		pMsg->nRegNum		=	nRegNum;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_OBSERVER_REG));
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_JAMBOREE_INIT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_JAMBOREE_INIT_1))
	{// 2007-04-10 by cmkwon
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 관리자만 사용 가능
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-10 by cmkwon, "format: /InitJamboree [인증숫자] - 대회서버군 DB(atum2_db_20)를 초기화 한다."

		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_JAMBOREE_INIT_HELP);
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070410_0000);
			return TRUE;
		}

		int nVerifyNumber = atoi(token);

		if(0 == ms_pFieldIOCP->m_nJamboreeInitCommandVerifyNumber
			||  nVerifyNumber != ms_pFieldIOCP->m_nJamboreeInitCommandVerifyNumber)
		{
			ms_pFieldIOCP->m_nJamboreeInitCommandVerifyNumber = RANDI(1000, 10000);
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070410_0000);
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070410_0001, ms_pFieldIOCP->m_nJamboreeInitCommandVerifyNumber);
			return TRUE;
		}
		ms_pFieldIOCP->m_nJamboreeInitCommandVerifyNumber = 0;

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-10 by cmkwon, 시스템 로그 남기기
		char szSysLog[1024];
		sprintf(szSysLog, "[Notify]: Jamboree DB Server Init, Admin[%s]\r\n", GetCharacterString(GetCharacter(), string()));
		g_pFieldGlobal->WriteSystemLog(szSysLog);
		DbgOut(szSysLog);

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-10 by cmkwon, 초기화 프로시저 호출
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_JamboreeInit, this, m_character.AccountUniqueNumber, NULL);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_JAMBOREE_ENTRANTS_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_JAMBOREE_ENTRANTS_1))
	{// 2007-04-10 by cmkwon
		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 관리자만 사용 가능
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-10 by cmkwon, "format: /EntrantJamboree [CharacterName] - 지정한 캐릭터의 데이터를 대회서버군 DB(atum2_db_20)으로 복사한다."
		// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - "format: /EntrantJamboree [CharacterName] [1(Normal)|2(BCU)|4(ANI)] - 지정한 캐릭터의 데이터를 대회서버군 DB(atum2_db_20)의 해당 세력으로 복사한다."
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_JAMBOREE_ENTRANTS_HELP);
			return TRUE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - "/대회서버참가자" 명령어 형식 수정
		char szCharName[SIZE_MAX_CHARACTER_NAME];
		STRNCPY_MEMSET(szCharName, token, SIZE_MAX_CHARACTER_NAME);

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_JAMBOREE_ENTRANTS_HELP);
			return TRUE;
		}
		BYTE byInflTy = (BYTE)(atoi(token));
		if(FALSE == IS_VALID_INFLUENCE_TYPE(byInflTy))
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_JAMBOREE_ENTRANTS_HELP);
			return TRUE;
		}


// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 아래와 같이 수정 함
// 		QPARAM_JAMBOREE_ENTRANTS *pQPEntrants = new QPARAM_JAMBOREE_ENTRANTS;
// 		STRNCPY_MEMSET(pQPEntrants->szCharName0, token, SIZE_MAX_CHARACTER_NAME);
// 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_JamboreeEntrants, this, m_character.AccountUniqueNumber, pQPEntrants);
 		QPARAM_JAMBOREE_ENTRANTS *pQPEntrants = new QPARAM_JAMBOREE_ENTRANTS;
 		STRNCPY_MEMSET(pQPEntrants->szCharName0, szCharName, SIZE_MAX_CHARACTER_NAME);
 		pQPEntrants->byInflTy	= byInflTy;											// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 세력지정 추가
 		pQPEntrants->MapIndex	= CAtumSJ::GetCityMapIndexByInfluence(byInflTy);	// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 도시맵 지정 추가
 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_JamboreeEntrants, this, m_character.AccountUniqueNumber, pQPEntrants);		
		return TRUE;
	}
	else if(0 == stricmp(token, STRMSG_CS_COMMAND_ARENA_TEAM_INFO_0)
		|| 0 == stricmp(token, STRMSG_CS_COMMAND_ARENA_TEAM_INFO_1))
	{// 2007-05-23 by dhjin, format: /아레나 - 현재 아레나 진행 정보를 보여준다.

		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_CS_COMMAND_ARENA_TEAM_INFO_HELP);
			return TRUE;
		}

		BYTE byInfl = atoi(token);
		if(INFLUENCE_TYPE_VCN == byInfl || INFLUENCE_TYPE_ANI == byInfl)
		{// 2007-05-25 by dhjin, 알링턴과 바이제니유 세력만
			this->ms_pFieldIOCP->m_ArenaManager.SendArenaTeamInfoByGMCommand(this, byInfl);
			return TRUE;
		}
		
		this->SendString128(STRING_128_USER_NOTICE, STRMSG_CS_COMMAND_ARENA_TEAM_INFO_HELP);
		return TRUE;
	}
	else if(0 == stricmp(token, STRMSG_CS_COMMAND_WATCH_START_INFO_0)
		|| 0 == stricmp(token, STRMSG_CS_COMMAND_WATCH_START_INFO_1))
	{// 2007-06-15 by dhjin, format: /관전시작 - 관전을 시작한다.

		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
		{// 2007-06-20 by dhjin, 일반 세력은 불가
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070620_0000);
			return RES_BREAK;
		}

		if(FALSE == this->IsInvisibleCharacter())
		{// 2007-06-15 by dhjin, 투명상태에서만 가능
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070615_0000);
			return FALSE;
		}


#ifdef S_ARENA_NOT_INFO
		//////////////////////////////////////////////////////////////////////////
		// 2007-06-21 by dhjin, 아레나 상태이면 할 수 없다.
		// 		if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
		// 		{
		// 			return FALSE;
		// 		}
#else
		if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
		{
			return FALSE;
		}
#endif




		if(FALSE == IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{// 2007-06-18 by dhjin, 아레나 맵에서만 가능
			return FALSE;
		}
		
		//////////////////////////////////////////////////////////////////////////
		// 2007-06-18 by dhjin, 관전 준비
		this->WatchReady();
		
		return TRUE;
	}
	else if(0 == stricmp(token, STRMSG_CS_COMMAND_WATCH_END_INFO_0)
		|| 0 == stricmp(token, STRMSG_CS_COMMAND_WATCH_END_INFO_1))
	{// 2007-06-15 by dhjin, format: /관전종료 - 관전을 종료한다.

		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		if(FALSE == this->IsInvisibleCharacter())
		{// 2007-06-15 by dhjin, 투명상태에서만 가능
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070615_0000);
			return FALSE;
		}

		if(FALSE == IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{// 2007-06-18 by dhjin, 아레나 맵에서만 가능
			return FALSE;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-06-18 by dhjin, 관전 종료
		this->WatchEnd();

		return TRUE;
	}	
	else if(0 == stricmp(token, STRMSG_CS_COMMAND_WARPOINT_0)
		|| 0 == stricmp(token, STRMSG_CS_COMMAND_WARPOINT_1))
	{// 2007-06-22 by dhjin, format: /전쟁포인트 [개수 1~1000000] [유저이름] - 전쟁포인트를 추가한다.

		if ( !CheckCommandExecutability(RACE_OPERATION) )
		{// 2007-11-08 by cmkwon, GM 명령어 정리 - '/전쟁포인트' 운영자 사용 불가, // 관리자/운영자만 사용 가능
			return FALSE;
		}
		
		token = strtok(NULL, seps);
		if (token == NULL)
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_CS_COMMAND_WARPOINT_HELP);
			return TRUE;
		}
		
		int	count = atoi(token);
		if(0 >= count 
			|| 1000000 <= count)
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_CS_COMMAND_WARPOINT_HELP);
			return TRUE;
		}

		CFieldIOCPSocket *pFISoc = this;
		token = strtok(NULL, seps);
		if (token != NULL)
		{
			pFISoc = this->ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if (NULL == pFISoc
				|| FALSE == pFISoc->IsValidCharacter())
			{
				SendString128(STRING_128_ADMIN_CMD, "%s NOT PLAYING", token);
				return TRUE;
			}
		}
		
		pFISoc->m_character.WarPoint += count;
		pFISoc->m_character.CumulativeWarPoint += count;
		
		// start 2012-01-16 by hskim, 통계 - 화패
		// 관리자 명령은 제외 
		//if( NULL != this->ms_pFieldIOCP->m_pStatisticsManager )
		//{
		//	this->ms_pFieldIOCP->m_pStatisticsManager->Add(STATISTICS_WAR_POINT, count);
		//}
		// end 2012-01-16 by hskim, 통계 - 화패

		// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CAtumLogSender::SendLogMessageGetWarPoint()에 인자(, BYTE i_byWPUpdateTy) 추가
		CAtumLogSender::SendLogMessageGetWarPoint(pFISoc, count, pFISoc->m_character.WarPoint, pFISoc->m_character.CumulativeWarPoint, WPUT_ADMIN_COMMAND);
		// 2007-05-16 by dhjin, DB에 업데이트
		QPARAM_UPDATE_WARPOINT *pQparam = new QPARAM_UPDATE_WARPOINT;
		pQparam->CharacterUID		= pFISoc->m_character.CharacterUniqueNumber;
		pQparam->AccountUID			= pFISoc->m_character.AccountUniqueNumber;
		pQparam->TotalWarPoint		= pFISoc->m_character.WarPoint;
		pQparam->CumulativeWarPoint	= pFISoc->m_character.CumulativeWarPoint;
		this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateWarPoint, pFISoc, pFISoc->m_character.AccountUniqueNumber, pQparam);

		// 2007-05-16 by dhjin, 클라이언트에게 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_PAY_WARPOINT, T_FC_CHARACTER_PAY_WARPOINT, pMsg, SendBuf);
		pMsg->WarPoint				= count;
		pMsg->TotalWarPoint			= pFISoc->m_character.WarPoint;
		pMsg->CumulativeWarPoint	= pFISoc->m_character.CumulativeWarPoint;
		pMsg->UseItemFlag			= FALSE;		// 2010-08-27 by shcho&&jskim, WARPOINT 증가 아이템 구현 - 아이템 사용 구분자
		pFISoc->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_PAY_WARPOINT));

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBID_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBID_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBID_2))
	{// 2007-07-11 by cmkwon, 아레나블럭 시스템 구현 - 아레나금지 명령어 추가
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		// 2008-02-21 by dhjin, 아레나 통합 - 아레나 서버에서 사용 불가
		if(g_pFieldGlobal->IsArenaServer())
		{
			return FALSE;
		}	
		
		// "format: /아레나금지 [character name] [시간(분)] - Arena 금지 시킴"
		token = strtok(NULL, seps);
		if (NULL == token)
		{// CharacterName 이 없음
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ARENAFORBID_HELP);
			return TRUE;
		}

		char szCharName[SIZE_MAX_CHARACTER_NAME];
		STRNCPY_MEMSET(szCharName, token, SIZE_MAX_CHARACTER_NAME);

		token = strtok(NULL, seps);
		if(NULL == token)
		{// 캐릭터 아레나블럭 정보를 전송한다
			
			int nRemainMinute = 0;
			if(FALSE == ms_pFieldIOCP->m_arenaBlockManager.IsExistChatBlockList(&nRemainMinute, szCharName))
			{
				this->SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0000, szCharName);
			}
			else
			{
				this->SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0001, szCharName, nRemainMinute);
			}
			return TRUE;
		}

		int  nMinutes = max(1, atoi(token));
		CFieldIOCPSocket *pFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(szCharName);
		if(pFISock
			&& pFISock->IsValidCharacter(FALSE))
		{
			pFISock->SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0002, nMinutes);
		}
		SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0001, szCharName, nMinutes);
		ms_pFieldIOCP->m_arenaBlockManager.InsertChatBlockList(szCharName, nMinutes);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBIDRelease_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBIDRelease_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAFORBIDRelease_2))
	{// 2007-07-11 by cmkwon, 아레나블럭 시스템 구현 - 아레나금지해제 명령어 추가
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}

		// 2008-02-21 by dhjin, 아레나 통합 - 아레나 서버에서 사용 불가
		if(g_pFieldGlobal->IsArenaServer())
		{
			return FALSE;
		}
		
		// "format: /아레나금지해제 [character name] - Arena 금지 해제 시킴"
		token = strtok(NULL, seps);
		if (NULL == token)
		{// CharacterName 이 없음
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_ARENAFORBIDRelease_HELP);
			return TRUE;
		}

		CFieldIOCPSocket *pFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
		if(pFISock
			&& pFISock->IsValidCharacter(FALSE))
		{
			pFISock->SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0003);
		}

		SendString128(STRING_128_USER_NOTICE, STRMSG_070711_0004, token);
		ms_pFieldIOCP->m_arenaBlockManager.DeleteChatBlockList(token);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_UsableSpeakerItem_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_UsableSpeakerItem_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_UsableSpeakerItem_2))
	{// 2007-08-24 by cmkwon, 스피커아이템 사용 가능/금지 설정 기능 추가 - 명령어 처리
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{// 관리자/운영자만 사용 가능
			return FALSE;
		}
		
		// "format: /스피커사용 [가능|금지] - 스피커아이템 사용을 금지/해제 시킴"
		token = strtok(NULL, seps);
		if (NULL == token)
		{// 첫번째 인자가 없음
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_UsableSpeakerItem_HELP);
			return TRUE;
		}

		BOOL	bUnusableFlag	= FALSE;
		if(0 == stricmp(token, STRCMD_CS_COMMAND_UsableSpeakerItem_P1Able))
		{
			bUnusableFlag		= FALSE;		// 사용 가능
		}
		else if(0 == stricmp(token, STRCMD_CS_COMMAND_UsableSpeakerItem_P1Forbid))
		{
			bUnusableFlag		= TRUE;			// 사용 불가
		}
		else
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_UsableSpeakerItem_HELP);
			return TRUE;
		}

		ms_pFieldIOCP->SetUnusableSpeakerItem(bUnusableFlag);		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermission_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermission_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermission_2))
	{// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 명령어 추가
		
		if (FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
		{// 지도자만 사용 가능

			if(FALSE == CheckCommandExecutability(RACE_OPERATION))
			{// 관리자는 가능
				return FALSE;
			}

			if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
			{// 일반세력은 불가
				SendString128(STRING_128_ADMIN_CMD, STRMSG_070830_0001);
				return FALSE;
			}
		}
		int					nConferenceRoomMapIndex = CFieldMapProject::GetConferenceRoomMapIndex(m_character.InfluenceType);
		CFieldMapProject	*pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nConferenceRoomMapIndex);
		if(NULL == pFMPro)
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070830_0002, nConferenceRoomMapIndex);
			return FALSE;
		}
		
		// "format: /[입장허가] [|CharacterName] - 지도자만 사용 가능, 해당 캐릭터를 회의룸 입장 허가 리스트에 추가 한다."
		token = strtok(NULL, seps);
		if (NULL == token)
		{// CharacterName 이 없음
			
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_EntrancePermission_HELP);
			pFMPro->SendWarpableUserList(this);
			return TRUE;
		}

		S_S1_CHARACTER_INFO s1CharInfo;		MEMSET_ZERO(&s1CharInfo, sizeof(s1CharInfo));
		if(pFMPro->FindInWarpableUserListByCharacterName(&s1CharInfo, token))
		{
			SendString128(STRING_128_ADMIN_CMD, STRMSG_070830_0004, token);
			return TRUE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 추가 쿼리
		QPARAM_Insert2WarpableUserList *pQParam	= new QPARAM_Insert2WarpableUserList;
		pQParam->MapIndex				= nConferenceRoomMapIndex;
		pQParam->byInfluenceType0		= m_character.InfluenceType;
		STRNCPY_MEMSET(pQParam->CharacterName0, token, SIZE_MAX_CHARACTER_NAME);
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Insert2WarpableUserList, this, m_character.AccountUniqueNumber, pQParam);

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermissionDeny_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermissionDeny_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_EntrancePermissionDeny_2))
	{// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 명령어 추가
	
		if (FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
		{// 지도자만 사용 가능

			if(FALSE == CheckCommandExecutability(RACE_OPERATION))
			{// 관리자는 가능
				return FALSE;
			}

			if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
			{// 일반세력은 불가
				SendString128(STRING_128_ADMIN_CMD, STRMSG_070830_0001);
				return FALSE;
			}
		}
		int					nConferenceRoomMapIndex = CFieldMapProject::GetConferenceRoomMapIndex(m_character.InfluenceType);
		CFieldMapProject	*pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nConferenceRoomMapIndex);
		if(NULL == pFMPro)
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_070830_0002, nConferenceRoomMapIndex);
			return FALSE;
		}

		// "format: /[입장불가] [|CharacterName] - 지도자만 사용 가능, 해당 캐릭터를 회의룸 입장 허가 리스트에서 삭제 한다."
		token = strtok(NULL, seps);
		if (NULL == token)
		{// CharacterName 이 없음
			SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_EntrancePermissionDeny_HELP);
			return TRUE;
		}

		S_S1_CHARACTER_INFO s1CharInfo;		MEMSET_ZERO(&s1CharInfo, sizeof(s1CharInfo));
		if(FALSE == pFMPro->PopInWarpableUserListByCharacterName(&s1CharInfo, token))
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_070830_0005, token);
			return TRUE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-08-31 by cmkwon
		CFieldIOCPSocket *pTargetFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(s1CharInfo.CharacterUID1);
		if(pTargetFISoc
			&& pTargetFISoc->IsValidCharacter(FALSE))
		{
			pTargetFISoc->SendString128(STRING_128_USER_NOTICE, STRMSG_070830_0010);

			if(IS_CONFERENCEROOM_MAP_INDEX(pTargetFISoc->GetCharacter()->MapChannelIndex.MapIndex))
			{// 현재 회의룸맵에 있을경우
				CFieldMapProject *pCityFMPro = this->GetCityFieldMapProjectPtr();
				if(pCityFMPro
					&& ERR_NO_ERROR == pTargetFISoc->IsEnableWarp(pCityFMPro->GetMapInfluenceType(), FALSE))
				{
					pTargetFISoc->WarpToCityMap();
				}
			}
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 삭제 쿼리 
		QPARAM_DeleteWarpableUser *pQParam	= new QPARAM_DeleteWarpableUser;
		pQParam->MapIndex				= nConferenceRoomMapIndex;
		pQParam->CharacterUID0			= s1CharInfo.CharacterUID1;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteWarpableUser, this, m_character.AccountUniqueNumber, pQParam);
		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_WAPPOINTINMAP_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_WAPPOINTINMAP_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_WAPPOINTINMAP_2))
	{// 2007-11-05 by cmkwon, WP 지급 명령어 구현 - 명령어 처리 구현

		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2007-11-05 by cmkwon, WP 지급 명령어 구현 - 관리자만 허용하도록 구현
			return TRUE;
		}

		// 2008-02-21 by dhjin, 아레나 통합 - 아레나 서버에서 사용 불가
		if(g_pFieldGlobal->IsArenaServer())
		{
			return FALSE;
		}

		// "format: /AddWarPointInMap [1(Normal)|2(VCN)|4(ANI)|3|5|6|7] [AddWarPoint(1~)] - 현재맵의 지정한 세력 유저에게 WarPoint를 지급한다."
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_WAPPOINTINMAP_HELP);
			return FALSE;
		}

		BYTE byInflTyMask = (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(byInflTyMask, INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid IfluenceTypeMask !!");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_WAPPOINTINMAP_HELP);
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "WarPoint error !!");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_WAPPOINTINMAP_HELP);
			return FALSE;
		}

		int nAddWarPoint = atoi(token);
		if(0 >= nAddWarPoint)
		{
			this->SendString128(STRING_128_USER_NOTICE, "WarPoint error !!");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_WAPPOINTINMAP_HELP);
			return FALSE;			
		}
		
		// 2007-11-05 by cmkwon, WP 지급 명령어 구현 - 현재맵의 해당 세력 유저들에게 WarPoint를 지급한다.
		GetCurrentFieldMapChannel()->AddWarPointInMap(nAddWarPoint, FALSE, byInflTyMask, WPUT_ADMIN_COMMAND);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_2))
	{// 2008-01-31 by cmkwon, 계정 블럭/해제 명령어로 가능한 시스템 구현 - 

		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-01-31 by cmkwon, 관리자/운영자 사용 가능
			return TRUE;
		}

		// "format: /Block [AccountName] [BlockType(1:Normal|2:Related Money|3:Related Item|4:Related SpeedHack|5:Related Chatting|6:Related GameBug)] [Period:Days] [Block Reason for User] / [Block Reason for only Admin]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}

		SBLOCKED_ACCOUNT_INFO blockedAccInfo;
		MEMSET_ZERO(&blockedAccInfo, sizeof(SBLOCKED_ACCOUNT_INFO));

		blockedAccInfo.AdminFieldServerClientIndex	= GetCharacter()->ClientIndex;
		STRNCPY_MEMSET(blockedAccInfo.szBlockAdminAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);		// 2008-01-31 by cmkwon, 관리자 AccountName

#if defined _DEFINED_GAMEFORGE4D_
		// Start 2012-01-03 by shcho, 블럭 명령도 소문자로 변경한다. - 게임포지 블럭유저 블럭시, 대소문자 구분으로 다음접속시에 블럭 안되는 문제 처리
		_strlwr(token);
		// End 2012-01-03 by shcho, 블럭 명령도 소문자로 변경한다. - 게임포지 블럭유저 블럭시, 대소문자 구분으로 다음접속시에 블럭 안되는 문제 처리
		STRNCPY_MEMSET(blockedAccInfo.szBlockedAccountName, token, SIZE_MAX_ACCOUNT_NAME);							// 2008-01-31 by cmkwon, 블럭시킬 유저의 AccountName		
#else
		// 2008-01-31 by cmkwon, [AccountName]
		STRNCPY_MEMSET(blockedAccInfo.szBlockedAccountName, token, SIZE_MAX_ACCOUNT_NAME);							// 2008-01-31 by cmkwon, 블럭시킬 유저의 AccountName
#endif


		// 2008-01-31 by cmkwon, [BlockType(1:Normal|2:Related Money|3:Related Item|4:Related SpeedHack|5:Related Chatting|6:Related GameBug)]
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}
		blockedAccInfo.enBlockedType = (EN_BLOCKED_TYPE)atoi(token);
		if(FALSE == IS_IN_RANGE(T_BLOCKEDACCOUNT_NORMAL, blockedAccInfo.enBlockedType, T_BLOCKEDACCOUNT_CHAT_GAMEBUG))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid BlockType !!");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}

		// 2008-01-31 by cmkwon, [Period:Days]
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}
		int nPeriodOfDay = atoi(token);
		if(0 >= nPeriodOfDay)
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid Period !!");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}
		blockedAccInfo.atimeStartTime.SetCurrentDateTime();
		blockedAccInfo.atimeEndTime	= blockedAccInfo.atimeStartTime;
		blockedAccInfo.atimeEndTime.AddDateTime(0, 0, nPeriodOfDay);

		// 2008-01-31 by cmkwon, [Block Reason for User] /
		token = strtok(NULL, "/");
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}
		STRNCPY_MEMSET(blockedAccInfo.szBlockedReasonForUser, token, SIZE_MAX_BLOCKED_ACCOUNT_REASON);

		// 2008-01-31 by cmkwon, [Block Reason for only Admin]
		token = strtok(NULL, "/");
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTBLOCK_HELP);
			return FALSE;
		}
		STRNCPY_MEMSET(blockedAccInfo.szBlockedReasonForOnlyAdmin, token, SIZE_MAX_BLOCKED_ACCOUNT_REASON);

		INIT_MSG_WITH_BUFFER(MSG_FP_ADMIN_BLOCKACCOUNT, T_FP_ADMIN_BLOCKACCOUNT, pBlockAcc, SendBuf);
		pBlockAcc->blockAccInfo	= blockedAccInfo;
		ms_pFieldIOCP->Send2PreServerW(SendBuf, MSG_SIZE(MSG_FP_ADMIN_BLOCKACCOUNT));		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTUNBLOCK_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTUNBLOCK_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_NEWACCOUNTUNBLOCK_2))
	{// 2008-01-31 by cmkwon, 계정 블럭/해제 명령어로 가능한 시스템 구현 - 

		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-01-31 by cmkwon, 관리자/운영자 사용 가능
			return TRUE;
		}

		// "format: /Unblock [AccountName]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_NEWACCOUNTUNBLOCK_HELP);
			return FALSE;
		}

		SBLOCKED_ACCOUNT_INFO blockedAccInfo;
		MEMSET_ZERO(&blockedAccInfo, sizeof(SBLOCKED_ACCOUNT_INFO));

		blockedAccInfo.AdminFieldServerClientIndex	= GetCharacter()->ClientIndex;
		STRNCPY_MEMSET(blockedAccInfo.szBlockAdminAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);		// 2008-01-31 by cmkwon, 관리자 AccountName
		// 2008-01-31 by cmkwon, [AccountName]
		STRNCPY_MEMSET(blockedAccInfo.szBlockedAccountName, token, SIZE_MAX_ACCOUNT_NAME);							// 2008-01-31 by cmkwon, 블럭시킬 유저의 AccountName
		blockedAccInfo.atimeStartTime.SetCurrentDateTime();
		blockedAccInfo.atimeEndTime	= blockedAccInfo.atimeStartTime;

		INIT_MSG_WITH_BUFFER(MSG_FP_ADMIN_UNBLOCKACCOUNT, T_FP_ADMIN_UNBLOCKACCOUNT, pUnblockAcc, SendBuf);
		pUnblockAcc->blockAccInfo	= blockedAccInfo;
		ms_pFieldIOCP->Send2PreServerW(SendBuf, MSG_SIZE(MSG_FP_ADMIN_UNBLOCKACCOUNT));		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ITEMALLUSER_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMALLUSER_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ITEMALLUSER_2))
	{// 2008-02-20 by cmkwon, 명령어 추가(접속 중인 유저 모두에게 아이템 지급 - 

		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2008-01-31 by cmkwon, 관리자만 사용 가능
			return TRUE;
		}

		// "format: /ItemAllUser [1(Normal)|2(VCN)|4(ANI)|255(All)] [Item Number] [# of items] - 접속한 유저들중에 지정한 세력 유저에게 지정한 아이템을 지급한다"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;
		}

		BYTE byInflTyMask = (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(byInflTyMask, INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid IfluenceTypeMask");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "ItemNum error");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;
		}

		int nInsertItemNum = atoi(token);
		if(NULL == ms_pFieldIOCP->GetItemInfo(nInsertItemNum))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ItemNum");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;			
		}

		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, "ItemCount error");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;
		}

		int nInsertItemCnts = atoi(token);
		if(0 >= nInsertItemCnts)
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ItemCount");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ITEMALLUSER_HELP);
			return FALSE;
		}
		
		ms_pFieldIOCP->InsertItemAllCharacter(nInsertItemNum, nInsertItemCnts, byInflTyMask);
		return TRUE;
	}
	//////////////////////////////////////////////////////////////////////////
	// 2008-03-10 by dhjin, 아레나 통합 - 명령어 추가
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_TEAMARENALEAVE_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_TEAMARENALEAVE_1))
	{
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ArenaServer");
			return FALSE;
		}

		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}

		// "format: /ArenaLeave [2(BLUE)|4(RED)|6(BLUE AND RED)]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TEAMARENALEAVE_HELP);
			return FALSE;
		}
		
		BYTE byInflTyMask = (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(byInflTyMask, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid IfluenceTypeMask");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TEAMARENALEAVE_HELP);
			return FALSE;
		}		
	
		GetCurrentFieldMapChannel()->TeamArenaLeaveCommand(byInflTyMask);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_TARGETARENALEAVE_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_TARGETARENALEAVE_1))
	{
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ArenaServer");
			return FALSE;
		}

		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}

		// "format: /TargetArenaLeave [Charactername]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TEAMARENALEAVE_HELP);
			return FALSE;
		}
		
		CFieldIOCPSocket *pFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
		if(NULL == pFISock
			|| FALSE == pFISock->IsValidCharacter(FALSE))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid CharacterName");
			return FALSE;			
		}		

		pFISock->SendAddMessageType(T_FC_ARENA_USE_CITYWARPITEM);

		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENT_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENT_2))
	{ 
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ArenaServer");
			return FALSE;
		}
			
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}

		// "format: /ArenaEvent [RoomNumber]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ARENAEVENT_HELP);
			return FALSE;
		}
		
		int Roomnum = atoi(token);
		if(!ms_pFieldIOCP->m_ArenaManager.SetTeamEventW(Roomnum,TRUE))
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_ARENAEVENT_080310_0003);
			return FALSE;			
		}
		
		this->SendString128(STRING_128_USER_NOTICE, STRMSG_ARENAEVENT_080310_0001, Roomnum);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENTRELEASE_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENTRELEASE_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ARENAEVENTRELEASE_2))
	{ 
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid ArenaServer");
			return FALSE;
		}
			
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}

		// "format: /ArenaEvent [RoomNumber]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ARENAEVENTRELEASE_HELP);
			return FALSE;
		}
		
		int Roomnum = atoi(token);
		if(!ms_pFieldIOCP->m_ArenaManager.SetTeamEventW(Roomnum,FALSE))
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_ARENAEVENT_080310_0003);
			return FALSE;			
		}
		
		this->SendString128(STRING_128_USER_NOTICE, STRMSG_ARENAEVENT_080310_0002, Roomnum);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENT_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENT_2))
	{// 2008-08-18 by dhjin, 세력마크이벤트
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}

		// "format: /influencemarkevent [세력 2(BCU)|4(ANI)]"
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_INFLUENCEMARKEVENT_HELP);
			return FALSE;
		}
		
		BYTE byInflTyMask = (BYTE)atoi(token);
		if(FALSE == COMPARE_INFLUENCE(byInflTyMask, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Invalid IfluenceTypeMask");
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_INFLUENCEMARKEVENT_HELP);
			return FALSE;
		}	

		INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_INFLUENCEMARK, T_FC_EVENT_INFLUENCEMARK, pSendMSG, SendBuf);
		pSendMSG->Influence	= byInflTyMask;
		this->ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_EVENT_INFLUENCEMARK), INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);
		
		return TRUE;		
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENTEND_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENTEND_1)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_INFLUENCEMARKEVENTEND_2))
	{// 2008-08-18 by dhjin, 세력마크이벤트 
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2008-03-10 by dhjin, 관리자, 운영자 사용 가능 
			return TRUE;
		}
		
		MessageType_t msgTy = T_FC_EVENT_INFLUENCEMARKEND;
		this->ms_pFieldIOCP->SendMessageToAllClients((BYTE*)&msgTy, SIZE_FIELD_TYPE_HEADER, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);
		
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_PCBANGRELOADTIME_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_PCBANGRELOADTIME_1))
	{// 2008-08-25 by dhjin, 태국 PC방 IP정보 로딩 
		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2008-08-25 by dhjin, 관리자 사용 가능 
			return TRUE;
		}
		
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_PCBANGRELOADTIME_HELP);
			return FALSE;
		}
		
		int PCBangMinTick = atoi(token);		

		if(MinPCBangMinTick > PCBangMinTick
			|| MaxPCBangMinTick < PCBangMinTick)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_PCBANGRELOADTIME_HELP);
			return FALSE;
		}

		this->ms_pFieldIOCP->m_nMaxPCBangMinTick = PCBangMinTick;
				
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_KICK_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_KICK_1))
	{// 2008-09-09 by cmkwon, "/kick" 명령어 추가 - 
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR, TRUE))
		{// 2008-09-09 by cmkwon, 관리자, 운영자, 모니터, AdminTool
			return TRUE;
		}
		
		// "format: /Kick [CharacterName] - 해당 캐릭터를 게임에서 종료 시킨다."
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_KICK_HELP);
			return FALSE;
		}
		
		CFieldIOCPSocket *pTargetFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
		if(NULL == pTargetFISoc
			|| FALSE == pTargetFISoc->IsValidCharacter(FALSE))
		{
			this->SendString128(STRING_128_USER_NOTICE, "Character(%s) is offline or invalid CharacterName !!", token);
			return FALSE;
		}
		
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] kicked %s by %s \r\n", GetCharacterString(pTargetFISoc->GetCharacter(), string()), GetCharacterString(this->GetCharacter(), string()));
		pTargetFISoc->Close(0x14070);
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_ADD_FAME_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_ADD_FAME_1))
	{// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 
		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2008-09-09 by cmkwon, 관리자
			return TRUE;
		}
		
		// "format: /명성 [개인명성] [여단명성] - 접속 캐릭터의 명성, 캐릭터 여단 명성을 올려준다."
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ADD_FAME_HELP);
			return FALSE;
		}
		
		int nAddCharacFame = atoi(token);
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_ADD_FAME_HELP);
			return FALSE;
		}
		int nAddGuildFame = atoi(token);

		this->AddCharacterFame(nAddCharacFame, nAddGuildFame);		// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 
		return TRUE;
	}
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_CHANGE_StartCityMapIndex_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_CHANGE_StartCityMapIndex_1))
	{// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::HandleAdminCommands#, 명령어 처리 추가
		if(FALSE == CheckCommandExecutability(RACE_OPERATION))
		{// 2009-10-15 by cmkwon, 관리자만 사용 가능
			return FALSE;
		}
		
		// "format: /시작도시맵 [2001|2002] [|CharacterName] - 해당 캐릭터의 일반세력시 시작도시맵을 해당 맵으로 변경한다."
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CHANGE_StartCityMapIndex_HELP);
			return FALSE;
		}
		
		int nStartCityMapIdx = atoi(token);
		if(FALSE == IS_VCN_CITY_MAP_INDEX(nStartCityMapIdx)
			&& FALSE == IS_ANI_CITY_MAP_INDEX(nStartCityMapIdx))
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_CHANGE_StartCityMapIndex_HELP);
			return FALSE;
		}

		CFieldIOCPSocket *pTargetFISoc = this;
		token = strtok(NULL, seps);
		if(NULL != token)
		{
			pTargetFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if(NULL == pTargetFISoc
				|| FALSE == pTargetFISoc->IsValidCharacter(FALSE))
			{
				this->SendString128(STRING_128_USER_NOTICE, "Character(%s) is offline or invalid CharacterName !!", token);
				return FALSE;
			}
		}
		pTargetFISoc->m_character.Material	= nStartCityMapIdx;		
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeStartCityMapIndex, NULL, m_character.AccountUniqueNumber, NULL, NULL, pTargetFISoc->GetCharacter()->CharacterUniqueNumber, nStartCityMapIdx);
		return TRUE;
	}
	// 2010. 06. 04 by hsLee 인티피니 필드 2차 난이도 조절. (GM 명령어 추가. /nextscene(다음 시네마 씬 호출.) )
	else if ( 0 == stricmp ( token , STRCMD_CS_COMMAND_INFINITY_NEXT_SCENE ) )
	{
		if ( FALSE == g_pFieldGlobal->IsArenaServer() )
			return FALSE;

		int nUpdateSceneCount = 0;

		token = strtok(NULL, seps);

		if(NULL != token)
			nUpdateSceneCount = atoi(token);
		
		ms_pFieldIOCP->m_InfinityManager.UpdateNextSceneProc ( this->m_InfinityPlayingInfo.ModeTypeNum , this->m_InfinityPlayingInfo.InfinityCreateUID , this , nUpdateSceneCount );
		
		return TRUE;
	}
	// End 2010. 06. 04 by hsLee 인티피니 필드 2차 난이도 조절. (GM 명령어 추가. /nextscene(다음 시네마 씬 호출.) )

	////////////////////////////////////////////////////////////////
	// 2011-06-22 by hskim 추가되는 명령어는 여기다가 추가하세요!!
	// ....	 요기 아래에 다가 넣으세요

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_RESETTRIGGER)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_RESETTRIGGER_1))
	{
		int iFunctionID = 0;
		if( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// "format: /리셋트리거 [트리거번호] - 진행되고 있는 트리거를 종료시키고 초기화 한다."
		token = strtok(NULL, seps);
		if(NULL != token)
		{
			iFunctionID = atoi(token);
			token = strtok(NULL, seps);
		}

		CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();

		if( NULL == pFMChann )
		{
			return FALSE;
		}

		if( 0 == iFunctionID )
		{
			ms_pFieldIOCP->m_pMapTriggerManager->SkipEventByMapChannelIndex(pFMChann->GetMapChannelIndex());
		}
		else
		{
			ms_pFieldIOCP->m_pMapTriggerManager->SkipEventByTriggerID(iFunctionID);
		}
		
		return TRUE;
	}
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	// start 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_TEST_MONSTER_DROPITEM)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_TEST_MONSTER_DROPITEM_1))
	{
		int MonsterIndex = 0;
		int TestCount = 10000;		// 기본 테스트 숫자 값
		if( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			// 운영자용, 일반 사용자는 무시
			return FALSE;
		}

		// "format: /테스트몬스터드랍 [monster number] [test numbers] - 몬스터 사냥시 드랍되는 아이템을 시뮬레이션해서 보여준다."
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			this->SendString128(STRING_128_USER_NOTICE, STRCMD_CS_COMMAND_TEST_MONSTER_DROPITEM_HELP);
			return FALSE;
		}

		MonsterIndex = atoi(token);

		token = strtok(NULL, seps);
		if(NULL != token)
		{
			TestCount = atoi(token);

			if( TestCount <= 0 )
			{
				return FALSE;
			}

			if( TestCount > 100000 )
			{
				return FALSE;
			}
		}

		return TestMonsterDropItems(MonsterIndex, TestCount);
	}
	// end 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어

	// ...
	////////////////////////////////////////////////////////////////

	// start 2011-06-22 by hskim, 사설 서버 방지
	else if ( 0 == stricmp ( token , STRCMD_CS_COMMAND_SERVERINFO ) )
	{
		this->SendString128(STRING_128_USER_NOTICE, "[%s %s] [%d]", __DATE__, __TIME__, g_pFieldGlobal->GetLanguageType());

		return TRUE;
	}
	// 2012-09-24 by jhseol, 아레나 종료 명령어 수정
	else if( 0 == stricmp( token , STRCMD_CS_COMMAND_ENDARENA ) )
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_DEMO|RACE_MONITOR) )
		{// 2008-09-09 by cmkwon, 모니터 권한 계정에 사용 권한 추가 - STRCMD_CS_COMMAND_MOVE, // 2006-04-13 by cmkwon, 관리자/운영자/DEMO만 사용 가능
			return FALSE;
		}
		
		if(TRUE == g_pFieldGlobal->IsArenaServer()) 
		{
			if( ARENA_STATE_FIGHTING_WARING == m_ArenaInfo.State )
			{
				CArenaDeathMatchRoom * tmArenaDMRoom = ms_pFieldIOCP->m_ArenaManager.GetArenaDeathMatchRoom(m_ArenaInfo.DeathMatchRoomNum);
				if( NULL != tmArenaDMRoom )
				{
					tmArenaDMRoom->ArenaFinish();
					SendString128(STRING_128_USER_NOTICE, "The command is complete. 'endarena'");
					return TRUE;
				}
			}
		}
		return FALSE;
	}
	// end 2012-09-24 by jhseol, 아레나 종료 명령어 수정
	// 2012-11-29 by jhseol, OX이벤트 맵 워프제한 - 명령어 추가
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_MAP_WARP_RESTRICT_0)
		|| 0 == stricmp(token, STRCMD_CS_COMMAND_MAP_WARP_RESTRICT_1))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}

		token = strtok(NULL, seps);
		if (NULL == token)
		{
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MAP_WARP_RESTRICT_HELP);
			return FALSE;
		}

		int MapIndex = atoi(token);

		switch( ms_pFieldIOCP->ReversalMapWarpPossible(MapIndex) )
		{
		case FALSE:
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MAP_WARP_RESTRICT_RESULT_0, MapIndex);
			break;
		case TRUE:
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MAP_WARP_RESTRICT_RESULT_1, MapIndex);
			break;
		default:
			SendString128(STRING_128_ADMIN_CMD, STRCMD_CS_COMMAND_MAP_WARP_ERROR, MapIndex);
			break;
		}
		return TRUE;
	}
	// end 2012-11-29 by jhseol, OX이벤트 맵 워프제한 - 명령어 추가
	// 2013-12-16 by jhseol, 역전의 기회 버프 리뉴얼 - 명령어 추가
#ifdef S_UPGRADE_INFLUENCE_POINT_RENEWAL_JHSEOL		// - 명령어 추가
	else if( 0 == stricmp(token, STRCMD_CS_COMMAND_RESET_REVERSAL_BUFF_TIME ))	// 2014-05-16 by bckim, 영문 명령어 추가		
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		ms_pFieldIOCP->m_InflWarManager.m_atBeforeTurnAroundBuffApplyTime.SetCurrentDateTime(TRUE);
		SendString128(STRING_128_ADMIN_CMD, "Time Reset Success.");
		return TRUE;
	}
// 2014-03-26 by jekim, 역전의 버프 전투력
	else if( 0 == stricmp(token, STRCMD_CS_COMMAND_RESET_REVERSAL_BUFF_STATE )) // 2014-05-16 by bckim, 영문 명령어 추가		
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		SendString128(STRING_128_ADMIN_CMD,"state : %d",ms_pFieldIOCP->m_InflWarManager.m_nBeforeContributionPointGap);		// 2014-05-16 by bckim, 영문 명령어 추가
		return TRUE;
	}
#ifdef SC_PVPBUFF_COMBAT_POWER_JEKIM_SSJUNG
	else if( 0 == stricmp(token, STRCMD_CS_COMMAND_RESET_REVERSAL_BUFF_EXECUTE ))	// 2014-05-16 by bckim, 영문 명령어 추가
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		SendString128(STRING_128_ADMIN_CMD,"Excute@");				// 2014-05-16 by bckim, 영문 명령어 추가
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PvpBuffUpdate, NULL, 0, NULL);
		return TRUE;
	}
	// 2014-04-10 by jekim, 역전의 버프 종료 명령어 추가
	else if( 0 == stricmp(token, STRCMD_CS_COMMAND_RESET_REVERSAL_BUFF_END ))	// 2014-05-16 by bckim, 영문 명령어 추가
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		ms_pFieldIOCP->m_InflWarManager.m_nBeforeContributionPointGap=0;
		ms_pFieldIOCP->DeleteBuffSkillAllCharacter(INFLUENCE_TYPE_VCN, DES_SKILLTYPE_TRUN_AROUND);
		ms_pFieldIOCP->DeleteBuffSkillAllCharacter(INFLUENCE_TYPE_ANI, DES_SKILLTYPE_TRUN_AROUND);
		SendString128(STRING_128_ADMIN_CMD,"END!!");			// 2014-05-16 by bckim, 영문 명령어 추가
		return TRUE;
	}
	// end 2014-04-10 by jekim, 역전의 버프 종료 명령어 추가
#endif
// end 2014-03-26 by jekim, 역전의 버프 전투력
#endif
	// 2013-12-16 by jhseol, 역전의 기회 버프 리뉴얼 - 명령어 추가

	// 2014-03-14 by jekim, 전투력 로그 추가 - 테스트용 명령어 추가
#ifdef S_COMBAT_POWER_LOGGING
	else if(0 == stricmp(token, STRCMD_CS_COMMAND_COMPAT_POWER ))	// 2014-05-16 by bckim, 영문 명령어 추가
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		CFieldIOCPSocket *pTargetFISoc;
		token = strtok(NULL, seps);
		if(NULL == token)
		{
			pTargetFISoc=this;
		}
		else
		{
			pTargetFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(token);
			if(NULL == pTargetFISoc
				|| FALSE == pTargetFISoc->IsValidCharacter(FALSE))
			{
				this->SendString128(STRING_128_USER_NOTICE, "Character(%s) is offline or invalid CharacterName !!", token);
				return FALSE;
			}
		}
		// 2014-11-24 by bckim, 해당 알림 문구 전국가 공용 번역
		//this->SendString128(STRING_128_USER_NOTICE, "%s의 전투력은 %d 입니다.", pTargetFISoc->m_character.CharacterName,pTargetFISoc->GetCombatPower());		
		this->SendString128(STRING_128_USER_NOTICE, "%s : combat power values =>> %d", pTargetFISoc->m_character.CharacterName,pTargetFISoc->GetCombatPower());		
		// end. 2014-11-24 by bckim, 해당 알림 문구 전국가 공용 번역
		return TRUE;
	}
#endif
	// end 2014-03-14 by jekim, 전투력 로그 추가

	// 2014-01-03 by jhseol&bckim, 파괴경매장 - 명령어 추가
#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG	// - 명령어 추가
	else if(0 == stricmp(token, "/파괴경매장"))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
		if ( TRUE == ms_pFieldIOCP->m_bDestroyAuctionContents )
		{			
			if ( TRUE == ms_pFieldIOCP->m_bDestroyAuctionInProgress )
			{
				SendString128(STRING_128_ADMIN_CMD, "진행중인 경매가 있어 OFF할 수 없습니다.");
				return FALSE;
			}
			
			ms_pFieldIOCP->m_bDestroyAuctionContents = FALSE;
			SendString128(STRING_128_ADMIN_CMD, "파괴경매장 OFF!!");
			return TRUE;
		}
		else
		{		
			ms_pFieldIOCP->m_bDestroyAuctionContents = TRUE;
			SendString128(STRING_128_ADMIN_CMD, "파괴경매장 ON!!");
			return TRUE;
		}
		return TRUE;
	}
	else if(0 == stricmp(token, "/경매시작"))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}

		if ( TRUE == ms_pFieldIOCP->m_bDestroyAuctionInProgress )
		{
			SendString128(STRING_128_ADMIN_CMD, "진행중인 경매가 있으므로 경매를 시작할수 없습니다.");
			return TRUE;
		}

		if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionContents )
		{
			SendString128(STRING_128_ADMIN_CMD, "파괴경매장 OFF!!상태 입니다. 상태변경이 필요합니다.");
			return FALSE;
		}


		CODBCStatement odbcStmt;
		BOOL bRet = odbcStmt.Init(g_pGlobalGameServer->GetDBServerIP(), g_pGlobalGameServer->GetDBServerPort(), g_pGlobalGameServer->GetDBServerDatabaseName(), (LPCSTR)g_pGlobalGameServer->GetODBCUID(), (LPCSTR)g_pGlobalGameServer->GetODBCPASSWORD(), g_pGlobalGameServer->GetMainWndHandle());
		if ( FALSE == bRet )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] fail to connect DBServer(CFieldIOCP::OnDoHourlyWorkIOCP) !! %s,%d %s %s %s\r\n"
				, g_pGlobalGameServer->GetDBServerIP(), g_pGlobalGameServer->GetDBServerPort()
				, g_pGlobalGameServer->GetDBServerDatabaseName(), (CHAR*)g_pGlobalGameServer->GetODBCUID(), (CHAR*)g_pGlobalGameServer->GetODBCPASSWORD());
			SendString128(STRING_128_ADMIN_CMD, "경매시작 실패, DB연결 Fail");
		}
		else
		{
			ms_pFieldIOCP->m_pDestroyAuctionManager->SetItemDestroyTimeFilter();
			ms_pFieldIOCP->m_pDestroyAuctionManager->SetDestroyAuctionStartEndTime();
			bRet = CAtumFieldDBManager::DBLoadDestroyAuctionList(&odbcStmt, ms_pFieldIOCP->m_pDestroyAuctionManager, ms_pFieldIOCP->m_pDestroyAuctionManager->GetItemDestroyTimeFilterBegin(), ms_pFieldIOCP->m_pDestroyAuctionManager->GetItemDestroyTimeFilterEnd());
			if (FALSE == bRet)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::HandleAdminCommands, DBLoadDestroyAuctionList fail !! \r\n");
				SendString128(STRING_128_ADMIN_CMD, "경매시작 실패, DBLoadDestroyAuctionList Fail");
			}
			else
			{
				ms_pFieldIOCP->m_bDestroyAuctionInProgress = TRUE;
				ms_pFieldIOCP->m_pDestroyAuctionManager->DestroyItemListUP();
				
				// 2014-07-07 by bckim, 파괴경매가 시작되어도 등록된 물품이 없으면 시작 메세지를 보내지 않음. 
				DESTROY_AUCTION_LIST* temp = ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr();
				if( NULL != temp && FALSE == temp->empty() )		// 경매물품이 있으면. 
				{
				MessageType_t msgTy = T_FC_DESTROY_AUCTION_NOTI_START;
				ms_pFieldIOCP->SendMessageToAllClients((BYTE*)&msgTy, SIZE_FIELD_TYPE_HEADER);
					SendString128(STRING_128_ADMIN_CMD, "경매시작 성공!!!");
				}
				else
				{
					SendString128(STRING_128_ADMIN_CMD, "경매시작 : 등록된 물품이 없습니다.");
				}
				// End. 2014-07-07 by bckim, 파괴경매가 시작되어도 등록된 물품이 없으면 시작 메세지를 보내지 않음. 	

				ATUM_DATE_TIME tmpStime = ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionStartTime();
				ATUM_DATE_TIME tmpEtime = ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionEndTime();

				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[NOTIFY] CFieldIOCPSocket::HandleAdminCommands, DestroyAuction Begin start[%s],end[%s] \r\n",
					tmpStime.GetAtTimeString(STRNBUF(SIZE_MAX_ATUM_DATE_TIME_STRING)), tmpEtime.GetAtTimeString(STRNBUF(SIZE_MAX_ATUM_DATE_TIME_STRING)));
			
			// 2014-05-12 by bckim, 파괴경매장 운영툴  // 경매물품 리스트 업 운영툴테이블 insert 
			bRet = CAtumFieldDBManager::DBInsertDestroyAuctionListUp(&odbcStmt, ms_pFieldIOCP->m_pDestroyAuctionManager);
			if (FALSE == bRet)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCP::OnDoMinutelyWorkIOCP, DBLoadDestroyAuctionList fail !! \r\n");
			}
			// End. 2014-05-12 by bckim, 파괴경매장 운영툴 

		}
		}
		return TRUE;
	}
	else if(0 == stricmp(token, "/경매종료"))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}

		if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionInProgress )
		{
			SendString128(STRING_128_ADMIN_CMD, "진행중인 경매가 없습니다.");
			return TRUE;
		}
		CODBCStatement odbcStmt;
		BOOL bRet = odbcStmt.Init(g_pGlobalGameServer->GetDBServerIP(), g_pGlobalGameServer->GetDBServerPort(), g_pGlobalGameServer->GetDBServerDatabaseName(), (LPCSTR)g_pGlobalGameServer->GetODBCUID(), (LPCSTR)g_pGlobalGameServer->GetODBCPASSWORD(), g_pGlobalGameServer->GetMainWndHandle());
		if ( FALSE == bRet )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] fail to connect DBServer(CFieldIOCP::OnDoHourlyWorkIOCP) !! %s,%d %s %s %s\r\n"
				, g_pGlobalGameServer->GetDBServerIP(), g_pGlobalGameServer->GetDBServerPort()
				, g_pGlobalGameServer->GetDBServerDatabaseName(), (CHAR*)g_pGlobalGameServer->GetODBCUID(), (CHAR*)g_pGlobalGameServer->GetODBCPASSWORD());
			SendString128(STRING_128_ADMIN_CMD, "경매종료 실패, DB연결 Fail");
		}
		else
		{
			bRet = CAtumFieldDBManager::DBSetClearDestroyAuctionList(&odbcStmt, ms_pFieldIOCP->m_pDestroyAuctionManager, ms_pFieldIOCP->m_pDestroyAuctionManager->GetItemDestroyTimeFilterBegin(), ms_pFieldIOCP->m_pDestroyAuctionManager->GetItemDestroyTimeFilterEnd());
			if (FALSE == bRet)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::HandleAdminCommands, DBSetClearDestroyAuctionList fail !! \r\n");
				SendString128(STRING_128_ADMIN_CMD, "경매종료 실패, DBSetClearDestroyAuctionList Fail");
			}
			else
			{
				ms_pFieldIOCP->m_bDestroyAuctionInProgress = FALSE;
				ms_pFieldIOCP->m_pDestroyAuctionManager->InitDestroyAuctionEndTime();
				MessageType_t msgTy = T_FC_DESTROY_AUCTION_NOTI_END;
				ms_pFieldIOCP->SendMessageToAllClients((BYTE*)&msgTy, SIZE_FIELD_TYPE_HEADER);
				SendString128(STRING_128_ADMIN_CMD, "경매종료 성공!!!");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[NOTIFY] CFieldIOCPSocket::HandleAdminCommands, DestroyAuction End \r\n");

				///////////////////////////////////////////////
				// 낙찰 로그 남기기
				DESTROY_AUCTION_LIST pDAuctionList;
				pDAuctionList.clear();
				ms_pFieldIOCP->m_pDestroyAuctionManager->CopyDestroyAuctionList(&pDAuctionList);
				DESTROY_AUCTION_ITR itr = pDAuctionList.begin();
				for ( ; itr != pDAuctionList.end() ; itr++ )
				{
					if ( 0 != (*itr)->CharacterUID )
					{
						INIT_MSG_WITH_BUFFER(MSG_FL_LOG_DESTROY_AUCTION_FIX, T_FL_LOG_DESTROY_AUCTION_FIX, pLogMsg, SendLogBuf);
						memcpy(&pLogMsg->DAuctionInfo, (*itr), sizeof(DESTROY_AUCTION_INFO));
						pLogMsg->DAuctionInfo.DAuctionState = AUCTION_ITEM_STATE_END;
						g_pFieldGlobal->SendLogFieldServer2LogServer(SendLogBuf, MSG_SIZE(MSG_FL_LOG_DESTROY_AUCTION_FIX));
					}
				}
			}
		}

		return TRUE;
	}
#endif	//#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG
	// end 2014-01-03 by jhseol&bckim, 파괴경매장 - 명령어 추가


	///////////////////////////////////////////////////////////////////////////////////////////
	// 테스트용 명령어 238 혹은 140까지만 있어야 하는 명령어는 여기에 추가를 한다. - start
#if defined(TEST140)
	// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 테스트 명렁어 추가
#ifdef S_TRIGGER_OUTPOST_JHSEOL	// - 테스트 명렁어 추가
	else if(0 == stricmp(token, "/버프고정"))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}

		token = strtok(NULL, seps);

		CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
		
		if( NULL == pFMChann )
		{
			return FALSE;
		}
		
		if(NULL != token)
		{
			ms_pFieldIOCP->m_pMapTriggerManager->FixedBuffItemChannelIndex(pFMChann->GetMapChannelIndex(), atoi(token));
		}
		else
		{
			ms_pFieldIOCP->m_pMapTriggerManager->FixedBuffItemChannelIndex(pFMChann->GetMapChannelIndex(), 0);
		}
		
		return TRUE;
	}
#endif
	// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 테스트 명렁어 추가
	// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
#ifdef S_MONTHL_CASH_BUY_GIFT_JHSEOL
	else if(0 == stricmp(token, "/선물줘"))
	{
		if ( !CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			return FALSE;
		}
// 2014-03-12 by jekim, 주민번호당 아이템 지급
#ifdef S_MONTHL_CASH_BUY_GIFT_JHSEOL
		if ( FALSE == g_pFieldGlobal->IsArenaServer() )
		{
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_LoadCashBuyDate, this, m_character.AccountUniqueNumber, NULL);
		}
#endif
// 		vectItemEventInfo		vectItemEventInfo1;
// 		vectItemEventInfo1.clear();
// 		vectItemEventInfo1.reserve(20);
// 		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemFirstPurchase(&vectItemEventInfo1, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, m_character.InfluenceType, \
// 			m_character.UnitKind, m_atAccountLastBuyDate, m_atCharacterLastBuyDate, m_nChannelingNum );	// 2014-02-10 by jhseol&bckim, 체널링
// 		for (int i=0; i < vectItemEventInfo1.size(); i++)
// 		{
// 			// 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경
// 			if ( FALSE == ms_pFieldIOCP->ItemEventSubTypeCheck(m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, vectItemEventInfo1[i]) )
// 			{
// 				continue;
// 			}
// 			// end 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경
// 
// 			char tmpAccount[SIZE_MAX_SQL_DATETIME_STRING] = {0, };
// 			m_atAccountLastBuyDate.GetSQLDateTimeString(tmpAccount, SIZE_MAX_SQL_DATETIME_STRING);
// 			char tmpCharacter[SIZE_MAX_SQL_DATETIME_STRING] = {0, };
// 			m_atCharacterLastBuyDate.GetSQLDateTimeString(tmpCharacter, SIZE_MAX_SQL_DATETIME_STRING);
// 			char EventStartTime[SIZE_MAX_SQL_DATETIME_STRING] = {0, };
// 			vectItemEventInfo1[i].StartTime.GetSQLDateTimeString(EventStartTime, SIZE_MAX_SQL_DATETIME_STRING);
// 			char EventEndTime[SIZE_MAX_SQL_DATETIME_STRING] = {0, };
// 			vectItemEventInfo1[i].EndTime.GetSQLDateTimeString(EventEndTime, SIZE_MAX_SQL_DATETIME_STRING);
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[S_MONTHL_CASH_BUY_GIFT_JHSEOL][Notify] CFieldIOCPSocket::HandleAdminCommands, AUID(%8d) CUID(%8d) A_Date(%s) C_Date(%s), Event ID(%5d) Time(%s ~ %s)\r\n"
// 				, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, tmpAccount, tmpCharacter, vectItemEventInfo1[i].ItemEventUID, EventStartTime, EventEndTime);
// 			QPARAM_CHECK_EVENTITEM *pQParam = new QPARAM_CHECK_EVENTITEM;
// 			pQParam->AccountUID		= m_character.AccountUniqueNumber;
// 			pQParam->ItemEventUID	= vectItemEventInfo1[i].ItemEventUID;
// 			pQParam->ItemEventType  = vectItemEventInfo1[i].ItemEventType;
// 			pQParam->ItemNum		= vectItemEventInfo1[i].ItemNum;
// 			pQParam->Count			= vectItemEventInfo1[i].Count;
// 			pQParam->PrefixCodeNum	= vectItemEventInfo1[i].PrefixCodeNum;
// 			pQParam->SuffixCodeNum	= vectItemEventInfo1[i].SuffixCodeNum;
// 			pQParam->CharacterUID	= (FALSE == vectItemEventInfo1[i].CheckWithCharacterUID) ? 0 : m_character.CharacterUniqueNumber;	// 2009-11-19 by cmkwon, 아이템 이벤트에 Account/Character 체크 기능 추가 - 
// 			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckEventItem, this, m_character.AccountUniqueNumber, pQParam);
// 		}
// 		m_atCharacterLastBuyDate.SetCurrentDateTime(FALSE);
// 		m_atAccountLastBuyDate.SetCurrentDateTime(FALSE);
// 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertCashBuyDate, this, m_character.AccountUniqueNumber, NULL);
// end 2014-03-12 by jekim, 주민번호당 아이템 지급
		return TRUE;
	}
	#endif	//#ifdef S_MONTHL_CASH_BUY_GIFT_JHSEOL 
	// end 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급

#endif
	// 테스트용 명령어 238 혹은 140까지만 있어야 하는 명령어는 여기에 추가를 한다. - end
	///////////////////////////////////////////////////////////////////////////////////////////
	else
	{
		if( TRUE == ms_pFieldIOCP->m_pSecurityManager->ExecCommand(token) ) 
		{
			return TRUE;
		}

		if( TRUE == ms_pFieldIOCP->m_pSecurityManager->CheckCommand(token) )		// 담당자 실수 방지 (로그 안남기도록 처리)
		{
			return TRUE;
		}
	}
	// end 2011-06-22 by hskim, 사설 서버 방지
	
	// 해당 명령어가 없는 경우
	SendErrorMessage(T_FIELD_IOCP, ERR_CHAT_INVALID_COMMAND, 0, 0, token);
	return FALSE;
}

ProcessResult CFieldIOCPSocket::Process_FM_PRINT_DEBUG_MSG(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FM_PRINT_DEBUG_MSG	*pRecvPrintDbg = NULL;

	nRecvTypeSize = sizeof(MSG_FM_PRINT_DEBUG_MSG);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FM_PRINT_DEBUG_MSG, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14056);
		return RES_RETURN_FALSE;
	}
	pRecvPrintDbg = (MSG_FM_PRINT_DEBUG_MSG*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

// 2008-02-14 by cmkwon, 처리 방식 수정으로 주석 처리함
// 	DBGOUT("=== START - DEBUG MESSAGE REQUESTED BY MONITOR SERVER ========\n");
// 	DBGOUT("  Int Param1   : %d \n", pRecvPrintDbg->IntParam1);
// 	DBGOUT("  Int Param2   : %d \n", pRecvPrintDbg->IntParam2);
// 	DBGOUT("  Float Param1 : %d \n", (int)pRecvPrintDbg->FloatParam1);
// 	DBGOUT("  Float Param2 : %d \n", (int)pRecvPrintDbg->FloatParam2);
// 	DBGOUT("  String Param : \"%s\" \n", pRecvPrintDbg->StringParam);
// 
// 	//char msg[200000];
// 	char *msg = NULL;
// 	PRINT_DEBUG_MESSAGE(msg);
// 
// 
// 	DBGOUT("=== END --- DEBUG MESSAGE REQUESTED BY MONITOR SERVER ========\n");

	return RES_RETURN_TRUE;
}

void CFieldIOCPSocket::PRINT_DEBUG_MESSAGE(char*& msg)
{
	// 2008-02-14 by cmkwon, 베트남 체크를 위해 임시로 추가한 코드임 - 해당 캐릭터의 아이템 정보를 로그로 저장한다.
	this->m_ItemManager.DBG_PRINT_ITEM();

}

// 2008-02-14 by cmkwon, 사용하지 않는 코드임. 위와 같이 수정해서 사용함
//void CFieldIOCPSocket::PRINT_DEBUG_MESSAGE(char*& msg)
// 	return;		// 2005-01-31 by cmkwon
// 
// 	char szTime[128];
// 	time_t ltime;
// 	struct tm *today = NULL;
// 	time(&ltime);
// 	today = localtime(&ltime);
// 	strftime(szTime, 128, "[%m-%d %H:%M:%S]", today );
// 
// 	PRINT_DEBUG_MESSAGE_LOCK.lock();
// 	///////////////////////////////////////////////////////////////////////////
// 	// START - DEBUG MESSAGE
// 	///////////////////////////////////////////////////////////////////////////
// 
// 	// 자기 자신의 정보
// 	SendString128(STRING_128_ADMIN_CMD, "Field - AUN(%d) CUN(%d) CI(%d) MAP(%d, %d)",
// 		m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber,
// 		m_character.ClientIndex, m_character.MapChannelIndex.MapIndex,
// 		m_character.MapChannelIndex.ChannelIndex);
// 
// 
// //	// 타이머 정보
// //	m_listWatingTimerEvents.lock();
// //	mtlistMexTimerEvent::iterator itrTimer = m_listWatingTimerEvents.begin();
// //	while(m_listWatingTimerEvents.end() != itrTimer)
// //	{
// //		MEX_TIMER_EVENT *pTimerEvent = &(*itrTimer);
// //
// //		SendString128(STRING_128_ADMIN_CMD, "%s %d", CAtumSJ::GetTimerTypeString(pTimerEvent->Type), pTimerEvent->TimerUID);
// //
// //		itrTimer++;
// //	}
// //	m_listWatingTimerEvents.unlock();
// 
// 	// 파티 정보
// 	DBGOUT2(DO2_DBGOUT, "\n[Party Info] - %s\n", szTime);
// 
// 	// lock m_MapParties
// 	mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);
// 	mtmapPartyID2FieldParty::iterator itr = ms_pFieldIOCP->m_MapParties.begin();
// 	while (itr != ms_pFieldIOCP->m_MapParties.end())
// 	{
// 		CFieldParty *pParty = itr->second;
// 		mt_auto_lock pmlock(&pParty->m_ListPartyMember);
// 
// 		// party master
// 		CFieldIOCPSocket *pMaster = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(pParty->GetMasterCharacterUniqueNumber());
// 
// 		if (pMaster != NULL)
// 		{
// 			DBGOUT2(DO2_DBGOUT, "PARTY Master: %s(%d, %d) - key: %d, MemberCounts: %d\n"
// 				, pMaster->m_character.CharacterName
// 				, pParty->GetMasterCharacterUniqueNumber()
// 				, pMaster->m_character.ClientIndex
// 				, HIDWORD(pParty->m_PartyID)
// 				, itr->second->m_ListPartyMember.size()
// 			);
// 		}
// 		else
// 		{
// 			DBGOUT2(DO2_DBGOUT, "PARTY Master: %s(%d, %s) - key: %d, num: %d\n"
// 				, "N/A"
// 				, pParty->GetMasterCharacterUniqueNumber()
// 				, "N/A"
// 				, HIDWORD(itr->first)
// 				, itr->second->m_ListPartyMember.size()
// 			);
// 		}
// 
// 		mtlistFieldPartyMember::iterator itr2 = pParty->m_ListPartyMember.begin();
// 		while (itr2 != pParty->m_ListPartyMember.end())
// 		{
// 			CFieldIOCPSocket *pMember = itr2->PM_CharacterSocket;
// 			if (pMember != NULL)
// 			{
// 				DBGOUT2(DO2_DBGOUT, "      Member: %10s(%6d, %4d) at %d(%d)\n"
// 					, pMember->m_character.CharacterName
// 					, pMember->m_character.CharacterUniqueNumber
// 					, pMember->m_character.ClientIndex
// 					, pMember->m_character.MapChannelIndex.MapIndex
// 					, pMember->m_character.MapChannelIndex.ChannelIndex
// 				);
// 			}
// 			else
// 			{
// 				DBGOUT2(DO2_DBGOUT, "      Member: ERROR! NULL MEMBER POINTER! CHECK IT OUT!\n");
// 			}
// 
// 			itr2++;
// 		}
// 
// 		itr++;
// 	}
// 
// 	///////////////////////////////////////////////////////////////////////////
// 	// 주의: 서비스 돌릴 때는 계정 찍지 말자, 20031103, kelovon
// 	///////////////////////////////////////////////////////////////////////////
// 	PRINT_DEBUG_MESSAGE_LOCK.unlock();
//}

ProcessResult CFieldIOCPSocket::Process_FC_MONSTER_SKILL_END_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize;	
	MSG_FC_MONSTER_SKILL_END_SKILL	*pEndSkill;

	nRecvTypeSize = sizeof(MSG_FC_MONSTER_SKILL_END_SKILL);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_MONSTER_SKILL_END_SKILL, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14053);
		return RES_RETURN_FALSE;
	}
	pEndSkill = (MSG_FC_MONSTER_SKILL_END_SKILL*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;	

	if(m_pCurrentFieldMapChannel)
	{
		INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_SKILL_END_SKILL, T_FN_MONSTER_SKILL_END_SKILL, pSeEndSkill, SendBuf);
		pSeEndSkill->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		pSeEndSkill->MonsterIndex	= pEndSkill->MonsterIndex;
		pSeEndSkill->PositionVector	= pEndSkill->PositionVector;
		pSeEndSkill->TargetVector	= pEndSkill->TargetVector;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_MONSTER_SKILL_END_SKILL));
	}

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_MONSTER_SUMMON_MONSTER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MONSTER_SUMMON_MONSTER
		, MSG_FC_MONSTER_SUMMON_MONSTER, pRSummonMonster);
	
	// start 2012-01-05 by hskim, 서버 죽는 문제 방지
	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	// end 2012-01-05 by hskim, 서버 죽는 문제 방지
	
	if(MONSTER_TARGETTYPE_TUTORIAL == pRSummonMonster->byMonsterTargetType2)
	{
		if(FALSE == IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
		{
			SendErrorMessage(T_FC_MONSTER_SUMMON_MONSTER, ERR_PROTOCOL_NOT_TUTORIAL_MAP, m_character.MapChannelIndex.MapIndex);
			return RES_BREAK;
		}
	}
	else
	{
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 관리자, 운영자만 허용
			SendErrorMessage(T_FC_MONSTER_SUMMON_MONSTER, ERR_PROTOCOL_RACE_PERMISSION_DENIED);
			return RES_BREAK;
		}
	}

	D3DXVECTOR3 tmVec3Pos = A2DX(pRSummonMonster->PositionAVector);
	if(FALSE == m_pCurrentFieldMapChannel->m_pFieldMapProject->IsValidTileForCreateMonster(&tmVec3Pos))
	{
		SendErrorMessage(T_FC_MONSTER_SUMMON_MONSTER, ERR_PROTOCOL_INVALID_POSITION);
		return RES_BREAK;
	}
	ez_map<int, MONSTER_INFO>::iterator itrMon = ms_pFieldIOCP->m_mapMonsterInfo.find(pRSummonMonster->SummonMonsterUnitKind);
	if (itrMon == ms_pFieldIOCP->m_mapMonsterInfo.end())
	{
		SendErrorMessage(T_FC_MONSTER_SUMMON_MONSTER, ERR_PROTOCOL_NO_SUCH_MONSTER_INFO, pRSummonMonster->SummonMonsterUnitKind);
		return RES_BREAK;
	}

	if (m_pCurrentFieldMapChannel->m_pFieldMapProject->GetNPCServerStartFlag() == FALSE)
	{
		SendErrorMessage(T_FC_MONSTER_SUMMON_MONSTER, ERR_PROTOCOL_INVALID_SOCKET_FORNPC);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// NPC Server로 전송
	INIT_MSG_WITH_BUFFER(MSG_FN_ADMIN_SUMMON_MONSTER, T_FN_ADMIN_SUMMON_MONSTER, pMsgSummonMonster, SendBuf);
	pMsgSummonMonster->ChannelIndex			= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	STRNCPY_MEMSET(pMsgSummonMonster->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pMsgSummonMonster->MonsterUnitKind		= pRSummonMonster->SummonMonsterUnitKind;
	pMsgSummonMonster->MonsterTargetType1	= pRSummonMonster->byMonsterTargetType2;
	pMsgSummonMonster->TargetTypeData1		= pRSummonMonster->nTargetTypeData2;
	pMsgSummonMonster->CltIdxForTargetType1	= 0;
	if(MONSTER_TARGETTYPE_TUTORIAL == pRSummonMonster->byMonsterTargetType2)
	{
		pMsgSummonMonster->CltIdxForTargetType1	= m_character.ClientIndex;
	}
	pMsgSummonMonster->NumOfMonster			= max(1, pRSummonMonster->nSummonCounts);
	pMsgSummonMonster->Position				= pRSummonMonster->PositionAVector;

	// 2010. 07. 05 by hsLee. 몬스터 소환 관련. (밸런스 데이터 누락 수정.)
	pMsgSummonMonster->MonsterBalanceData.Init(0);

	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_ADMIN_SUMMON_MONSTER));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_MONSTER_TUTORIAL_MONSTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MONSTER_TUTORIAL_MONSTER_DELETE
		, MSG_FC_MONSTER_TUTORIAL_MONSTER_DELETE, pRTMonDel);
	
	if(FALSE == IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{
		SendErrorMessage(T_FC_MONSTER_TUTORIAL_MONSTER_DELETE, ERR_PROTOCOL_NOT_TUTORIAL_MAP, m_character.MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	CFieldMonster *pFMon = m_pCurrentFieldMapChannel->GetFieldMonster(pRTMonDel->monsterIdx, 22);
	if(NULL == pFMon
		|| MONSTER_TARGETTYPE_TUTORIAL != pFMon->m_byMonsterTargetType)
	{
		return RES_BREAK;
	}

	m_pCurrentFieldMapChannel->OnMonsterDeadFieldMapChannel(pFMon);
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_RACING_RACINGLIST_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{	
	INIT_MSG_WITH_BUFFER(MSG_FC_RACING_RACINGLIST_REQUEST_ACK, T_FC_RACING_RACINGLIST_REQUEST_ACK, pSMsg, SendBuf);	
	if(FALSE == ms_pFieldIOCP->m_pRacingDemon->MakeMessageRacingDemon(T_FC_RACING_RACINGLIST_REQUEST_ACK, pSMsg))
	{
		return RES_BREAK;
	}
	
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_RACING_RACINGLIST_REQUEST_ACK)+pSMsg->byRacingListCounts*sizeof(MAP_CHANNEL_INDEX));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_RACING_RACINGINFO_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;	
	MSG_FC_RACING_RACINGINFO_REQUEST	*pRMsg = NULL;

	nRecvTypeSize = sizeof(MSG_FC_RACING_RACINGINFO_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_RACING_RACINGINFO_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14053);
		return RES_RETURN_FALSE;
	}
	pRMsg = (MSG_FC_RACING_RACINGINFO_REQUEST*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;
	
	if(m_pRacingFieldMapChannel)
	{
		m_pRacingFieldMapChannel->OutRacingSystem(this);
		m_pRacingFieldMapChannel = NULL;
	}
	m_pRacingFieldMapChannel = ms_pFieldIOCP->m_pRacingDemon->FindRacingMapChannel(pRMsg->mapChannIdx);
	if(NULL == m_pRacingFieldMapChannel)
	{
		return RES_BREAK;
	}

	m_pRacingFieldMapChannel->InRacingWaitingRoom(this);

	INIT_MSG_WITH_BUFFER(MSG_FC_RACING_RACINGINFO_REQUEST_ACK, T_FC_RACING_RACINGINFO_REQUEST_ACK, pSMsg, SendBuf);
	if(FALSE == m_pRacingFieldMapChannel->MakeRacingMessage(T_FC_RACING_RACINGINFO_REQUEST_ACK, pSMsg))
	{
		return RES_BREAK;
	}
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_RACING_RACINGINFO_REQUEST_ACK));	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_RACING_JOIN_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;	
	MSG_FC_RACING_JOIN_REQUEST	*pRMsg = NULL;

	nRecvTypeSize = sizeof(MSG_FC_RACING_JOIN_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_RACING_JOIN_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14053);
		return RES_RETURN_FALSE;
	}
	pRMsg = (MSG_FC_RACING_JOIN_REQUEST*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(NULL == m_pRacingFieldMapChannel
		|| m_pRacingFieldMapChannel->GetMapChannelIndex() != pRMsg->mapChannIdx)
	{
		m_pRacingFieldMapChannel = ms_pFieldIOCP->m_pRacingDemon->FindRacingMapChannel(pRMsg->mapChannIdx);
		if(NULL == m_pRacingFieldMapChannel)
		{
			return RES_BREAK;
		}
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_RACING_JOIN_REQUEST_ACK, T_FC_RACING_JOIN_REQUEST_ACK, pSMsg, SendBuf);
	pSMsg->mapChannIdx		= m_pRacingFieldMapChannel->GetMapChannelIndex();
	pSMsg->byJoinedOrder	= m_pRacingFieldMapChannel->JoinRacing(this);
	if(0 == pSMsg->byJoinedOrder)
	{
		pSMsg->byJoinedFlag		= FALSE;
	}
	else
	{
		pSMsg->byJoinedFlag		= TRUE;
	}
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_RACING_JOIN_REQUEST_ACK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_RACING_CHECKPOINT_CHECK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;	
	MSG_FC_RACING_CHECKPOINT_CHECK	*pRMsg = NULL;

	nRecvTypeSize = sizeof(MSG_FC_RACING_CHECKPOINT_CHECK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_RACING_CHECKPOINT_CHECK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14053);
		return RES_RETURN_FALSE;
	}
	pRMsg = (MSG_FC_RACING_CHECKPOINT_CHECK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(NULL == m_pRacingFieldMapChannel)
	{
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_RACING_CHECKPOINT_CHECK_ACK, T_FC_RACING_CHECKPOINT_CHECK_ACK, pSMsg, SendBuf);
	pSMsg->byCheckedFlag		= FALSE;
	pSMsg->byCheckPointIndex	= pRMsg->byCheckPointIndex;	
// 2004-11-23 by cmkwon, GetEventInfoByObjectTypeAndDistanceW함수로 수정해야함
//	vectorObjectInfoServer::iterator it(m_pRacingFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.begin());
//	while(it != m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.end())
//	{
//		D3DXVECTOR3	tmVec3 = A2DX(pRMsg->PositionAVector3);
//		if(it->m_EventInfo.m_bEventType == EVENT_TYPE_RACING_CHECK_POTINT
//			&& pRMsg->dwObjectType == it->m_dwObjType			
//			&& D3DXVec3Length(&(tmVec3 - it->m_vPos)) < 10.0f)
//		{
//			if(TRUE == m_pRacingFieldMapChannel->CheckPointCheck(this, pRMsg->byCheckPointIndex))
//			{
//				pSMsg->byCheckedFlag = TRUE;
//			}
//		}
//		it++;
//	}
//	pSMsg->byRanking = this->m_byRacingRanking;
//	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_RACING_CHECKPOINT_CHECK_ACK));
//
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CITYWAR_GET_OCCUPYINFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK, T_FC_CITYWAR_GET_OCCUPYINFO_OK, pSMsg, SendBuf);
	if(FALSE == pFMChann->MakeMSG_FC_CITYWAR_GET_OCCUPYINFO_OK(pSMsg, m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITYWAR_GET_OCCUPYINFO, ERR_CITYWAR_NO_SUCH_CITYWAR_INFO
			, pFMChann->m_MapChannelIndex.MapIndex, pFMChann->m_MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}

	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_CITYWAR_SET_SETTINGTIME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITYWAR_SET_SETTINGTIME
		, MSG_FC_CITYWAR_SET_SETTINGTIME, pRSetWarTime);

	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	Err_t err = pFMChann->SetCityWarSettingTimeFieldMapChannel(&pRSetWarTime->atimeSetCityWarSettingTime, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_CITYWAR_SET_SETTINGTIME, err, pFMChann->m_MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 모니터로 변경 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FM_CITYWAR_CHANGED_OCCUPY_INFO, T_FM_CITYWAR_CHANGED_OCCUPY_INFO, pS2MOccInfo, SendBuf);
	pS2MOccInfo->MapChannelIndex.MapIndex		= pFMChann->m_pRefCityWar1->MapIndex;	
	pS2MOccInfo->MapChannelIndex.ChannelIndex	= 0;
	pS2MOccInfo->cityWarOccupyInfo				= *(pFMChann->m_pRefCityWar1->GetCITY_OCCUPY_INFO());
	ms_pFieldIOCP->SendMessageToMonitor(SendBuf, MSG_SIZE(MSG_FM_CITYWAR_CHANGED_OCCUPY_INFO));
	
	///////////////////////////////////////////////////////////////////////////////
	// 여단장에게 수정 정보 전송
	INIT_MSG(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK, T_FC_CITYWAR_GET_OCCUPYINFO_OK, pS2COccInfo, SendBuf);
	if(FALSE == pFMChann->MakeMSG_FC_CITYWAR_GET_OCCUPYINFO_OK(pS2COccInfo, m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITYWAR_SET_SETTINGTIME, ERR_CITYWAR_NO_SUCH_CITYWAR_INFO
			, pFMChann->m_MapChannelIndex.MapIndex, pFMChann->m_MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_CITYWAR_SET_TEX(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITYWAR_SET_TEX
		, MSG_FC_CITYWAR_SET_TEX, pRSetTex);

	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	Err_t err = pFMChann->SetCityWarTexFieldMapChannel(pRSetTex->fSetTex, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_CITYWAR_SET_TEX, err, pFMChann->m_MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 여단장에게 수정 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK, T_FC_CITYWAR_GET_OCCUPYINFO_OK, pS2COccInfo, SendBuf);
	if(FALSE == pFMChann->MakeMSG_FC_CITYWAR_GET_OCCUPYINFO_OK(pS2COccInfo, m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITYWAR_SET_TEX, ERR_CITYWAR_NO_SUCH_CITYWAR_INFO
			, pFMChann->m_MapChannelIndex.MapIndex, pFMChann->m_MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_CITYWAR_SET_BRIEFING(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITYWAR_SET_BRIEFING
		, MSG_FC_CITYWAR_SET_BRIEFING, pRSetBriefing);

	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	Err_t err = pFMChann->SetCityWarBriefingFieldMapChannel(pRSetBriefing->szSetBriefing, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_CITYWAR_SET_BRIEFING, err, pFMChann->m_MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 여단장에게 수정 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK, T_FC_CITYWAR_GET_OCCUPYINFO_OK, pS2COccInfo, SendBuf);
	if(FALSE == pFMChann->MakeMSG_FC_CITYWAR_GET_OCCUPYINFO_OK(pS2COccInfo, m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITYWAR_SET_BRIEFING, ERR_CITYWAR_NO_SUCH_CITYWAR_INFO
			, pFMChann->m_MapChannelIndex.MapIndex, pFMChann->m_MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_CITYWAR_BRING_SUMOFTEX(const char* pPacket, int nLength, int &nBytesUsed)
{	
	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	int nBringTex = 0.0f;
	Err_t err = pFMChann->CityWarBringSumOfTex(&nBringTex, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_CITYWAR_BRING_SUMOFTEX, err, pFMChann->m_MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	if(nBringTex <= 0)
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 가져온 세금을 자신을 추가한다
	mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);
	m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, nBringTex, IUT_CITYWAR_BRING_SUMOFTEX);
	mtA.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 가져온 세금 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CITYWAR_BRING_SUMOFTEX_OK, T_FC_CITYWAR_BRING_SUMOFTEX_OK, pS2CBringOK, SendBuf);
	pS2CBringOK->nBroughtSumOfTex	= nBringTex;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_BRING_SUMOFTEX_OK));
	
	///////////////////////////////////////////////////////////////////////////////
	// 여단장에게 수정 정보 전송
	INIT_MSG(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK, T_FC_CITYWAR_GET_OCCUPYINFO_OK, pS2COccInfo, SendBuf);
	if(FALSE == pFMChann->MakeMSG_FC_CITYWAR_GET_OCCUPYINFO_OK(pS2COccInfo, m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITYWAR_SET_BRIEFING, ERR_CITYWAR_NO_SUCH_CITYWAR_INFO
			, pFMChann->m_MapChannelIndex.MapIndex, pFMChann->m_MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITYWAR_GET_OCCUPYINFO_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_WAR_REQ_SIGN_BOARD_STRING_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-17 ~ 2006-04-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_WAR_REQ_SIGN_BOARD_STRING_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_WAR_REQ_SIGN_BOARD_STRING_LIST
		, MSG_FC_WAR_REQ_SIGN_BOARD_STRING_LIST, pRReqStringList);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-19 by cmkwon, 전광판 공지사항 전송
	ms_pFieldIOCP->SendSignBoardStringList(this, pRReqStringList->nReqStringCount);


	// 2009-10-13 by cmkwon, 일반 세력은 기여도 전송 할 필요 없다
	if(FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2006-04-19 by cmkwon, 기여도 전송함
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_UPDATE_CONTRIBUTION_POINT_OK, T_FC_WAR_UPDATE_CONTRIBUTION_POINT_OK, pSConPoint, SendBuf);
		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 아래와 같이 자신의 세력을 설정한다.
		//pSConPoint->byInfluenceType		= m_character.GetInfluenceMask();
		pSConPoint->byInfluenceType		= m_character.InfluenceType;
		pSConPoint->nContributionPoint	= ms_pFieldIOCP->m_InflWarManager.GetContributionPoint(m_character.InfluenceType);
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_UPDATE_CONTRIBUTION_POINT_OK));
	}
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_PUT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_PUT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_SELL_PUT_ITEM
		, MSG_FC_BAZAAR_SELL_PUT_ITEM, pRMsg);

	if(0 >= pRMsg->nAmount
		|| 0 >= pRMsg->nEachPrice
		|| MAX_ITEM_COUNTS < (INT64)pRMsg->nAmount * (INT64)pRMsg->nEachPrice)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_DB_INVALID_PARAMETER);
		return RES_BREAK;
	}

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pSellItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->itemUID);
	if(NULL == pSellItemG)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if(FALSE == this->IsTransferItem(pSellItemG, TRUE))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if(FALSE == IS_COUNTABLE_ITEM(pSellItemG->Kind))
	{
		pRMsg->nAmount			= 1;
	}
	else
	{
		if(pSellItemG->CurrentCount < pRMsg->nAmount)
		{
			SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
			return RES_BREAK;
		}
	}

	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	ITEM_GENERAL *pSPIItemG = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pSPIItemG)
	{
		if(NULL == pSPIItemG)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	INT64	n64TotalMoney = m_bazaarManager.GetTotalPrice() + (INT64)pRMsg->nAmount * (INT64)pRMsg->nEachPrice + pSPIItemG->CurrentCount; 
	if(MAX_ITEM_COUNTS < n64TotalMoney)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	Err_t errCode = m_bazaarManager.AddSellItem(pSellItemG, pRMsg->nAmount, pRMsg->nEachPrice);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_PUT_ITEM, errCode);
		return RES_BREAK;
	}

	bmLock.auto_unlock_cancel();
	igLock.auto_unlock_cancel();


	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_SELL_PUT_ITEM_OK, T_FC_BAZAAR_SELL_PUT_ITEM_OK, pSItemOK, SendBuf);
	pSItemOK->itemUID		= pRMsg->itemUID;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_PUT_ITEM_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_CANCEL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_CANCEL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_SELL_CANCEL_ITEM
		, MSG_FC_BAZAAR_SELL_CANCEL_ITEM, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_CANCEL_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	if(BAZAAR_STATE_READY != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_CANCEL_ITEM, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	SBazaarItem *pBazaarItem = m_bazaarManager.FindBazaarItemByItemUIDNoLock(pRMsg->itemUID);
	if(NULL == pBazaarItem)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_CANCEL_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	m_bazaarManager.DeleteBazaarItem(pBazaarItem->nBuyItemIndex);

	bmLock.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_SELL_CANCEL_ITEM_OK, T_FC_BAZAAR_SELL_CANCEL_ITEM_OK, pSCancelOK, SendBuf);
	pSCancelOK->itemUID		= pRMsg->itemUID;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_CANCEL_ITEM_OK));
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_START(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_SELL_START
		, MSG_FC_BAZAAR_SELL_START, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}


	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	if(BAZAAR_STATE_READY != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	if(m_bazaarManager.IsEmptyBazaar())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if(0 >= strlen(pRMsg->szBazaarName))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	m_bazaarManager.SetBazaarName(pRMsg->szBazaarName);
	m_bazaarManager.SetBazaarState(BAZAAR_STATE_ACTIVE);	

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 주위 모든 유저에게 BazaarInfo 전송 준비
	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_INFO_OK, T_FC_BAZAAR_INFO_OK, pSBazaarInfoOK, SendBuf);
	this->MakeMSG_FC_BAZAAR_INFO_OKW(pSBazaarInfoOK);

	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Bazaar Sell Shop open !! %s ItemKindCount(%d)\r\n", GetCharacterString(this->GetCharacter(), string()), m_bazaarManager.GetBazaarItemListPtr()->size());

	bmLock.auto_unlock_cancel();
	igLock.auto_unlock_cancel();	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 여기에서 해제 하는 것이 좋을 것 같음
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 자기 자신에게 개인 상점 시작 OK 전송
	SendAddMessageType(T_FC_BAZAAR_SELL_START_OK);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 주위 모든 유저에게 BazaarInfo 전송
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf, MSG_SIZE(MSG_FC_BAZAAR_INFO_OK),
															this->m_pCurrentFieldMapChannel, m_character.ClientIndex);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_REQUEST_ITEMLIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 바자판매 상점에서 구매자가 판매 아이템 리스트 요청 프로토콜
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_REQUEST_ITEMLIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_SELL_REQUEST_ITEMLIST
		, MSG_FC_BAZAAR_SELL_REQUEST_ITEMLIST, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, 바자판매 상점에서 판매 아이템 리스트 요청시 구매자가 개인 상점을 오픈 중인지 체크
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}

	CFieldIOCPSocket *pPeerFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->clientIndex0);
	if(NULL == pPeerFISock
		|| FALSE == pPeerFISock->IsValidCharacter()
		|| FALSE == pPeerFISock->GetCharacter()->CharacterMode)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}

	if(REQUERED_BAZAAR_DISTANCE < D3DXVec3Length(&(m_character.PositionVector - pPeerFISock->GetCharacter()->PositionVector)))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_PROTOCOL_TOO_FAR_TO_DO);
		return RES_BREAK;
	}
	
	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BAZAAR, (0==m_backupRace)?m_character.Race:m_backupRace, m_character.InfluenceType,
		(0==pPeerFISock->m_backupRace)?pPeerFISock->m_character.Race:pPeerFISock->m_backupRace, pPeerFISock->m_character.InfluenceType))
	{// 2006-08-07 by cmkwon, 관리자/운영자 거래 체크
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	if(FALSE == pPeerFISock->SendBazaarItemList(this, BAZAAR_TYPE_SELL))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 바자판매 상점에서 구매자가 아이템 구매 요청하는 프로토콜
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_SELL_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_SELL_BUY_ITEM
		, MSG_FC_BAZAAR_SELL_BUY_ITEM, pRMsg);

	if(0 >= pRMsg->nAmount0)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_DB_INVALID_PARAMETER);
		return RES_BREAK;
	}

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - T_FC_BAZAAR_SELL_BUY_ITEM, 바자판매 상점에서 아이템 구매 요청시 구매자가 개인 상점을 오픈 중인지 체크
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}

	CFieldIOCPSocket *pPeerFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->clientIndex0);
	if(NULL == pPeerFISock
		|| FALSE == pPeerFISock->IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BAZAAR, (0==m_backupRace)?m_character.Race:m_backupRace, m_character.InfluenceType,
		(0==pPeerFISock->m_backupRace)?pPeerFISock->m_character.Race:pPeerFISock->m_backupRace, pPeerFISock->m_character.InfluenceType))
	{// 2006-08-07 by cmkwon, 관리자/운영자 거래 체크
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	mt_auto_lock meigLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pMeMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pMeMoney)
	{
		if(NULL == pMeMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	mt_auto_lock peerigLock(&pPeerFISock->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock peerbiLock(pPeerFISock->m_bazaarManager.GetBazaarItemListPtr());

	SBazaarItem *pBazaarItem = pPeerFISock->m_bazaarManager.FindBazaarItemByItemUIDNoLock(pRMsg->itemUID);
	if(NULL == pBazaarItem)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_BAZAAR_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemG = pPeerFISock->m_ItemManager.GetItemGeneralByUID(pRMsg->itemUID);
	if(NULL == pItemG
		|| pItemG != pBazaarItem->pItemGeneral)
	{// 2008-07-23 by cmkwon, 아이템 복사 버그 수정 - 바자 판매상점 아이템 판매시 아이템 체크 추가
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_BAZAAR_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_BAZAAR_SELL_BUY_ITEM
	if(pBazaarItem->pItemGeneral->UniqueNumber != pRMsg->itemUID
		|| pBazaarItem->pItemGeneral->Possess != pPeerFISock->GetCharacter()->CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d\r\n"
			, GetProtocolTypeString(T_FC_BAZAAR_SELL_BUY_ITEM), GetCharacterString(pPeerFISock->GetCharacter(), string()), GetItemGeneralString(pBazaarItem->pItemGeneral, string()), pBazaarItem->pItemGeneral->Possess, pRMsg->itemUID);
		return RES_BREAK;
	}

// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 아래와 같이 실제 아이템의 개수도 체크 함.
// 	if(pBazaarItem->nItemCnts < pRMsg->nAmount0)
// 	{
// 		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
// 		return RES_BREAK;
// 	}
	if(pBazaarItem->nItemCnts < pRMsg->nAmount0
		|| (IS_COUNTABLE_ITEM(pItemG->Kind) && pItemG->CurrentCount < pRMsg->nAmount0) )	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 카운터블 아이템 인벤의 아이템 개수 체크
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED, pItemG->CurrentCount, pRMsg->nAmount0);
		return RES_BREAK;
	}

	ITEM_GENERAL *pPeerMoney = pPeerFISock->m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pPeerMoney)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	// 2006-07-26 by cmkwon, 구매자 SPI 체크
	if(pMeMoney->CurrentCount < (INT64)pRMsg->nAmount0 * (INT64)pBazaarItem->nItemPriceOfEach)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	if(MAX_ITEM_COUNTS < (INT64)pPeerMoney->CurrentCount + (INT64)pRMsg->nAmount0 * (INT64)pBazaarItem->nItemPriceOfEach)
	{// 2006-08-03 by cmkwon, 
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
		return RES_BREAK;
	}

	// 2006-07-26 by cmkwon, 구매자 인벤토리 공간 체크
	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
	if(m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매 아이템 처리
	this->BazaarInsertItem(pPeerFISock, pBazaarItem->pItemGeneral, pRMsg->nAmount0);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매자 SPI 처리 
	ITEM_GENERAL tmpItemOnlyForLog_BazaarSellVisitor = *pMeMoney;
	tmpItemOnlyForLog_BazaarSellVisitor.CurrentCount -= pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach;

	// 2008-09-08 by cmkwon, 개인상점 로그 버그 수정 및 로그 추가 - (판매상점)기존 SendLogMessageITEMBazaarRecv을 수정함.
	CAtumLogSender::SendLogMessageITEMBazaarSend(this, &tmpItemOnlyForLog_BazaarSellVisitor, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, &pPeerFISock->m_character);	// 아이템 거래: 받기, non-countable
	m_ItemManager.UpdateItemCountByPointer(pMeMoney, -(pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach), IUT_BAZAAR_SELL);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 판매자 SPI 처리 
	ITEM_GENERAL tmpItemOnlyForLog_BazaarSeller = *pPeerMoney;
	tmpItemOnlyForLog_BazaarSeller.CurrentCount += pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach;

	// 2008-09-08 by cmkwon, 개인상점 로그 버그 수정 및 로그 추가 - (판매상점)기존 SendLogMessageITEMBazaarSend을 수정 함.
	CAtumLogSender::SendLogMessageITEMBazaarRecv(pPeerFISock, &tmpItemOnlyForLog_BazaarSeller, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, &this->m_character);	// 아이템 거래: 주기, non-countable
	pPeerFISock->m_ItemManager.UpdateItemCountByPointer(pPeerMoney, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, IUT_BAZAAR_SELL);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 개인 상점 아이템 처리
	if(FALSE == IS_COUNTABLE_ITEM(pBazaarItem->pBazaarItemInfo->Kind)
		|| pBazaarItem->nItemCnts == pRMsg->nAmount0)
	{
		pPeerFISock->m_bazaarManager.DeleteBazaarItem(pBazaarItem->nBuyItemIndex);
	}
	else	
	{
		pBazaarItem->nItemCnts	-= pRMsg->nAmount0;
	}

	peerbiLock.auto_unlock_cancel();
	peerigLock.auto_unlock_cancel();
	meigLock.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 메시지 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_SELL_BUY_ITEM_OK, T_FC_BAZAAR_SELL_BUY_ITEM_OK, pSBuyItemOK, SendBuf);
	pSBuyItemOK->itemUID		= pRMsg->itemUID;
	pSBuyItemOK->nAmount0		= pRMsg->nAmount0;
	pSBuyItemOK->clientIndex0	= pRMsg->clientIndex0;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_BUY_ITEM_OK));

	pSBuyItemOK->clientIndex0	= this->GetCharacter()->ClientIndex;
	pPeerFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_BUY_ITEM_OK));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_PUT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-27 ~ 2006-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_PUT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_BUY_PUT_ITEM
		, MSG_FC_BAZAAR_BUY_PUT_ITEM, pRMsg);

	if(0 >= pRMsg->nAmount
		|| MAX_ITEM_COUNTS <= (INT64)pRMsg->nAmount * (INT64)pRMsg->nEachPrice)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_DB_INVALID_PARAMETER);
		return RES_BREAK;
	}

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);


	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pRMsg->itemNum0);
	if(NULL == pItemInfo)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->itemNum0);
		return RES_BREAK;
	}

	if(FALSE == this->IsTransferItem(pItemInfo, TRUE))
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}


	if(FALSE == IS_COUNTABLE_ITEM(pItemInfo->Kind))
	{
		pRMsg->nAmount			= 1;
	}
	else
	{
		ITEM_GENERAL *pMeItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pRMsg->itemNum0);
		if(pMeItemG
			&& MAX_ITEM_COUNTS <= (INT64)pMeItemG->CurrentCount + (INT64)pRMsg->nAmount)		
		{
			SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
			return RES_BREAK;
		}
	}

	ITEM_GENERAL *pSPIItemG = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pSPIItemG)
	{
		if(NULL == pSPIItemG)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	if(m_bazaarManager.GetTotalPrice() + (INT64)pRMsg->nAmount * (INT64)pRMsg->nEachPrice > pSPIItemG->CurrentCount)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	int nBuyItemIndex = 0;
	Err_t errCode = m_bazaarManager.AddBuyItem(&nBuyItemIndex, pItemInfo, pRMsg->nAmount, pRMsg->nEachPrice);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_PUT_ITEM, errCode);
		return RES_BREAK;
	}

	bmLock.auto_unlock_cancel();
	igLock.auto_unlock_cancel();


	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_BUY_PUT_ITEM_OK, T_FC_BAZAAR_BUY_PUT_ITEM_OK, pSItemOK, SendBuf);
	pSItemOK->itemNum0			= pRMsg->itemNum0;
	pSItemOK->nBuyItemIndex0	= nBuyItemIndex;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_BUY_PUT_ITEM_OK));

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_CANCEL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_CANCEL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_BUY_CANCEL_ITEM
		, MSG_FC_BAZAAR_BUY_CANCEL_ITEM, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_CANCEL_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	if(BAZAAR_STATE_READY != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_CANCEL_ITEM, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	SBazaarItem *pBazaarItem = m_bazaarManager.FindBazaarItemByBazaarIndexNoLock(pRMsg->nBuyItemIndex0);
	if(NULL == pBazaarItem)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_CANCEL_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	m_bazaarManager.DeleteBazaarItem(pBazaarItem->nBuyItemIndex);

	bmLock.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_BUY_CANCEL_ITEM_OK, T_FC_BAZAAR_BUY_CANCEL_ITEM_OK, pSCancelOK, SendBuf);
	pSCancelOK->nBuyItemIndex0	= pRMsg->nBuyItemIndex0;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_BUY_CANCEL_ITEM_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_START(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_BUY_START
		, MSG_FC_BAZAAR_BUY_START, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_START, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_BUY_START, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());

	if(BAZAAR_STATE_READY != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_START, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	if(m_bazaarManager.IsEmptyBazaar())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_START, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if(0 >= strlen(pRMsg->szBazaarName))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_START, ERR_PROTOCOL_INVALID_CHARACTER_STATE);
		return RES_BREAK;
	}

	m_bazaarManager.SetBazaarName(pRMsg->szBazaarName);
	m_bazaarManager.SetBazaarState(BAZAAR_STATE_ACTIVE);	

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 주위 모든 유저에게 BazaarInfo 전송 준비
	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_INFO_OK, T_FC_BAZAAR_INFO_OK, pSBazaarInfoOK, SendBuf);
	this->MakeMSG_FC_BAZAAR_INFO_OKW(pSBazaarInfoOK);
	
	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Bazaar Buy  Shop open !! %s ItemKindCount(%d)\r\n", GetCharacterString(this->GetCharacter(), string()), m_bazaarManager.GetBazaarItemListPtr()->size());

	bmLock.auto_unlock_cancel();
	igLock.auto_unlock_cancel();	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 여기에서 해제 하는 것이 좋을 것 같음
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 자기 자신에게 개인 상점 시작 OK 전송
	SendAddMessageType(T_FC_BAZAAR_BUY_START_OK);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-26 by cmkwon, 주위 모든 유저에게 BazaarInfo 전송
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf, MSG_SIZE(MSG_FC_BAZAAR_INFO_OK),
															this->m_pCurrentFieldMapChannel, m_character.ClientIndex);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_REQUEST_ITEMLIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 바자구매 상점에서 판매자가 구매 아이템 리스트 요청하는 프로토콜
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_REQUEST_ITEMLIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_BUY_REQUEST_ITEMLIST
		, MSG_FC_BAZAAR_BUY_REQUEST_ITEMLIST, pRMsg);

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_REQUEST_ITEMLIST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_BUY_REQUEST_ITEMLIST, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - T_FC_BAZAAR_BUY_REQUEST_ITEMLIST, 바자구매 상점에서 판매자가 구매 아이템 리스트 요청시 판매자 개인 상점을 오픈 중인지 체크
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_REQUEST_ITEMLIST, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}

	CFieldIOCPSocket *pPeerFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->clientIndex0);
	if(NULL == pPeerFISock
		|| FALSE == pPeerFISock->IsValidCharacter()
		|| FALSE == pPeerFISock->GetCharacter()->CharacterMode)
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}

	if(REQUERED_BAZAAR_DISTANCE < D3DXVec3Length(&(m_character.PositionVector - pPeerFISock->GetCharacter()->PositionVector)))
	{
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_PROTOCOL_TOO_FAR_TO_DO);
		return RES_BREAK;
	}

	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BAZAAR, (0==m_backupRace)?m_character.Race:m_backupRace, m_character.InfluenceType,
		(0==pPeerFISock->m_backupRace)?pPeerFISock->m_character.Race:pPeerFISock->m_backupRace, pPeerFISock->m_character.InfluenceType))
	{// 2006-08-07 by cmkwon, 관리자/운영자 거래 체크
		SendErrorMessage(T_FC_BAZAAR_SELL_REQUEST_ITEMLIST, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	if(FALSE == pPeerFISock->SendBazaarItemList(this, BAZAAR_TYPE_BUY))
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_REQUEST_ITEMLIST, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_SELL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - 바자구매 상점에서 판매자가 판매 요청하는 프로토콜
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BAZAAR_BUY_SELL_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BAZAAR_BUY_SELL_ITEM
		, MSG_FC_BAZAAR_BUY_SELL_ITEM, pRMsg);

	if(0 >= pRMsg->nAmount0)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_DB_INVALID_PARAMETER);
		return RES_BREAK;
	}

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2008-10-30 by cmkwon, 베트남 아이템 복사 버그 수정 - T_FC_BAZAAR_BUY_SELL_ITEM, 바자구매 상점에서 아이템 판매 요청시 판매자가 개인 상점을 오픈 중인지 체크
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}

// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// 2006-08-03 by cmkwon, 투명상태에서는 개인 상점 불가
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_INVISIBLE_STATE);
		return RES_BREAK;
	}

	CFieldIOCPSocket *pPeerFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->clientIndex0);
	if(NULL == pPeerFISock
		|| FALSE == pPeerFISock->IsValidCharacter())
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BAZAAR, (0==m_backupRace)?m_character.Race:m_backupRace, m_character.InfluenceType,
		(0==pPeerFISock->m_backupRace)?pPeerFISock->m_character.Race:pPeerFISock->m_backupRace, pPeerFISock->m_character.InfluenceType))
	{// 2006-08-07 by cmkwon, 관리자/운영자 거래 체크
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_INVALID_BAZAAR);
		return RES_BREAK;
	}

	mt_auto_lock meigLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->itemUID);
	if (NULL == pItemG)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_BAZAAR_BUY_SELL_ITEM
	if(pItemG->UniqueNumber != pRMsg->itemUID
		|| pItemG->Possess != GetCharacter()->CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d\r\n"
			, GetProtocolTypeString(T_FC_BAZAAR_BUY_SELL_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemG, string()), pItemG->Possess, pRMsg->itemUID);
		return RES_BREAK;
	}

	if(0 != pItemG->PrefixCodeNum
		|| 0 != pItemG->SuffixCodeNum
		|| this->GetVectEnchantListPtr(pRMsg->itemUID))
	{// 2006-07-27 by cmkwon, 기본 아이템 체크
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
	if(FALSE == this->IsTransferItem(pItemG, TRUE))
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if(FALSE == IS_COUNTABLE_ITEM(pItemG->Kind))
	{
		pRMsg->nAmount0		= 1;
	}
	else
	{
		if(pItemG->CurrentCount < pRMsg->nAmount0)
		{
			SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
			return RES_BREAK;
		}
	}

	ITEM_GENERAL *pMeMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
 	if(NULL == pMeMoney)
 	{
		if(NULL == pMeMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
 		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, MONEY_ITEM_NUMBER);
		return RES_BREAK;
 	}

	mt_auto_lock peerigLock(&pPeerFISock->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock peerbiLock(pPeerFISock->m_bazaarManager.GetBazaarItemListPtr());

	SBazaarItem *pBazaarItem = pPeerFISock->m_bazaarManager.FindBazaarItemByBazaarIndexNoLock(pRMsg->nBuyItemIndex0);
	if(NULL == pBazaarItem)
	{
 		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_BAZAAR_NO_SUCH_ITEM, pRMsg->nBuyItemIndex0);
		return RES_BREAK;
	}

	// 2010-01-26 by cmkwon, 바자구매상점 버그 수정(ItemNum 체크) - 
	if(pItemG->ItemNum != pBazaarItem->pBazaarItemInfo->ItemNum)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_INVALID_ITEMNUM, pItemG->ItemNum, pBazaarItem->pBazaarItemInfo->ItemNum);
		return RES_BREAK;
	}

	if(pBazaarItem->nItemCnts < pRMsg->nAmount0)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
		return RES_BREAK;
	}

	ITEM_GENERAL *pPeerMoney = pPeerFISock->m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pPeerMoney)
	{
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

 	if(pPeerMoney->CurrentCount < (INT64)pRMsg->nAmount0 * (INT64)pBazaarItem->nItemPriceOfEach)
 	{
 		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
 		return RES_BREAK;
 	}
	if(MAX_ITEM_COUNTS < (INT64)pMeMoney->CurrentCount + (INT64)pRMsg->nAmount0 * (INT64)pBazaarItem->nItemPriceOfEach)
	{// 2006-08-03 by cmkwon
 		SendErrorMessage(T_FC_BAZAAR_SELL_BUY_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
 		return RES_BREAK;
	}

	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
	if(pPeerFISock->m_ItemManager.GetInventoryItemCounts() >= pPeerFISock->m_ItemManager.GetMaxInventoryCount())
	{// 2007-10-30 by cmkwon, 버그 수정 - CAtumSJ::GetMaxInventorySize() 함수에 인자로 상대방의 멤버쉽 플래그 넣어 줘야함
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM);
		return RES_BREAK;
	}

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 개인상점 판매
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 개인상점 판매
	if ( 0 != pItemG->ShapeItemNum && SHAPE_STAT_INIT_LEVEL < pItemG->FixedTermShape.nStatLevel )
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0009);
		SendErrorMessage(T_FC_BAZAAR_BUY_SELL_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
#endif
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 개인상점 판매

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매상점 주인에게 아이템 추가
	pPeerFISock->BazaarInsertItem(this, pItemG, pRMsg->nAmount0, IUT_BAZAAR_BUY);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매상점 고객의 SPI 처리 
	ITEM_GENERAL tmpItemOnlyForLog_BazaarBuyVisitor = *pMeMoney;
	tmpItemOnlyForLog_BazaarBuyVisitor.CurrentCount += pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach;
	CAtumLogSender::SendLogMessageITEMBazaarRecv(this, &tmpItemOnlyForLog_BazaarBuyVisitor, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, &pPeerFISock->m_character);	// 아이템 거래: 받기, non-countable
	m_ItemManager.UpdateItemCountByPointer(pMeMoney, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, IUT_BAZAAR_BUY);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매상점 주인의 SPI 처리
	ITEM_GENERAL tmpItemOnlyForLog_BazaarBuyer = *pPeerMoney;
	tmpItemOnlyForLog_BazaarBuyer.CurrentCount -= pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach;
	CAtumLogSender::SendLogMessageITEMBazaarSend(pPeerFISock, &tmpItemOnlyForLog_BazaarBuyer, pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach, &this->m_character);	// 아이템 거래: 주기, non-countable
	pPeerFISock->m_ItemManager.UpdateItemCountByPointer(pPeerMoney, -(pRMsg->nAmount0 * pBazaarItem->nItemPriceOfEach), IUT_BAZAAR_BUY);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 구매상점 아이템 처리
	if(FALSE == IS_COUNTABLE_ITEM(pBazaarItem->pBazaarItemInfo->Kind)
		|| pBazaarItem->nItemCnts == pRMsg->nAmount0)
	{
		pPeerFISock->m_bazaarManager.DeleteBazaarItem(pBazaarItem->nBuyItemIndex);
	}
	else	
	{
		pBazaarItem->nItemCnts	-= pRMsg->nAmount0;
	}

	peerbiLock.auto_unlock_cancel();
	peerigLock.auto_unlock_cancel();
	meigLock.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 메시지 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_BUY_SELL_ITEM_OK, T_FC_BAZAAR_BUY_SELL_ITEM_OK, pSBuyItemOK, SendBuf);
	pSBuyItemOK->itemUID		= pRMsg->itemUID;
	pSBuyItemOK->nBuyItemIndex0	= pRMsg->nBuyItemIndex0;
	pSBuyItemOK->nAmount0		= pRMsg->nAmount0;
	pSBuyItemOK->clientIndex0	= pRMsg->clientIndex0;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_BUY_SELL_ITEM_OK));

	pSBuyItemOK->clientIndex0	= this->GetCharacter()->ClientIndex;
	pPeerFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_BUY_SELL_ITEM_OK));

	return RES_RETURN_TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 2012-06-08 by jhseol, 아레나 추가개발part2 - 케릭터 : 타입 복사
///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_PLAY_CHARACTER_TYPE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 플레이 할 케릭터 타입 설정
/// \author		jhseol
/// \date		2012-06-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_PLAY_CHARACTER_TYPE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_PLAY_CHARACTER_TYPE
		, MSG_FC_ARENA_PLAY_CHARACTER_TYPE, pRMsg);
	
	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_PLAY_CHARACTER_TYPE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	m_nPlayCharacterType = pRMsg->PlayCharacterType;

	if(TRUE == g_pFieldGlobal->IsArenaServer())
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(this->m_ArenaInfo.TeamNum);
	}
	
	return RES_RETURN_TRUE;
}
// end 2012-06-08 by jhseol, 아레나 추가개발part2 - 케릭터 : 타입 복사

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-23 ~ 2007-04-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_REQUEST_TEAM
		, MSG_FC_ARENA_REQUEST_TEAM, pRMsg);
	
	if(this->m_character.ClientIndex != pRMsg->ClientIndex)
	{
		SendErrorMessage(T_FC_ARENA_REQUEST_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_REQUEST_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 방 목록 요청 사항을 처리한다.
	this->ms_pFieldIOCP->m_ArenaManager.SendRequestTeamInfo(this, pRMsg->ArenaMode, pRMsg->StartTeamNum, pRMsg->RequestTeamState, pRMsg->ArenaMap);	// 2012-04-12 by jhseol, 아레나 추가개발 - 선택한 아레나 맵 파라미터 추가
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_CREATE_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-23 ~ 2007-04-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_CREATE_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_CREATE_TEAM
		, MSG_FC_ARENA_CREATE_TEAM, pRMsg);
	
	if(this->m_character.ClientIndex != pRMsg->ClientIndex)
	{
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-30 by dhjin, 아레나 활동이 없어야 팀 생성을 할 수 있다.
	if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_ARENA_STATE);
		return RES_BREAK;		
	}
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 상태 체크
	if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState ) {
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_INFINITY_STATE);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 세력 선택하지 않았으면 오류
	if(COMPARE_INFLUENCE(this->m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_REQ_CHOOSE_INFLUENCE_TYPE);
		return RES_BREAK;
	}

	// 2012-08-24 by jhseol, 아레나 버그수정 - 입장레벨 체크 추가
	// 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
#ifdef SC_ARENA_EX_1ST_JHSEOL_MSPARK
#ifndef SC_ARENA_EX_1ST_RESTORE_JHSEOL_MSPARK
	if( this->m_character.Level < ARENA_STAGE_START_LEVEL || this->m_character.Level > ARENA_STAGE_A_END_LEVEL)
	{
		return RES_BREAK;
	}
#endif
#endif
	// end 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
	// end 2012-08-24 by jhseol, 아레나 버그수정 - 입장레벨 체크 추가

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 미션 진행중인 유저는 참가 불가
//	if(this->GetCharacterQuestInProgress())
//	{
//		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_PROTOCOL_QUEST_IS_IN_PROGRESS);
//		return RES_BREAK;
//	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 모선전, 거점전일 때는 참가 불가
// 2008-01-03 by dhjin, 아레나 통합 - 클라이언트에서 처리
//	if(this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint())
//	{
//		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_BOSS_STRATEGYPOINT_STATE_SUMMON);
//		return RES_BREAK;
//	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 지도자의 광휘를 착용한 상태에서는 신청할 수 없다.
// 2008-01-03 by dhjin, 아레나 통합 - 지도자의광휘 아이템을 아레나 서버로 복사하지 않는다.
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//	ITEM_GENERAL *pBCULeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_BCU_LEADER, ITEM_IN_CHARACTER);
//	ITEM_GENERAL *pANILeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_ANI_LEADER, ITEM_IN_CHARACTER);
//	if( (pBCULeaderItem && WEAR_NOT_ATTACHED != pBCULeaderItem->Wear)
//		|| (pANILeaderItem && WEAR_NOT_ATTACHED != pANILeaderItem->Wear) )
//	{
//		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION);
//		return RES_BREAK;		
//	}
//	igLock.auto_unlock_cancel();

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-15 by dhjin, 파티전 여단전 일때는 생성 불가
// 2008-01-03 by dhjin, 아레나 통합 - 체크 루틴에서 제외
//	if (this->IsPartyBattleState())
//	{
//		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_PROTOCOL_DOING_PARTY_BATTLE);
//		return RES_BREAK;
//	}
//	
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-15 by dhjin, 여단전 일대는 생성 불가.
//	mt_auto_lock mtGW(ms_pFieldIOCP->m_GuildWarManager.GetmtmapGuildWarPtr());
//	if (ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(this->GetCharacter()->GuildUniqueNumber))
//	{
//		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_PROTOCOL_DOING_GUILDWAR_BATTLE);
//		return RES_BREAK;
//	}
// 	mtGW.auto_unlock_cancel();

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 생성
	INT	nTeamNum =	this->ms_pFieldIOCP->m_ArenaManager.CreateTeam(pRMsg, this);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 생성 실패
	if(STATE_ERROR == nTeamNum)
	{
		SendErrorMessage(T_FC_ARENA_CREATE_TEAM, ERR_ARENA_CREATE_TEAM);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, Arena 상태
	this->m_ArenaInfo.ArenaMode =	pRMsg->ArenaMode;
	this->m_ArenaInfo.State		=	ARENA_STATE_JOINING;
	this->m_ArenaInfo.TeamNum	=	nTeamNum;
	this->m_ArenaInfo.ReadyButtonClickTime.SetCurrentDateTime();
	this->m_ArenaInfo.ReadyButtonClickTime.AddDateTime(0,0,0,0,0,-5);

	// 2008-01-03 by dhjin,  아레나 통합 - 필드서버에 케릭터 아레나 상태값 변경
	if(FALSE == this->SendMFSArenaStateChange(ARENA_STATE_JOINING))
	{
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 생성 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_CREATE_TEAM_OK, T_FC_ARENA_CREATE_TEAM_OK, pCreateTeamOK, SendBuf);
	pCreateTeamOK->ArenaMode	= pRMsg->ArenaMode;
	pCreateTeamOK->TeamSize		= this->ms_pFieldIOCP->m_ArenaManager.GetTeamSize(nTeamNum);
	pCreateTeamOK->TeamNum		= nTeamNum;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ARENA_CREATE_TEAM_OK));

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] CreateTeam - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s), TeamSize(%d)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName, pCreateTeamOK->TeamSize);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(nTeamNum);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 상태가 ARENA_STATE_READY이면 READY 상태를 알려준다.
	if(ARENA_STATE_READY == this->ms_pFieldIOCP->m_ArenaManager.GetTeamState(nTeamNum))
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberState(nTeamNum, ARENA_STATE_READY);
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_ENTER_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-23 ~ 2007-04-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_ENTER_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_ENTER_TEAM
		, MSG_FC_ARENA_ENTER_TEAM, pRMsg);
	
	if(this->m_character.ClientIndex != pRMsg->ClientIndex)
	{
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태가 아니어야 함
	if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_ARENA_STATE);
		return RES_BREAK;		
	}

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 상태 체크
	if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState ) {
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_INFINITY_STATE);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 세력 선택하지 않았으면 오류
	if(COMPARE_INFLUENCE(this->m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_REQ_CHOOSE_INFLUENCE_TYPE);
		return RES_BREAK;
	}

// 2007-05-15 by dhjin, 미션 진행중에도 아레나 참가 가능
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-04-26 by dhjin, 미션 진행중인 유저는 참가 불가
//	if(this->GetCharacterQuestInProgress())
//	{
//		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_PROTOCOL_QUEST_IS_IN_PROGRESS);
//		return RES_BREAK;
//	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 모선전, 거점전일 때는 참가 불가
// 2008-01-03 by dhjin, 아레나 통합 - 클라이언트에서 처리
//	if(this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint())
//	{
//		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_BOSS_STRATEGYPOINT_STATE_SUMMON);
//		return RES_BREAK;
//	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 지도자의 광휘를 착용한 상태에서는 신청할 수 없다.
// 2008-01-03 by dhjin, 아레나 통합 - 지도자의광휘 아이템을 아레나 서버로 복사하지 않는다.
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//	ITEM_GENERAL *pBCULeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_BCU_LEADER, ITEM_IN_CHARACTER);
//	ITEM_GENERAL *pANILeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_ANI_LEADER, ITEM_IN_CHARACTER);
//	if( (pBCULeaderItem && WEAR_NOT_ATTACHED != pBCULeaderItem->Wear)
//		|| (pANILeaderItem && WEAR_NOT_ATTACHED != pANILeaderItem->Wear) )
//	{
//		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION);
//		return RES_BREAK;		
//	}
//	igLock.auto_unlock_cancel();

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-15 by dhjin, 파티전 여단전 일때는 생성 불가
// 2008-01-03 by dhjin, 아레나 통합 - 체크 루틴에서 제외
//	if (this->IsPartyBattleState())
//	{
//		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_PROTOCOL_DOING_PARTY_BATTLE);
//		return RES_BREAK;
//	}
//	
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-15 by dhjin, 여단전 일대는 생성 불가.
//	mt_auto_lock mtGW(ms_pFieldIOCP->m_GuildWarManager.GetmtmapGuildWarPtr());
//	if (ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(this->GetCharacter()->GuildUniqueNumber))
//	{
//		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, ERR_PROTOCOL_DOING_GUILDWAR_BATTLE);
//		return RES_BREAK;
//	}	
//	mtGW.auto_unlock_cancel();
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 추가 
	Err_t errCode = this->ms_pFieldIOCP->m_ArenaManager.InsertMember(pRMsg, this);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ARENA_ENTER_TEAM, errCode);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, Arena 상태 
	this->m_ArenaInfo.ArenaMode =	pRMsg->ArenaMode;
	this->m_ArenaInfo.State		=	ARENA_STATE_JOINING;
	this->m_ArenaInfo.TeamNum	=	pRMsg->TeamNum;
	this->m_ArenaInfo.ReadyButtonClickTime.SetCurrentDateTime();
	this->m_ArenaInfo.ReadyButtonClickTime.AddDateTime(0,0,0,0,0,-5);

	// 2008-01-03 by dhjin,  아레나 통합 - 필드서버에 케릭터 아레나 상태값 변경
	if(FALSE == this->SendMFSArenaStateChange(ARENA_STATE_JOINING))
	{
		return RES_BREAK;
	}

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] EnterTeam - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 입장 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_ENTER_TEAM_OK, T_FC_ARENA_ENTER_TEAM_OK, pEnterTeamOK, SendBuf);
	pEnterTeamOK->ArenaMode		= pRMsg->ArenaMode;
	pEnterTeamOK->TeamSize		= this->ms_pFieldIOCP->m_ArenaManager.GetTeamSize(pRMsg->TeamNum);
	pEnterTeamOK->TeamNum		= pRMsg->TeamNum;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ARENA_ENTER_TEAM_OK));

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(pRMsg->TeamNum);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 상태가 ARENA_STATE_READY이면 READY 상태를 알려준다.
	if(ARENA_STATE_READY == this->ms_pFieldIOCP->m_ArenaManager.GetTeamState(pRMsg->TeamNum))
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberState(pRMsg->TeamNum, ARENA_STATE_READY);
	}
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REAVE_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-23 ~ 2007-04-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REAVE_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_REAVE_TEAM
		, MSG_FC_ARENA_REAVE_TEAM, pRMsg);
	
	if(this->m_character.ClientIndex != pRMsg->ClientIndex)
	{
		SendErrorMessage(T_FC_ARENA_REAVE_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ARENA_REAVE_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-03 by dhjin, 메세지 체크
	if(FALSE == this->m_ArenaInfo.IsValidArenaState()			// 2007-05-14 by cmkwon, 체크추가
		|| this->m_ArenaInfo.ArenaMode != pRMsg->ArenaMode
		|| this->m_ArenaInfo.TeamNum != pRMsg->TeamNum)
	{
		SendErrorMessage(T_FC_ARENA_REAVE_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 삭제
	Err_t errCode = this->ms_pFieldIOCP->m_ArenaManager.DeleteMember(this);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ARENA_REAVE_TEAM, errCode);
		return RES_BREAK;
	}

	// 2008-01-03 by dhjin,  아레나 통합 - 필드서버에 케릭터 아레나 상태값 변경
	if(FALSE == this->SendMFSArenaStateChange(ARENA_STATE_NONE))
	{
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-03 by dhjin, 아레나에서 떠난 상태 정보 전송
	this->SendAddMessageType(T_FC_ARENA_REAVE_TEAM_OK);


	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, Arena 상태
	this->m_ArenaInfo.ResetArenaInfo();

	//////////////////////////////////////////////////////////////////////
	// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 경기가 끝나면 속해 있던 팀번호를 초기화 해준다
	INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_ARENA_TEAM_NUM, T_FI_PARTY_ARENA_TEAM_NUM, msgArenaTeamNum, msgArenaTeamNumBuf);
	msgArenaTeamNum->TeamNum = this->m_ArenaInfo.TeamNum;
	msgArenaTeamNum->CharacterUniqueNumber = this->m_character.CharacterUniqueNumber;
	this->ms_pFieldIOCP->m_pIMWinSocket->Write((char*)msgArenaTeamNumBuf, MSG_SIZE(MSG_FI_PARTY_ARENA_TEAM_NUM));
	// end 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 경기가 끝나면 속해 있던 팀번호를 초기화 해준다
	//////////////////////////////////////////////////////////////////////

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_TEAM_READY_FINISH(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-05-02 ~ 2007-05-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_TEAM_READY_FINISH(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	// 2007-07-11 by cmkwon, 아레나블럭 시스템 구현 - T_FC_ARENA_TEAM_READY_FINISH
	int nRemainMinute = 0;
	if(ms_pFieldIOCP->m_arenaBlockManager.IsExistChatBlockList(&nRemainMinute, m_character.CharacterName))
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH, ERR_ARENA_BLOCKED, nRemainMinute);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태 ARENA_STATE_READY가 아니면 올바른 상태가 아니다.
	if(ARENA_STATE_JOINING != this->m_ArenaInfo.State
		&&  ARENA_STATE_READY != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH, ERR_ARENA_STATE);
		return RES_BREAK;		
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 모선전, 거점전일 때는 참가 불가
// 2008-01-03 by dhjin, 아레나 통합 - 클라이언트에서 처리
//	if(this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint())
//	{
//		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH, ERR_BOSS_STRATEGYPOINT_STATE_SUMMON);
//		return RES_BREAK;
//	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-08 by dhjin, 키눌림 시간 비교, 3초 딜레이가 지나지 않았다면 리턴한다.
	ATUM_DATE_TIME tmCurTime;
	tmCurTime.SetCurrentDateTime();
	if(ARENA_READYBUTTON_INTERVAL > tmCurTime.GetTimeDiffTimeInSeconds(this->m_ArenaInfo.ReadyButtonClickTime))
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH, ERR_COUNTDOWN_NOT_ENOUGH_TIME,
			tmCurTime.GetTimeDiffTimeInSeconds(this->m_ArenaInfo.ReadyButtonClickTime), 0,
			(char*)(m_ArenaInfo.ReadyButtonClickTime.GetCurrentDateTimeString(STRNBUF(SIZE_MAX_SQL_DATETIME_STRING))));
		return RES_BREAK;	
	}
	this->m_ArenaInfo.ReadyButtonClickTime = tmCurTime;

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태 ARENA_STATE_READY_FINISH 로 변경
	this->m_ArenaInfo.State	= ARENA_STATE_READY_FINISH;

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(this->m_ArenaInfo.TeamNum);

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] TeamReadyFinish - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName);

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 팀원이 모두 ARENA_STATE_READY_FINISH인지 체크하여 TRUE이면 매칭을 시작한다.
	if(this->ms_pFieldIOCP->m_ArenaManager.ChectTeamFullReadyFinish(this->m_ArenaInfo.TeamNum))
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendTeamMatchIngState(this->m_ArenaInfo.TeamNum);
		
		if(!this->ms_pFieldIOCP->m_ArenaManager.TeamMatch(this->m_ArenaInfo.TeamNum))
		{
			return RES_BREAK;
		}
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult Process_FC_ARENA_TEAM_READY_FINISH_CANCEL(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-05-04 ~ 2007-05-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_TEAM_READY_FINISH_CANCEL(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH_CANCEL, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-08 by dhjin, 키눌림 시간 비교, 3초 딜레이가 지나지 않았다면 리턴한다.
	ATUM_DATE_TIME tmCurTime;
	tmCurTime.SetCurrentDateTime();
	if(ARENA_READYBUTTON_INTERVAL > tmCurTime.GetTimeDiffTimeInSeconds(this->m_ArenaInfo.ReadyButtonClickTime))
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH_CANCEL, ERR_COUNTDOWN_NOT_ENOUGH_TIME,
			tmCurTime.GetTimeDiffTimeInSeconds(this->m_ArenaInfo.ReadyButtonClickTime), 0,
			(char*)(m_ArenaInfo.ReadyButtonClickTime.GetCurrentDateTimeString(STRNBUF(SIZE_MAX_SQL_DATETIME_STRING))));
		return RES_BREAK;	
	}
	this->m_ArenaInfo.ReadyButtonClickTime = tmCurTime;

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태 ARENA_STATE_READY_FINISH가 아니면 올바른 상태가 아니다.
	if(ARENA_STATE_FIGHTING_WARREADY == this->ms_pFieldIOCP->m_ArenaManager.GetTeamState(this->m_ArenaInfo.TeamNum)
		&& ARENA_STATE_READY_FINISH != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_TEAM_READY_FINISH_CANCEL, ERR_ARENA_STATE);
		return RES_BREAK;		
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-05-04 by dhjin, 아레나 상태 변경 ARENA_STATE_READY로 변경
	this->m_ArenaInfo.State	= ARENA_STATE_READY;

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] TeamReadyFinishCancel - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName);

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-04 by dhjin, 팀이 꽉 차 있다면 상태를 ARENA_STATE_READY로 설정, 아니면 ARENA_STATE_JOINING로 변경
	if(this->ms_pFieldIOCP->m_ArenaManager.CheckTeamFullMember(this->m_ArenaInfo.TeamNum))
	{
		this->ms_pFieldIOCP->m_ArenaManager.SetTeamState(this->m_ArenaInfo.TeamNum, ARENA_STATE_READY);	
	}
	else
	{
		this->ms_pFieldIOCP->m_ArenaManager.SetTeamState(this->m_ArenaInfo.TeamNum, ARENA_STATE_JOINING);	
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(this->m_ArenaInfo.TeamNum);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_ENTER_ROOM_WARP(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-05-04 ~ 2007-05-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_ENTER_ROOM_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ARENA_ENTER_ROOM_WARP
		, MSG_FC_ARENA_ENTER_ROOM_WARP, pRMsg);
	
	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ARENA_ENTER_ROOM_WARP, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	//////////////////////////////////////////////////////////////////////////
	// 2008-02-21 by dhjin, 아레나 통합 - '/아레나이동' 명령어가 아니면 체크한다. 명령어로 아레나 서버로 이동하기 위한 필요루틴 ~!
	if(pRMsg->CheckCommand
		&& CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
	{
		this->m_ArenaInfo.Command	= TRUE;	
	}
	else
	{
		//////////////////////////////////////////////////////////////////////////
		// 2007-05-02 by dhjin, 아레나 상태 ARENA_STATE_READY가 아니면 올바른 상태가 아니다.
		if(ARENA_STATE_FIGHTING_WARREADY != this->m_ArenaInfo.State)
		{
			SendErrorMessage(T_FC_ARENA_ENTER_ROOM_WARP, ERR_ARENA_STATE);
			return RES_BREAK;		
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-04 by dhjin, 아레나 방으로 워프 시킨다
// 2008-01-04 by dhjin, 아레나 통합 - 필드 서버로 매칭 정보를 전송한다.
//	this->ms_pFieldIOCP->m_ArenaManager.WarpToDeathMatchRoom(this);
	CIOCPSocket	*	MFSSock = ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == MFSSock)
	{// 2007-12-28 by dhjin, 필드 서버에 대한 정보가 없으면 오류
		SendErrorMessage(T_FC_ARENA_ENTER_ROOM_WARP, ERR_NO_SUCH_FIELDSERVER);
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FtoA_ARENA_TEAM_MATCHING, T_FtoA_ARENA_TEAM_MATCHING, pSendMsg, SendBuf);
	pSendMsg->AccountUID				= this->m_character.AccountUniqueNumber;
	pSendMsg->AFSCharacterUID			= this->m_character.CharacterUniqueNumber;
	pSendMsg->AFSClientIndex			= this->m_character.ClientIndex;
	pSendMsg->MFSCharacterUID			= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pSendMsg->MFSClientIndex			= this->m_AfsNeedMfsInfo.MFSClientIdx;
	MFSSock->SendAddData(SendBuf, MSG_SIZE(MSG_FtoA_ARENA_TEAM_MATCHING));

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] EnterRoomWarp - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_FINISH_WARP(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-24 ~ 2007-04-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_FINISH_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ARENA_FINISH_WARP, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태 ARENA_STATE_WARFINISH 아니면 올바른 상태가 아니다.
	if(ARENA_STATE_FIGHTING_WARFINISH != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_FINISH_WARP, ERR_ARENA_STATE, 10000, this->m_ArenaInfo.State);
		return RES_BREAK;		
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-24 by dhjin, 마을로 워프 요청을 처리한다.
	this->ms_pFieldIOCP->m_ArenaManager.SendDeathMatchUserWarpCity(this->m_ArenaInfo.DeathMatchRoomNum, this);

//	// 2007-05-18 by cmkwon, 테스트 로그
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] FinishWarp - TeamNum(%4d) AState(%30s) DMRoomNum(%d) CharName(%s)\r\n" 
//			, m_ArenaInfo.TeamNum, GET_ARENA_STATE_STRING(m_ArenaInfo.State), m_ArenaInfo.DeathMatchRoomNum, m_character.CharacterName);

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(this->m_ArenaInfo.TeamNum);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_CREATE_TEAMINFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-04-26 ~ 2007-04-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_CREATE_TEAMINFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_REQUEST_CREATE_TEAMINFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-24 by dhjin, 팀을 생성하기 위한 DB정보를 전송한다.
	this->ms_pFieldIOCP->m_ArenaManager.SendCreatTeamInfo(this);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_OTHER_TEAM_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		상대 팀 정보를 전송
/// \author		dhjin
/// \date		2007-05-23 ~ 2007-05-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_REQUEST_OTHER_TEAM_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_REQUEST_OTHER_TEAM_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-23 by dhjin, 상대 팀 정보를 전송한다.
	this->ms_pFieldIOCP->m_ArenaManager.SendOtherTeamInfo(this);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ARENA_QUICK_ENTER_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		빠른 신청 키를 눌렀을 때 
/// \author		dhjin
/// \date		2007-06-05 ~ 2007-06-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_QUICK_ENTER_TEAM(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 아레나 상태가 아니어야 함
	if(ARENA_STATE_NONE != this->m_ArenaInfo.State)
	{
		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_ARENA_STATE);
		return RES_BREAK;		
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 세력 선택하지 않았으면 오류
	if(COMPARE_INFLUENCE(this->m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{
		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_REQ_CHOOSE_INFLUENCE_TYPE);
		return RES_BREAK;
	}
	
	// 2012-08-24 by jhseol, 아레나 버그수정 - 입장레벨 체크 추가
	// 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
#ifdef SC_ARENA_EX_1ST_JHSEOL_MSPARK
#ifndef SC_ARENA_EX_1ST_RESTORE_JHSEOL_MSPARK
	if( this->m_character.Level < ARENA_STAGE_START_LEVEL || this->m_character.Level > ARENA_STAGE_A_END_LEVEL)
	{
		return RES_BREAK;
	}
#endif
#endif
	// end 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
	// end 2012-08-24 by jhseol, 아레나 버그수정 - 입장레벨 체크 추가

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 모선전, 거점전일 때는 참가 불가
// 2008-01-03 by dhjin, 아레나 통합 - 클라이언트에서 처리
//	if(this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint())
//	{
//		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_BOSS_STRATEGYPOINT_STATE_SUMMON);
//		return RES_BREAK;
//	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-02 by dhjin, 지도자의 광휘를 착용한 상태에서는 신청할 수 없다.
// 2008-01-03 by dhjin, 아레나 통합 - 지도자의광휘 아이템을 아레나 서버로 복사하지 않는다.
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//	ITEM_GENERAL *pBCULeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_BCU_LEADER, ITEM_IN_CHARACTER);
//	ITEM_GENERAL *pANILeaderItem = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_BRIGHTNESS_OF_ANI_LEADER, ITEM_IN_CHARACTER);
//	if( (pBCULeaderItem && WEAR_NOT_ATTACHED != pBCULeaderItem->Wear)
//		|| (pANILeaderItem && WEAR_NOT_ATTACHED != pANILeaderItem->Wear) )
//	{
//		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION);
//		return RES_BREAK;		
//	}
//	igLock.auto_unlock_cancel();

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-15 by dhjin, 파티전 여단전 일때는 생성 불가
// 2008-01-03 by dhjin, 아레나 통합 - 체크 루틴에서 제외
//	if (this->IsPartyBattleState())
//	{
//		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_PROTOCOL_DOING_PARTY_BATTLE);
//		return RES_BREAK;
//	}
//	
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-15 by dhjin, 여단전 일대는 생성 불가.
//	mt_auto_lock mtGW(ms_pFieldIOCP->m_GuildWarManager.GetmtmapGuildWarPtr());
//	if (ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(this->GetCharacter()->GuildUniqueNumber))
//	{
//		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, ERR_PROTOCOL_DOING_GUILDWAR_BATTLE);
//		return RES_BREAK;
//	}	
//	mtGW.auto_unlock_cancel();
	
	BYTE CreateArenaMode = 0;
	BYTE CreateTeamSize = 0;
	INT CreateTeamNum = -1;
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 추가 
	Err_t errCode = this->ms_pFieldIOCP->m_ArenaManager.QuickInsertMember(this, &CreateArenaMode, &CreateTeamSize, &CreateTeamNum);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ARENA_QUICK_ENTER_TEAM, errCode);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, Arena 상태 
	this->m_ArenaInfo.ArenaMode =	CreateArenaMode;
	this->m_ArenaInfo.State		=	ARENA_STATE_JOINING;
	this->m_ArenaInfo.TeamNum	=	CreateTeamNum;
	this->m_ArenaInfo.ReadyButtonClickTime.SetCurrentDateTime();
	this->m_ArenaInfo.ReadyButtonClickTime.AddDateTime(0,0,0,0,0,-5);

	// 2008-01-03 by dhjin,  아레나 통합 - 필드서버에 케릭터 아레나 상태값 변경
	if(FALSE == this->SendMFSArenaStateChange(ARENA_STATE_JOINING))
	{
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 입장 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_ENTER_TEAM_OK, T_FC_ARENA_ENTER_TEAM_OK, pEnterTeamOK, SendBuf);
	pEnterTeamOK->ArenaMode		= CreateArenaMode;
	pEnterTeamOK->TeamSize		= CreateTeamSize;
	pEnterTeamOK->TeamNum		= CreateTeamNum;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ARENA_ENTER_TEAM_OK));

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀원 정보 보내기
	this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberList(CreateTeamNum);

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-23 by dhjin, 팀 상태가 ARENA_STATE_READY이면 READY 상태를 알려준다.
	if(ARENA_STATE_READY == this->ms_pFieldIOCP->m_ArenaManager.GetTeamState(CreateTeamNum))
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendTeamMemberState(CreateTeamNum, ARENA_STATE_READY);
	}

	return RES_RETURN_TRUE;
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 2008-01-08 by dhjin, 아레나 통합 -

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		
/// \author		dhjin
/// \date		2008-01-08 ~ 2008-01-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ARENA_CHARACTER_GAMESTART(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}	

// 2008-04-24 by dhjin, 핵쉴드 서버 연동 시스템 수정 - 예정
// 	Err_t err = this->SecurityClientInit();		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 
//	if(ERR_NO_ERROR != err)
//	{
//		SendErrorMessage(T_FC_ARENA_CHARACTER_GAMESTART, err);
//		return RES_RETURN_FALSE;
//	}	

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
//		this->SetDataArenaGameStart();
	if(INFINITY_STATE_READY <= this->m_InfinityPlayingInfo.InfinityState) {
		this->SetDataInfinityGameStart();
	}
	else {
		this->SetDataArenaGameStart();

		//////////////////////////////////////////////////////////////////////////
		// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 아레나 방 입장시 사용되는 파티생성 요청 패킷 생성
#ifdef SC_ARENA_EX_1ST_JHSEOL_MSPARK
		// 2012-08-09 by jhseol, 아레나 추가개발 - 관전자 버그 수정 : 관전자는 파티를 할 필요가 없음으로 다음의 루틴 생략
		if( m_ArenaInfo.WatchState || m_ArenaInfo.Command )
		{
			return RES_RETURN_TRUE;
		}
		// end 2012-08-09 by jhseol, 아레나 추가개발 - 관전자 버그 수정 : 관전자는 파티를 할 필요가 없음으로 다음의 루틴 생략
		CFieldIOCPSocket *pSock = NULL;
		// 2013-10-01 by jhseol, 아레나 크래쉬 수정 - CriticalSection을 mt_auto_lock으로 교체
		mt_auto_lock mta(ms_pFieldIOCP->m_ArenaManager.GetArenaTeamManagerPtr());
		CArenaTeam * ArenaTeamInfo = ms_pFieldIOCP->m_ArenaManager.FindTeam(this->m_ArenaInfo.TeamNum);
//		EnterCriticalSection(&m_criticalLevelAndExperience);	// 2013-02-13 by jhseol, 아레나 서버 크래쉬 예방 : 이미 사용중인 녀석을 활용 - Lock
//		CArenaTeam * ArenaTeamInfo = ms_pFieldIOCP->m_ArenaManager.GetArenaTeam(this->m_ArenaInfo.TeamNum);
		// end 2013-10-01 by jhseol, 아레나 크래쉬 수정 - CriticalSection을 mt_auto_lock으로 교체
		if(NULL == ArenaTeamInfo)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaTeamInfo Fine Fail!!\r\n");
			//LeaveCriticalSection(&m_criticalLevelAndExperience);	// 2013-10-01 by jhseol, 아레나 크래쉬 수정 - CriticalSection을 mt_auto_lock으로 교체	// 2013-02-13 by jhseol, 아레나 서버 크래쉬 예방 : 이미 사용중인 녀석을 활용 - unLock
			return RES_RETURN_TRUE;
		}
		vectorClientIndex * TeamMamba = ArenaTeamInfo->GetTeamList();
		if( NULL == TeamMamba )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] TeamMamba Fine Fail!!\r\n");
			//LeaveCriticalSection(&m_criticalLevelAndExperience);	// 2013-10-01 by jhseol, 아레나 크래쉬 수정 - CriticalSection을 mt_auto_lock으로 교체	// 2013-02-13 by jhseol, 아레나 서버 크래쉬 예방 : 이미 사용중인 녀석을 활용 - unLock
			return RES_RETURN_TRUE;
		}
		vectorClientIndex::iterator itr = TeamMamba->begin();
		for(; itr != TeamMamba->end(); itr++)
		{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 맴버들의 클라인덱스 번호로 소켓을 찾는다.
			// 2012-11-27 by jhseol, 간헐적 아레나 서버가 다운되는 현상. 코드수정 예외처리 추가
			if( itr == TeamMamba->end() || itr == NULL )	// 2013-10-01 by jhseol, 아레나 크래쉬 수정
			{
				break;
			}
			// end 2012-11-27 by jhseol, 간헐적 아레나 서버가 다운되는 현상. 코드수정 예외처리 추가
			pSock = ms_pFieldIOCP->GetFieldIOCPSocket(*itr);
			if(NULL == pSock)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] TeamMamba in pSock Fine Fail!!\r\n");
				continue;
			}
			if(m_character.CharacterUniqueNumber == pSock->m_character.CharacterUniqueNumber)
			{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 찾은 맴버가 자기 자신이면 패스 한다.
				continue;
			}
			if(NULL != pSock->m_pFieldParty)
			{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 찾은 맴버의 소켓정보에서 파티의 유뮤를 확인.
				if(SIZE_MAX_PARTY_MEMBER > pSock->m_pFieldParty->m_ListPartyMember.size())
				{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 파티 현제 인원을 확인. 6명 이하면은 가입 패킷 보내고 루프 탈출
					INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_REQUEST_INVITE_QUESTION_THE_ARENA, T_FC_PARTY_REQUEST_INVITE_QUESTION_THE_ARENA, pQuestion, pQuestionBuf);
					pQuestion->PartyID = pSock->m_pFieldParty->m_PartyID;
					//STRNCPY_MEMSET(pQuestion->MasterCharacterName, ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pSock->m_pFieldParty->GetMasterCharacterUniqueNumber())->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
					// 2013-05-16 by jhseol, 인피 재접속 시 파티지원 - 수정하면서 불표한 것으로 판단되어 주석처리함.
					SendAddData(pQuestionBuf, MSG_SIZE(MSG_FC_PARTY_REQUEST_INVITE_QUESTION_THE_ARENA));
					break;
				}
			}
		}
		if(itr == TeamMamba->end())
		{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 여기까지 욌다는것은 생성된 파티 혹은 가입할 수 있는 파티가 없음을 의미함.
			if(NULL == m_pFieldParty)
			{// 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티 : 파티가 없으면 파티생성 패킷을 보냄.
				SPARTY_INFO PartyInfo;
				MEMSET_ZERO(&PartyInfo, sizeof(SPARTY_INFO));
				PartyInfo.ExpDistributeType			= EXP_DISTRIBUTE_TYPE_DAMAGE;
				PartyInfo.FormationType				= FLIGHT_FORM_NONE;
				PartyInfo.ItemDistributeType		= ITEM_DISTRIBUTE_TYPE_DAMAGE;
				PartyInfo.MaxLevel					= CHARACTER_MAX_LEVEL;
				PartyInfo.MinLevel					= 1;
				PartyInfo.PartyInfluence			= m_character.InfluenceType;
				PartyInfo.PartyJoinType				= PARTY_JOIN_TYPE_FREE;
				PartyInfo.PartyLock					= FALSE;
				char chPartyName[3][256]			= {STRMSG_C_080610_0200, STRMSG_C_080610_0201, STRMSG_C_080610_0202};
				int nRandIdx = rand() %3;
				if(nRandIdx <0 || nRandIdx >= 3)
				{
					nRandIdx = 0;
				}
				memcpy(PartyInfo.PartyName, chPartyName[nRandIdx], SIZE_MAX_PARTY_NAME);
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_AUTO_CREATED_THE_ARENA, T_FC_PARTY_AUTO_CREATED_THE_ARENA, pSMsg, SendBuf);
				MEMSET_ZERO(pSMsg, sizeof(MSG_FC_PARTY_AUTO_CREATED_THE_ARENA));
				pSMsg->PartyInfo = PartyInfo;
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_PARTY_AUTO_CREATED_THE_ARENA));
			}
		}
		//LeaveCriticalSection(&m_criticalLevelAndExperience);	// 2013-10-01 by jhseol, 아레나 크래쉬 수정 - CriticalSection을 mt_auto_lock으로 교체	// 2013-02-13 by jhseol, 아레나 서버 크래쉬 예방 : 이미 사용중인 녀석을 활용 - unLock
		INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_ARENA_TEAM_NUM, T_FI_PARTY_ARENA_TEAM_NUM, msgArenaTeamNum, msgArenaTeamNumBuf);
		msgArenaTeamNum->TeamNum = this->m_ArenaInfo.TeamNum;
		msgArenaTeamNum->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		ms_pFieldIOCP->m_pIMWinSocket->Write((char*)msgArenaTeamNumBuf, MSG_SIZE(MSG_FI_PARTY_ARENA_TEAM_NUM));
		// end 2012-04-12 by jhseol, 아레나 추가개발 - 자동파티

		// 2012-06-21 by jhseol, 아레나 추가개발part2 - 아레나 전용 퀵슬롯 ( 0 = 메인, 1 = 아레나 )
		QPARAM_GET_QUICKSLOT *pQParam = new QPARAM_GET_QUICKSLOT;
		pQParam->AccountUID			= m_character.AccountUniqueNumber;
		pQParam->CharacterUID		= m_character.CharacterUniqueNumber;
		// 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
#ifdef SC_ARENA_EX_1ST_RESTORE_JHSEOL_MSPARK
		pQParam->SlotPurpose		= SLOT_PURPOSE_MAIN;
#else
		pQParam->SlotPurpose		= SLOT_PURPOSE_ARENA;
#endif	//#ifdef SC_ARENA_EX_1ST_RESTORE_JHSEOL_MSPARK
		// end 2012-09-14 by jhseol, 아레나 추가개발 restore - 리뉴얼 적용 상태에서 자신의 케릭터로만 플레이 하도록 수정
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Get_QuickSlot,this, m_character.AccountUniqueNumber, pQParam);
		// end 2012-06-21 by jhseol, 아레나 추가개발part2 - 아레나 전용 퀵슬롯 ( 0 = 메인, 1 = 아레나 )
#endif
	}

//	// 2007-05-18 by cmkwon, 테스트 로그	
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENACHECK] T_FC_ARENA_CHARACTER_GAMESTART ArenaCUID = %d, CUID = %d, AUID = %d\r\n"
//		, this->m_character.CharacterUniqueNumber, 0, this->m_character.AccountUniqueNumber);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		Tutorial 시작 
/// \author		dhjin
/// \date		2007-07-06 ~ 2007-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_START(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_TUTORIAL_START, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-07-06 by dhjin, Tutorial 정보를 설정한다.
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_LoadTutorialComplete, this, 0, NULL);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			INT	CFieldIOCPSocket::MakeMSG_FC_TUTORIAL_START_OK(STUTORIAL_LIST_INFO * o_pTutorialListInfo)
/// \brief		Tutorial 메세지 만들기
/// \author		dhjin
/// \date		2007-07-06 ~ 2007-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
INT	CFieldIOCPSocket::MakeMSG_FC_TUTORIAL_START_OK(STUTORIAL_LIST_INFO * o_pTutorialListInfo)
{
	INT	nTutorialListCount = 0;

	mt_auto_lock mta(&m_mtvectTutorialList);

	mtvectTutorialList::iterator itr(m_mtvectTutorialList.begin());
	for(; itr != m_mtvectTutorialList.end(); itr++)
	{
		o_pTutorialListInfo[nTutorialListCount].TutorialNum		= itr->TutorialNum;
		o_pTutorialListInfo[nTutorialListCount].TutorialComplete= itr->TutorialComplete;
		nTutorialListCount++;
	}

	return nTutorialListCount;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_COMPLETE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		Tutorial 완료 
/// \author		dhjin
/// \date		2007-07-06 ~ 2007-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_COMPLETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_TUTORIAL_COMPLETE
									, MSG_FC_TUTORIAL_COMPLETE, pRMsg);

	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_TUTORIAL_COMPLETE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}


	mt_auto_lock mta(&m_mtvectTutorialList);

	// 2007-07-09 by dhjin, 완료 정보 설정
	STUTORIAL_LIST_INFO *pTutorialData = this->GetTutorialDataNoLock(pRMsg->TutorialNum);
	if(NULL == pTutorialData)
	{
		SendErrorMessage(T_FC_TUTORIAL_COMPLETE, ERR_INVALID_TUTORIAL);
		return RES_BREAK;
	}
	BOOL bAlreadyCompleted	= FALSE;	// 2007-07-18 by dhjin, Tutorial 완료 체크 변수 
	if(pTutorialData->TutorialComplete)
	{// 이미 완료 상태 체크
		bAlreadyCompleted	= TRUE;
	}
	pTutorialData->TutorialComplete = TRUE;		// 2007-07-23 by cmkwon, 
	mta.auto_unlock_cancel();					// 2007-07-23 by cmkwon, 추가

	// 2007-07-06 by dhjin, 완료 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_TUTORIAL_COMPLETE_OK, T_FC_TUTORIAL_COMPLETE_OK, pTutorialComplete, SendBuf);
	pTutorialComplete->TutorialNum		= pRMsg->TutorialNum;

	if(bAlreadyCompleted)
	{// 2007-07-18 by dhjin, 이미 완료했다면 아이템 지급, 로그를 남기지 않는다.
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_TUTORIAL_COMPLETE_OK));
		return RES_RETURN_TRUE;
	}

	// 2007-07-23 by cmkwon, 아이템 지급 - Tutorial 완료 번호로 지급될 아이템을 찾아 지급한다.
	STUTORIAL_INFO *pTutorialInfo = ms_pFieldIOCP->GetTutorialInfo(pRMsg->TutorialNum);
	if(pTutorialInfo)
	{
		if(0 < pTutorialInfo->TutorialPayItem1 && 0 < pTutorialInfo->TutorialPayItemCount1)
		{
			if(this->m_ItemManager.InsertItemBaseByItemNum(pTutorialInfo->TutorialPayItem1, pTutorialInfo->TutorialPayItemCount1, IUT_TUTORIAL_PAY_ITEM))
			{
				pTutorialComplete->TutorialItemNum1		= pTutorialInfo->TutorialPayItem1;
				pTutorialComplete->TutorialItemCount1	= pTutorialInfo->TutorialPayItemCount1;
			}
		}
		if(0 < pTutorialInfo->TutorialPayItem2 && 0 < pTutorialInfo->TutorialPayItemCount2)
		{
			if(this->m_ItemManager.InsertItemBaseByItemNum(pTutorialInfo->TutorialPayItem2, pTutorialInfo->TutorialPayItemCount2, IUT_TUTORIAL_PAY_ITEM))
			{
				pTutorialComplete->TutorialItemNum2		= pTutorialInfo->TutorialPayItem2;
				pTutorialComplete->TutorialItemCount2	= pTutorialInfo->TutorialPayItemCount2;
			}
		}
		if(0 < pTutorialInfo->TutorialPayItem3 && 0 < pTutorialInfo->TutorialPayItemCount3)
		{
			if(this->m_ItemManager.InsertItemBaseByItemNum(pTutorialInfo->TutorialPayItem3, pTutorialInfo->TutorialPayItemCount3, IUT_TUTORIAL_PAY_ITEM))
			{
				pTutorialComplete->TutorialItemNum3		= pTutorialInfo->TutorialPayItem3;
				pTutorialComplete->TutorialItemCount3	= pTutorialInfo->TutorialPayItemCount3;
			}
		}
	}
	
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_TUTORIAL_COMPLETE_OK));

	// 2007-07-06 by dhjin, 로그를 남긴다.
	CAtumLogSender::SendLogMessageTutorialCOMPLETION(this, pRMsg->TutorialNum);

	// 2007-07-06 by dhjin, Tutorial 완료 DB에 업데이트 
	QPARAM_INSERT_TUTORIAL_COMPLETE *pQParam = new QPARAM_INSERT_TUTORIAL_COMPLETE;
	pQParam->CharacterUID		= this->m_character.CharacterUniqueNumber;
	pQParam->TutorialUID		= pRMsg->TutorialNum;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertTutorialComplete, this, m_character.AccountUniqueNumber, pQParam);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_END(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		Tutorial 종료
/// \author		dhjin
/// \date		2007-07-06 ~ 2007-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_END(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 2007-07-06 by dhjin, 종료 처리 완료 메세지 전송
	this->SendAddMessageType(T_FC_TUTORIAL_END_OK);

	// 2007-07-06 by dhjin, 마을로 워프
	this->WarpToCityMap();

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_WARP(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-07-16 ~ 2007-07-16
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_TUTORIAL_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_TUTORIAL_WARP, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2007-07-06 by dhjin, Tutorial 맵으로 워프
	this->WarpToMap(TUTORIAL_MAP_INDEX, 0);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_RESET_CHECK_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-20 ~ 2007-08-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
//ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_RESET_CHECK_START(const char* pPacket, int nLength, int &nBytesUsed)
//{
//	if(!this->IsValidCharacter())
//	{// 2007-08-20 by dhjin, 유효한 유저인지 체크 
//		SendErrorMessage(T_FC_OUTPOST_RESET_CHECK_START, ERR_INVALID_CHARACTER);
//		return RES_BREAK;
//	}
//
//	if(!ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber))
//	{// 2007-08-20 by dhjin, 여단장인지 체크 
//		SendErrorMessage(T_FC_OUTPOST_RESET_CHECK_START, ERR_PROTOCOL_NOT_GUILD_MASTER);
//		return RES_BREAK;		
//	}
//
//	if(!ms_pFieldIOCP->m_OutPostManager.CheckResetValidGuildUID(m_character.MapChannelIndex.MapIndex, m_character.GuildUniqueNumber))
//	{// 2007-08-20 by dhjin, 각인이 가능한 여단인지 체크 
//		SendErrorMessage(T_FC_OUTPOST_RESET_CHECK_START, ERR_PROTOCOL_GUILD_NOT_MATCHED);
//		return RES_BREAK;
//	}
//
//	this->SendAddMessageType(T_FC_OUTPOST_RESET_CHECK_START_OK);
//
//	return RES_RETURN_TRUE;
//}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_RESET_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-20 ~ 2007-08-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_RESET_START(const char* pPacket, int nLength, int &nBytesUsed)
{	
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_OUTPOST_RESET_START
									, MSG_FC_OUTPOST_RESET_START, pRMsg);

	CFieldMonster	*pMonster = m_pCurrentFieldMapChannel->GetFieldMonster(pRMsg->TargetIndex, 3);
	if(NULL == pMonster
		|| (BELL_OUTPOST_RESET_VCN != pMonster->MonsterInfoPtr->Belligerence
			&& BELL_OUTPOST_RESET_ANI != pMonster->MonsterInfoPtr->Belligerence))
	{// 2007-09-10 by dhjin, 전진기지 중앙 처리 장치가 아니면 오류
		SendErrorMessage(T_FC_OUTPOST_RESET_START, ERR_PROTOCOL_REQ_MONSTER_NOT_MATCHED);
		return RES_BREAK;
	}

	// 2007-08-20 by dhjin, T_FC_OUTPOST_RESET_CHECK_START에서 체크한 부분이지만 한 번 더 체크한다.
	if(!this->IsValidCharacter())
	{// 2007-08-20 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_OUTPOST_RESET_START, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!ms_pFieldIOCP->m_OutPostManager.CheckResetValidGuildUID(m_character.MapChannelIndex.MapIndex, m_character.GuildUniqueNumber))
	{// 2007-08-20 by dhjin, 각인이 가능한 여단인지 체크 
		SendErrorMessage(T_FC_OUTPOST_RESET_START, ERR_PROTOCOL_GUILD_NOT_MATCHED);
		return RES_BREAK;
	}

	if(!ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber))
	{// 2007-08-20 by dhjin, 여단장인지 체크 
		SendErrorMessage(T_FC_OUTPOST_RESET_START, ERR_PROTOCOL_NOT_GUILD_MASTER);
		return RES_BREAK;		
	}	

	// 2007-10-16 by cmkwon, 로그 추가 - SendOutPostResetStartByGuildCommander() 함수 인자 수정
	if(this->ms_pFieldIOCP->m_OutPostManager.SendOutPostResetStartByGuildCommander(m_character.MapChannelIndex.MapIndex, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber))
	{
		// 2007-09-10 by dhjin, 중앙처리 장치 바디컨디션을 바꾼다.
		CLEAR_BODYCON_BIT(pMonster->BodyCondition, BODYCON_MON_BUILDED);			// 2007-09-20 by cmkwon, 텔레포트 수정 - 
		SET_BODYCON_BIT(pMonster->BodyCondition,  BODYCON_MON_BUILDING);
		this->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pMonster, T_FN_MONSTER_CHANGE_BODYCONDITION);
		this->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pMonster, T_FC_MONSTER_CHANGE_BODYCONDITION);
		m_pCurrentFieldMapChannel->m_ChangeBodyConMonsterIndex	=	pRMsg->TargetIndex;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_NEXTWAR_INFO_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_NEXTWAR_INFO_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{// 2007-08-28 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_OUTPOST_NEXTWAR_INFO_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	BOOL	CheckGuildCommander = FALSE;

	if(ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber))
	{// 2007-08-28 by dhjin, 전진기지 점령 여단장인지 체크 
		CheckGuildCommander = TRUE;
	}
	
	BYTE	SendMsg[SIZE_MAX_PACKET];
	MEMSET_ZERO(SendMsg,SIZE_MAX_PACKET);
	INT		SendBuf = 0;
	ms_pFieldIOCP->m_OutPostManager.MakeMsgOutPostNextWarInfoRequest(m_character.MapChannelIndex.MapIndex, CheckGuildCommander, SendMsg, &SendBuf);
	this->SendAddData(SendMsg, SendBuf);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_NEXTWAR_SET_TIME(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_OUTPOST_NEXTWAR_SET_TIME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_OUTPOST_NEXTWAR_SET_TIME
									, MSG_FC_OUTPOST_NEXTWAR_SET_TIME, pRMsg);

	if(!this->IsValidCharacter())
	{// 2007-08-28 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_OUTPOST_NEXTWAR_SET_TIME, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(!ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber))
	{// 2007-08-28 by dhjin, 전진기지 점령 여단장인지 체크 
		SendErrorMessage(T_FC_OUTPOST_NEXTWAR_SET_TIME, ERR_PROTOCOL_GUILD_NOT_MATCHED);
		return RES_BREAK;
	}

	// 2007-08-28 by dhjin, 전진기지 다음 전쟁시간 설정. // 2007-11-05 by dhjin, OutPostNextWarTimeSetByChoiceUserW()로 함수명 변경
	// 2007-10-16 by cmkwon, 로그 추가 - OutPostNextWarTimeSetW() 함수 인자 수정
	Err_t errCode = ms_pFieldIOCP->m_OutPostManager.OutPostNextWarTimeSetByChoiceUserW(m_character.MapChannelIndex.MapIndex, pRMsg->OutPostNextWarSelectTimeChoice, m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_OUTPOST_NEXTWAR_SET_TIME, errCode);
		return RES_BREAK;
	}

	// 2007-08-28 by dhjin, 전진기지 다음 전쟁시간 설정 정보 전송.
	BYTE	SendMsg[SIZE_MAX_PACKET];
	MEMSET_ZERO(SendMsg,SIZE_MAX_PACKET);
	INT		SendBuf = 0;
	ms_pFieldIOCP->m_OutPostManager.MakeMsgOutPostNextWarInfoRequest(m_character.MapChannelIndex.MapIndex, TRUE, SendMsg, &SendBuf);
	this->SendAddData(SendMsg, SendBuf);

	// 2007-09-06 by dhjin,  전진기지 다음 시간 설정 정보를 모든 유저에게 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FC_OUTPOST_NEXTWAR_SET_TIME_OK, T_FC_OUTPOST_NEXTWAR_SET_TIME_OK, SendMsg2, SendBuf2);
	SendMsg2->MapIndex				= m_character.MapChannelIndex.MapIndex;
	SendMsg2->OutPostNextWarTime	= *(ms_pFieldIOCP->m_OutPostManager.GetOutPostNextWarTimeByCityMapIndex(m_character.MapChannelIndex.MapIndex));
	this->ms_pFieldIOCP->SendMessageToAllClients(SendBuf2, MSG_SIZE(MSG_FC_OUTPOST_NEXTWAR_SET_TIME_OK),INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	return RES_RETURN_TRUE;
}

//////////////////////////////////////////////////////////////////////////
// 2007-08-22 by dhjin, Notice

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_NOTICE_REQUEST
									, MSG_FC_INFO_NOTICE_REQUEST, pRMsg);

	if(!this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_INFO_NOTICE_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_NOTICE_REQUEST_OK, T_FC_INFO_NOTICE_REQUEST_OK, pSendMsg, Sendbuf);
	if(NULL != ms_pFieldIOCP->m_CityLeader.GetNotice(pRMsg->MapIndex))
	{
		STRNCPY_MEMSET(pSendMsg->NoticeString, ms_pFieldIOCP->m_CityLeader.GetNotice(pRMsg->MapIndex), SIZE_MAX_NOTICE);	
	}
	this->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_INFO_NOTICE_REQUEST_OK));

	// 2007-09-14 by dhjin, 전진기지 전쟁 시간 보내기, 차 후 다시 구조를 만든다. 
	BYTE	SendMsg2[SIZE_MAX_PACKET];
	MEMSET_ZERO(SendMsg2,SIZE_MAX_PACKET);
	INT		SendBuf2 = 0;
	ms_pFieldIOCP->m_OutPostManager.MakeMsgOutPostNextWarInfoRequest(2004, FALSE, SendMsg2, &SendBuf2);
	this->SendAddData(SendMsg2, SendBuf2);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_REG(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_REG(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_NOTICE_REG
									, MSG_FC_INFO_NOTICE_REG, pRMsg);
 	
	if(!this->IsValidCharacter()
		|| pRMsg->GuildUID != m_character.GuildUniqueNumber
		|| FALSE == ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber))
	{/// 2007-08-22 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_INFO_NOTICE_REG, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2007-08-22 by dhjin, 공지사항 등록
	this->ms_pFieldIOCP->m_CityLeader.SetNotice(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber, pRMsg->NoticeString);

	// 2007-08-22 by dhjin, DB에 공지사항 등록
	QPARAM_REG_NOTICE *pQParam	= new QPARAM_REG_NOTICE;
	pQParam->MapIndex			= m_character.MapChannelIndex.MapIndex;
	pQParam->CharacterUID		= m_character.CharacterUniqueNumber;
	if(NULL == pRMsg->NoticeString)
	{
		MEMSET_ZERO(pQParam->Notice, SIZE_MAX_NOTICE);
	}
	else
	{
		STRNCPY_MEMSET(pQParam->Notice, pRMsg->NoticeString, SIZE_MAX_NOTICE);
	}
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_RegNotice, NULL, NULL, pQParam);
	
	this->SendAddMessageType(T_FC_INFO_NOTICE_REG_OK);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_MODIFY(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_NOTICE_MODIFY(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_NOTICE_MODIFY
									, MSG_FC_INFO_NOTICE_MODIFY, pRMsg);
	
	if(!this->IsValidCharacter()
		|| pRMsg->GuildUID != m_character.GuildUniqueNumber
		|| FALSE == ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber))
	{/// 2007-08-22 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_INFO_NOTICE_MODIFY, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2007-08-22 by dhjin, 공지사항 등록
	this->ms_pFieldIOCP->m_CityLeader.SetNotice(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber, pRMsg->NoticeString);

	// 2007-08-22 by dhjin, DB에 공지사항 등록
	QPARAM_MODIFY_NOTICE *pQParam	= new QPARAM_MODIFY_NOTICE;
	pQParam->MapIndex			= m_character.MapChannelIndex.MapIndex;
	pQParam->CharacterUID		= m_character.CharacterUniqueNumber;
	if(NULL == pRMsg->NoticeString)
	{
		MEMSET_ZERO(pQParam->Notice, SIZE_MAX_NOTICE);
	}
	else
	{
		STRNCPY_MEMSET(pQParam->Notice, pRMsg->NoticeString, SIZE_MAX_NOTICE);
	}
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ModifyNotice, NULL, NULL, pQParam);
	
	this->SendAddMessageType(T_FC_INFO_NOTICE_MODIFY_OK);
	
	return RES_RETURN_TRUE;
}


//////////////////////////////////////////////////////////////////////////
// 2007-08-22 by dhjin, 판공비

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_EXPEDIENCYFUND_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_EXPEDIENCYFUND_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_EXPEDIENCYFUND_REQUEST
									, MSG_FC_INFO_EXPEDIENCYFUND_REQUEST, pRMsg);
	
	if(!this->IsValidCharacter()
		|| FALSE == ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(pRMsg->MapIndex, m_character.CharacterUniqueNumber))
	{/// 2007-08-22 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	SCITYLEADER_INFO	tmCityLeaderInfo;
	MEMSET_ZERO(&tmCityLeaderInfo, sizeof(SCITYLEADER_INFO));
	this->ms_pFieldIOCP->m_CityLeader.GetExpediencyfund(pRMsg->MapIndex, &tmCityLeaderInfo);

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_EXPEDIENCYFUND_REQUEST_OK, T_FC_INFO_EXPEDIENCYFUND_REQUEST_OK, pSendMsg, Sendbuf);
	pSendMsg->ExpediencyFund			= tmCityLeaderInfo.ExpediencyFund;
	pSendMsg->ExpediencyFundRate		= tmCityLeaderInfo.ExpediencyFundRate;
	pSendMsg->CumulativeExpediencyFund	= tmCityLeaderInfo.ExpediencyFundCumulative;
	this->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_INFO_EXPEDIENCYFUND_REQUEST_OK));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_EXPEDIENCYFUND_PAYBACK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_EXPEDIENCYFUND_PAYBACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_EXPEDIENCYFUND_PAYBACK
									, MSG_FC_INFO_EXPEDIENCYFUND_PAYBACK, pRMsg);
	
	if(0 >= pRMsg->ExpediencyFundPayBackCount
		|| MAX_ITEM_COUNTS <= pRMsg->ExpediencyFundPayBackCount)
	{// 2007-10-05 by cmkwon, 에러 체크
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, ERR_DB_INVALID_PARAMETER);
		return RES_BREAK;
	}

	if(!this->IsValidCharacter()
		|| FALSE == ms_pFieldIOCP->m_CityLeader.CheckIsValidCharacter(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber))
	{/// 2007-08-22 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	SCITYLEADER_INFO	tmCityLeaderInfo;
	MEMSET_ZERO(&tmCityLeaderInfo, sizeof(SCITYLEADER_INFO));
	this->ms_pFieldIOCP->m_CityLeader.GetExpediencyfund(m_character.MapChannelIndex.MapIndex, &tmCityLeaderInfo);
	if(tmCityLeaderInfo.ExpediencyFund < pRMsg->ExpediencyFundPayBackCount)
	{// 2007-08-22 by dhjin, 찾는 판공비가 더 크면 오류
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, ERR_OVER_COUNT);
		return RES_BREAK;
	}

	// 2007-08-22 by dhjin, 판공비 유저에게 지급
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if(NULL == pMoney)
	{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	INT64 n64CurCnt		= pMoney->CurrentCount;
	if(MAX_ITEM_COUNTS < n64CurCnt + pRMsg->ExpediencyFundPayBackCount)
	{// 2007-10-05 by cmkwon, 최대 개수 체크
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
		return RES_BREAK;
	}
	
	CAtumLogSender::SendLogMessageITEMSPI(this, pMoney, IUT_EXPEDIENCYFUND_PAYBACK, pRMsg->ExpediencyFundPayBackCount, max(0, pMoney->CurrentCount+pRMsg->ExpediencyFundPayBackCount));
	m_ItemManager.UpdateItemCountByPointer(pMoney, pRMsg->ExpediencyFundPayBackCount, IUT_EXPEDIENCYFUND_PAYBACK);
	
	igLock.auto_unlock_cancel();

	// 2007-08-22 by dhjin, 판공비 요청 처리
	Err_t errCode = ms_pFieldIOCP->m_CityLeader.PayBackExpediencyfund(m_character.MapChannelIndex.MapIndex, m_character.CharacterUniqueNumber, pRMsg->ExpediencyFundPayBackCount, &tmCityLeaderInfo);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFO_EXPEDIENCYFUND_PAYBACK, errCode);
		return RES_BREAK;
	}

	// 2007-08-22 by dhjin, 판공비 환불 정보 DB에 업데이트
	QPARAM_SET_EXPEDIENCY_FUNDPAYBACK *pQParam	= new QPARAM_SET_EXPEDIENCY_FUNDPAYBACK;
	pQParam->MapIndex				= tmCityLeaderInfo.MapIndex;
	pQParam->Influence				= tmCityLeaderInfo.Influence;
	pQParam->CharacterUID			= tmCityLeaderInfo.CharacterUID;
	pQParam->ExpediencyFund			= tmCityLeaderInfo.ExpediencyFund;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SetExpediencyFundPayBack, NULL, NULL, pQParam);

	// 2007-08-22 by dhjin, 판공비 환불 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_EXPEDIENCYFUND_PAYBACK_OK, T_FC_INFO_EXPEDIENCYFUND_PAYBACK_OK, pSendMsg, Sendbuf);
	pSendMsg->ExpediencyFund			= tmCityLeaderInfo.ExpediencyFund;
	pSendMsg->ExpediencyFundRate		= tmCityLeaderInfo.ExpediencyFundRate;
	pSendMsg->CumulativeExpediencyFund	= tmCityLeaderInfo.ExpediencyFundCumulative;
	pSendMsg->ExpediencyFundPayBackCount= pRMsg->ExpediencyFundPayBackCount;
	this->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_INFO_EXPEDIENCYFUND_PAYBACK_OK));

	// 2007-10-02 by dhjin, 판공비 환불 정보 로그 남기기
	// 2007-10-16 by cmkwon, 로그 추가 -
	CAtumLogSender::SendLogMessageExpediencyFund(this, m_character.MapChannelIndex.MapIndex, FALSE, pRMsg->ExpediencyFundPayBackCount, tmCityLeaderInfo.ExpediencyFundRate, tmCityLeaderInfo.ExpediencyFund);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 함수 추가
/// \author		cmkwon
/// \date		2007-09-12 ~ 2007-09-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD
									, MSG_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	if(FALSE == g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag())
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD, ERR_SECPASS_NOT_USE_SYSTEM);
		return RES_BREAK;
	}

// 2007-09-28 by cmkwon, NewSecPassword가 NULL이면 2차패스워드 해제하는 것임
//	if(0 == strncmp(pRMsg->NewSecPassword, "", SIZE_MAX_PASSWORD_MD5_STRING))
//	{// 2007-09-12 by cmkwon, 새로운 패스워드가 설정 되어 있지 않음
//		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD, ERR_SECPASS_NEW_PASSWORD_NOT_SETTING);
//		return RES_BREAK;
//	}

	if(FALSE != IsSettingSecondaryPassword())
	{// 2007-09-12 by cmkwon, 2차패스워드가 설정되어 있다

		if(FALSE == CompareSecondaryPassword(pRMsg->CurrentSecPassword))
		{// 2007-09-12 by cmkwon, 현재 2차패스워드가 다르다
			
			SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD, ERR_SECPASS_PASSWORD_NOT_MATCHED);
			return RES_BREAK;
		}		
	}
	
	///////////////////////////////////////////////////////////////////////////////
	QPARAM_UPDATE_SECONDARY_PASSWORD *pQParam = new QPARAM_UPDATE_SECONDARY_PASSWORD;
	pQParam->AccountUID	= m_character.AccountUniqueNumber;
	STRNCPY_MEMSET(pQParam->NewSecPassword, pRMsg->NewSecPassword, SIZE_MAX_PASSWORD_MD5_STRING);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateSecondaryPassword, this, m_character.AccountUniqueNumber, pQParam);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 함수 추가
/// \author		cmkwon
/// \date		2007-09-12 ~ 2007-09-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD
									, MSG_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD, pRMsg);

	if(FALSE == g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag())
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD, ERR_SECPASS_NOT_USE_SYSTEM);
		return RES_BREAK;
	}

	if(FALSE == IsSettingSecondaryPassword())
	{// 2007-09-12 by cmkwon, 2차패스워드가 설정되지 않은 상태
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD, ERR_SECPASS_PASSWORD_NOT_SETTING);
		return RES_BREAK;
	}
		
	if(FALSE == CompareSecondaryPassword(pRMsg->CurrentSecPassword))
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD, ERR_SECPASS_PASSWORD_NOT_MATCHED);
		return RES_BREAK;
	}
	
	this->SendAddMessageType(T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD_OK);	
	return RES_RETURN_TRUE;
}



///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_LOCK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 함수 추가
/// \author		cmkwon
/// \date		2007-09-12 ~ 2007-09-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_SECONDARYPASSWORD_LOCK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_SECONDARYPASSWORD_LOCK
									, MSG_FC_INFO_SECONDARYPASSWORD_LOCK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag())
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_SECPASS_NOT_USE_SYSTEM);
		return RES_BREAK;
	}

	if(FALSE == IsSettingSecondaryPassword())
	{// 2007-09-12 by cmkwon, 2차패스워드가 설정되지 않은 상태
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_SECPASS_PASSWORD_NOT_SETTING);
		return RES_BREAK;
	}

	if(FALSE == m_bUnlockSecondaryPassword && FALSE == pRMsg->bIsUnlockFlag)
	{// 2007-09-12 by cmkwon, 현재 Lock상태인데 Lock 요청을 한다.
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_SECPASS_ALREADY_LOCK);
		return RES_BREAK;
	}

	if(m_bUnlockSecondaryPassword && pRMsg->bIsUnlockFlag)
	{// 2007-09-12 by cmkwon, 현재 Unlock상태인데 Unlock 요청을 한다.
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_SECPASS_ALREADY_UNLOCK);
		return RES_BREAK;
	}

	if(FALSE == CompareSecondaryPassword(pRMsg->CurrentSecPassword))
	{
		SendErrorMessage(T_FC_INFO_SECONDARYPASSWORD_LOCK, ERR_SECPASS_PASSWORD_NOT_MATCHED);
		return RES_BREAK;
	}

	m_bUnlockSecondaryPassword	= pRMsg->bIsUnlockFlag;			// 2007-09-18 by cmkwon, Lock/Unlock을 설정한다.
	
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_SECONDARYPASSWORD_LOCK_OK, T_FC_INFO_SECONDARYPASSWORD_LOCK_OK, pSendMsg, Sendbuf);
	pSendMsg->bIsUnlockFlag		= pRMsg->bIsUnlockFlag;
	this->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_INFO_SECONDARYPASSWORD_LOCK_OK));
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn		ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_GUILDMARK(const char* pPacket, int nLength, int &nBytesUsed)	
/// \brief		
/// \author		dhjin
/// \date		2007-12-07 ~ 2007-12-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_GUILDMARK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_GET_GUILDMARK
									, MSG_FC_INFO_GET_GUILDMARK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_INFO_GET_GUILDMARK, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetGuildMark, this, 0, NULL, NULL, pRMsg->GuildUID);

	return RES_RETURN_TRUE;
}


//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

ProcessResult CFieldIOCPSocket::Process_FN_MAPPROJECT_START(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(NULL == m_pFieldMapProjectForNPC)
	{
		char	szSystemLog[256];
		sprintf(szSystemLog, "[ERROR] CFieldIOCPSocket::OnRecvdPacketFieldServer invalid variable, MapProject[%#08x] Index[%d]\r\n"
			, m_pFieldMapProjectForNPC, this->GetClientArrayIndex());
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);
		return RES_RETURN_FALSE;
	}

	// 2009-03-26 by cmkwon, 시스템 로그 추가 - 
	g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] UDP Socket ready for NPC Server!! MapIndex(%d) SockIdx(%4d) \r\n", m_pFieldMapProjectForNPC->m_nMapIndex, this->GetClientArrayIndex());

	m_pFieldMapProjectForNPC->ResetAllChannel();
	this->SetPeerUDPReady(TRUE);
	m_PeerSocketType = ST_NPC_SERVER;

	INIT_MSG_WITH_BUFFER(MSG_FN_MAPPROJECT_START_OK, T_FN_MAPPROJECT_START_OK, pSendStartOK, SendBuf);	
	MSG_FN_CONNECT_SET_CHANNEL_STATE *pChannelState = (MSG_FN_CONNECT_SET_CHANNEL_STATE*)(SendBuf + MSG_SIZE(MSG_FN_MAPPROJECT_START_OK));
	int nChannelCounts = 0;
	m_pFieldMapProjectForNPC->MakeMsg_AllChannelState(&nChannelCounts, pChannelState);
	pSendStartOK->CreateChannelCounts	= nChannelCounts;
	pSendStartOK->bCityWarStarted		= FALSE;
	pSendStartOK->CityWarOccupyGuildUID	= INVALID_GUILD_UID;
	if(m_pFieldMapProjectForNPC->m_pRefCityWar2
		&& IS_CITYWAR_MAP_INDEX(m_pFieldMapProjectForNPC->m_nMapIndex))
	{
		pSendStartOK->CityWarOccupyGuildUID = m_pFieldMapProjectForNPC->m_pRefCityWar2->m_OccupyCITY_WAR_DATAWhenWarStarted.GuildUID1;
		if(CITYWAR_STATE_STARTED == m_pFieldMapProjectForNPC->m_pRefCityWar2->GetCityWarState())
		{
			pSendStartOK->bCityWarStarted = TRUE;;
		}		
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FN_MAPPROJECT_START_OK) + pSendStartOK->CreateChannelCounts*sizeof(MSG_FN_CONNECT_SET_CHANNEL_STATE));
	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_CREATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FN_MONSTER_CREATE	*pRecvFMCreate = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_CREATE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_CREATE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14057);
		return RES_RETURN_FALSE;
	}
	pRecvFMCreate = (MSG_FN_MONSTER_CREATE*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterCreateW(pRecvFMCreate);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_MOVE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FN_MONSTER_MOVE		*pRecvFCMove = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_MOVE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_MOVE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14058);
		return RES_RETURN_FALSE;
	}
	pRecvFCMove = (MSG_FN_MONSTER_MOVE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterMoveW(pRecvFCMove);

	// check: 클라이언트에서 보내주기로 결정, 구현 끝나면 삭제하기, 20031114, kelovon
	//		// 마인 공격 처리
	//		CheckMineAttackMonster(pMonster);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_GET_CHARACTER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FN_GET_CHARACTER_INFO		*pRecvCharacterInfo = NULL;

	nRecvTypeSize = sizeof(MSG_FN_GET_CHARACTER_INFO);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_GET_CHARACTER_INFO, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1405A);
		return RES_RETURN_FALSE;
	}
	pRecvCharacterInfo = (MSG_FN_GET_CHARACTER_INFO*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnGetCharacterInfoW(pRecvCharacterInfo);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FN_MONSTER_DELETE		*pRecvMonsterDele = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_DELETE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_DELETE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1405B);
		return RES_RETURN_FALSE;
	}
	pRecvMonsterDele = (MSG_FN_MONSTER_DELETE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterDeleteW(pRecvMonsterDele);
	return RES_RETURN_TRUE;
}

// start 2011-05-11 by hskim, 인피니티 3차 - 시네마 관련 기능 추가 - 해당 맵채널 특정 몬스터 변경 기능 추가
ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_CHANGE_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int nRecvTypeSize	= 0;
	MSG_FN_MONSTER_CHANGE_OK *pRecvMonsterChange = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_CHANGE_OK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_CHANGE_OK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1405F);
		return RES_RETURN_FALSE;
	}
	pRecvMonsterChange = (MSG_FN_MONSTER_CHANGE_OK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterChangeOkW(pRecvMonsterChange);
	return RES_RETURN_TRUE;
}
// end 2011-05-11 by hskim, 인피니티 3차 - 시네마 관련 기능 추가 - 해당 맵채널 특정 몬스터 변경 기능 추가

ProcessResult CFieldIOCPSocket::Process_FN_MISSILE_MOVE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize = 0;
	MSG_FN_MISSILE_MOVE		*pRecvMissileMove = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MISSILE_MOVE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MISSILE_MOVE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1405C);
		return RES_RETURN_FALSE;
	}
	pRecvMissileMove = (MSG_FN_MISSILE_MOVE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMissileMoveW(pRecvMissileMove);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_HPRECOVERY(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FN_MONSTER_HPRECOVERY	*pRecvHPRecovery = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_HPRECOVERY);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_HPRECOVERY, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvHPRecovery = (MSG_FN_MONSTER_HPRECOVERY*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterHPRecoveryW(pRecvHPRecovery);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_HIDE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize = 0;
	MSG_FN_MONSTER_HIDE		*pRecvHide = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_HIDE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_HIDE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvHide = (MSG_FN_MONSTER_HIDE*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterHideW(pRecvHide);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_SHOW(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize = 0;
	MSG_FN_MONSTER_HIDE		*pRecvShow = NULL;

	nRecvTypeSize = sizeof(MSG_FN_MONSTER_SHOW);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_SHOW, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvShow = (MSG_FN_MONSTER_SHOW*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterShowW(pRecvShow);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_PRIMARY(const char* pPacket, int nLength, int &nBytesUsed
																 , MSG_FN_BATTLE_ATTACK_PRIMARY *i_pObjectMonsterAttackPrimary/*=NULL*/
																 , CFieldMapProject *i_pFMapProject/*=NULL*/)
{
	MSG_FN_BATTLE_ATTACK_PRIMARY	*pRFNAttackPri = i_pObjectMonsterAttackPrimary;
	if(NULL == pRFNAttackPri)
	{
		int				nRecvTypeSize = 0;	

		nRecvTypeSize = sizeof(MSG_FN_BATTLE_ATTACK_PRIMARY);
		if(nLength - nBytesUsed < nRecvTypeSize)
		{	// 받아야할 메세지 타입의 사이즈보다 남은 데이타의 사이즈가 작다면 에러
			// Protocl Error 처리
			// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
			SendErrorMessage(T_FN_BATTLE_ATTACK_PRIMARY, ERR_PROTOCOL_INVALID_FIELD_DATA);
			Close(0x1402C);
			return RES_RETURN_FALSE;
		}
		pRFNAttackPri = (MSG_FN_BATTLE_ATTACK_PRIMARY*)(pPacket+nBytesUsed);
		nBytesUsed += nRecvTypeSize;
	}

	CFieldMapProject *pCurFMapProject = NULL;
	if(NULL == i_pFMapProject)
	{
		pCurFMapProject = m_pFieldMapProjectForNPC;
	}
	else
	{
		pCurFMapProject = i_pFMapProject;
	}

	CFieldMonster *ptmFMonster = pCurFMapProject->GetFieldMonsterW(pRFNAttackPri->ChannelIndex, pRFNAttackPri->AttackIndex, 100);
	if(NULL == ptmFMonster
		|| ptmFMonster->m_enMonsterState != MS_PLAYING
		|| TRUE == COMPARE_BODYCON_BIT(ptmFMonster->BodyCondition, BODYCON_DEAD_MASK))
	{
		return RES_BREAK;
	}

	// Primary 공격무기 할당
	ITEM		*pAttackItemDefault = ptmFMonster->FindItemPtrWithItemNum(pRFNAttackPri->WeaponItemNumber);
	if(NULL == pAttackItemDefault)
	{	// 공격무기가 유효 하지 않음

		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////////////
	// --> Start 공격자가 몬스터, 피공격자가 캐릭터
	if(pRFNAttackPri->TargetIndex < MONSTER_CLIENT_INDEX_START_NUM)
	{
		CFieldIOCPSocket	*pPeerFieldIOCPSocket = NULL;
		CHARACTER			*pCharacter;

		if(FALSE == CheckValidAttackTargetCharacter(ptmFMonster->m_pCurrentFieldMapChannelMonster, pRFNAttackPri->TargetIndex, pPeerFieldIOCPSocket, pCharacter))
		{
			return RES_BREAK;
		}

// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack#로 통합
// 		if (pAttackItemDefault->Kind == ITEMKIND_FOR_MON_ALLATTACK)
// 		{// 2005-12-13 by cmkwon, 전체 공격 SplashDamage 처리
// 			ProcessSplashDamageMonsterAllAttack(pRFNAttackPri, this, ptmFMonster, pAttackItemDefault);
// 			return RES_RETURN_TRUE;
// 		}
// 
// 		////////////////////////////////////////////////////////////////////////////////
// 		// 2009-09-09 ~ 2010 by dhjin, 인피니티 -
// 		if(ITEMKIND_FOR_MON_RANGE_ATTACK == pAttackItemDefault->Kind) {
// 			// 몬스터 범위 공격
// 			ProcessRangeDamageMonsterAllAttack(pRFNAttackPri, this, ptmFMonster, pAttackItemDefault);
// 			return RES_RETURN_TRUE;
// 		}
		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack#로 통합
		if(pAttackItemDefault->Kind == ITEMKIND_FOR_MON_ALLATTACK || ITEMKIND_FOR_MON_RANGE_ATTACK == pAttackItemDefault->Kind)
		{
 			ProcessSplashDamageMonsterAllAttack(pRFNAttackPri, this, ptmFMonster, pAttackItemDefault);
 			return RES_RETURN_TRUE;
		}

		float		fDistance;
		float		fDamage;
		D3DXVECTOR3		vFrontVel, vExpectPos;

		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
		pSFCAttackOK->AttackIndex						= pRFNAttackPri->AttackIndex;
		pSFCAttackOK->TargetInfo.TargetIndex			= pRFNAttackPri->TargetIndex;
		pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
		pSFCAttackOK->TargetInfo.TargetPosition			= pRFNAttackPri->TargetPosition;
		pSFCAttackOK->FirePosition.Reset();	
		pSFCAttackOK->AttackType						= ATT_TYPE_GENERAL_PRI;
		pSFCAttackOK->WeaponIndex						= pRFNAttackPri->WeaponIndex;
		pSFCAttackOK->ItemNum							= pAttackItemDefault->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
		pSFCAttackOK->RemainedBulletFuel				= 0;
		pSFCAttackOK->SkillNum							= 0;


		// 캐릭과의 거리를 계산하고 체크한다.
		// 20030107 cmkwon, 몬스터는 사정거리 체크는 필요없음
		fDistance = D3DXVec3Length(&(ptmFMonster->PositionVector - pCharacter->PositionVector));

		// 타켓의 오차 각 계산
		D3DXVec3Normalize(&vFrontVel, &(A2DX(pRFNAttackPri->TargetPosition) - ptmFMonster->PositionVector));	// 공격자의 화면에서
		vExpectPos = ptmFMonster->PositionVector + vFrontVel * fDistance;
		// 실제 Damage Kind 를 계산한다.
		BYTE DamageKind = pPeerFieldIOCPSocket->CalcDamageKind(D3DXVec3Length(&(vExpectPos - pCharacter->PositionVector)));

		if(DamageKind != DAMAGEKIND_NO_DAMAGE)
		{
// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
//			mt_auto_lock dummyLock(&pPeerFieldIOCPSocket->m_mapFieldDummy);			// lock m_mapFieldDummy
//
//			if (pPeerFieldIOCPSocket->m_mapFieldDummy.empty())
//			{// 피공격자가 Dummy를 달고 있지 않을 때
//
//				// 실제 Damage를 계산한다.
//				fDamage = CFieldIOCPSocket::CalcDamageOfAttack(M2C, 1.0f, this,		// @Process_FN_BATTLE_ATTACK_PRIMARY()
//						ptmFMonster, pPeerFieldIOCPSocket, (void*)pCharacter, pAttackItemDefault,
//						&DamageKind, A2DX(pRFNAttackPri->TargetPosition),
//						pAttackItemDefault->Range, ((pAttackItemDefault->OrbitType == ORBIT_BODYSLAM) ? 0 : fDistance ));
//	// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
//	//			// 전체 공격인 경우 splash damage 처리
//	//			if (pAttackItemDefault->Kind == ITEMKIND_FOR_MON_ALLATTACK)
//	//			{
//	//				ProcessSplashDamage(M2C, this, ptmFMonster, A2DX(pRFNAttackPri->TargetPosition), pAttackItemDefault, pRFNAttackPri->TargetIndex);
//	//			}
//				pPeerFieldIOCPSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0128, ptmFMonster->MonsterInfoPtr->MonsterUnitKind, fDamage);
//			}
//			else
//			{// 피공격자가 Dummy를 달고 있을 때
//				
//				FIELD_DUMMY *pTargetDummy = (pPeerFieldIOCPSocket->m_mapFieldDummy.begin())->second;
//				pSFCAttackOK->TargetInfo.TargetItemFieldIndex = pTargetDummy->ItemFieldIndex;
//				
//				fDamage = CalcDamageOfAttack(M2C, 1.0f, this, ptmFMonster, pPeerFieldIOCPSocket, (void*)pCharacter,
//						pAttackItemDefault, &DamageKind, A2DX(pSFCAttackOK->TargetInfo.TargetPosition),
//						0, 0, (pTargetDummy==NULL?NULL:pTargetDummy->ItemFieldIndex));
//				pPeerFieldIOCPSocket->SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0129, ptmFMonster->MonsterInfoPtr->MonsterUnitKind, fDamage);
//			}
			///////////////////////////////////////////////////////////////////////////////	
			// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
			SATTACK_PARAMETER attParam;	
			MEMSET_ZERO(&attParam, sizeof(attParam));
			attParam.MultiTargetIndex = pRFNAttackPri->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
			ptmFMonster->APCalcAttckParameter(&attParam, pAttackItemDefault, pRFNAttackPri->WeaponIndex);
			fDamage = CFieldIOCPSocket::CalcDamageOfAttackNew(&DamageKind, M2C, 1.0f, this, ptmFMonster, &attParam, pPeerFieldIOCPSocket, (void*)pCharacter, pAttackItemDefault->Range, ((pAttackItemDefault->OrbitType == ORBIT_BODYSLAM) ? 0.0f : fDistance ));
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//			// 2006-12-04 by dhjin, 아래와 같이 수정
//			fDamage = CFieldIOCPSocket::CalcDamageOfAttack(M2C, 1.0f, this, ptmFMonster, pPeerFieldIOCPSocket, (void*)pCharacter, pAttackItemDefault,
//					&DamageKind, A2DX(pRFNAttackPri->TargetPosition), pAttackItemDefault->Range, ((pAttackItemDefault->OrbitType == ORBIT_BODYSLAM) ? 0 : fDistance ));
			pPeerFieldIOCPSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0128, ptmFMonster->MonsterInfoPtr->MonsterUnitKind, fDamage);
		}// end_if(DamageKind != DAMAGEKIND_NO_DAMAGE)

		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-13 by cmkwon, 결과 전송
		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(pRFNAttackPri->AttackIndex, Sendbuf
			, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), ptmFMonster->m_pCurrentFieldMapChannelMonster
			, FALSE, ptmFMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW());

		return RES_RETURN_TRUE;
	}	// --> End 공격자가 몬스터, 피공격자가 캐릭터

	//////////////////////////////////////////////////////////////////////////
	// 공격자가 몬스터, 피공격자도 몬스터
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	else {
// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 
// 		CFieldMonster *pTargetFMonster = pCurFMapProject->GetFieldMonsterW(pRFNAttackPri->ChannelIndex, pRFNAttackPri->TargetIndex, 104);
// 		if(NULL == pTargetFMonster
// 			|| pTargetFMonster->m_enMonsterState != MS_PLAYING
// 			|| TRUE == COMPARE_BODYCON_BIT(pTargetFMonster->BodyCondition, BODYCON_DEAD_MASK)) {
// 			return RES_BREAK;
// 		}
		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 
		CFieldMapChannel *pFMapCh = pCurFMapProject->GetFieldMapChannelByIndex(pRFNAttackPri->ChannelIndex);
		if(NULL == pFMapCh)
		{
			return RES_RETURN_TRUE;
		}
		CFieldMonster *pTargetFMonster = NULL;
		if(FALSE == this->CheckValidM2M(pFMapCh, pRFNAttackPri->AttackIndex, &ptmFMonster, pRFNAttackPri->TargetIndex, &pTargetFMonster))
		{
			return RES_RETURN_TRUE;
		}

// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack#로 통합
// 		if (pAttackItemDefault->Kind == ITEMKIND_FOR_MON_ALLATTACK)
// 		{// 2005-12-13 by cmkwon, 전체 공격 SplashDamage 처리
// 			ProcessSplashDamageMonsterAllAttack(pRFNAttackPri, this, pTargetFMonster, pAttackItemDefault);
// 			return RES_RETURN_TRUE;
// 		}
// 
// 		if(ITEMKIND_FOR_MON_RANGE_ATTACK == pAttackItemDefault->Kind) {
// 			// 몬스터 범위 공격
// 			ProcessRangeDamageMonsterAllAttack(pRFNAttackPri, this, ptmFMonster, pAttackItemDefault);
// 			return RES_RETURN_TRUE;
// 		}
		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack#로 통합
 		if (pAttackItemDefault->Kind == ITEMKIND_FOR_MON_ALLATTACK || ITEMKIND_FOR_MON_RANGE_ATTACK == pAttackItemDefault->Kind)
		{
 			ProcessSplashDamageMonsterAllAttack(pRFNAttackPri, this, ptmFMonster, pAttackItemDefault);
 			return RES_RETURN_TRUE;
		}


		float		fDistance;
		float		fDamage;
		D3DXVECTOR3		vFrontVel, vExpectPos;
		
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
		pSFCAttackOK->AttackIndex						= pRFNAttackPri->AttackIndex;
		pSFCAttackOK->TargetInfo.TargetIndex			= pRFNAttackPri->TargetIndex;
		pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
		pSFCAttackOK->TargetInfo.TargetPosition			= pRFNAttackPri->TargetPosition;
		pSFCAttackOK->TargetInfo.MultiTargetIndex		= pRFNAttackPri->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		pSFCAttackOK->FirePosition.Reset();	
		pSFCAttackOK->AttackType						= ATT_TYPE_GENERAL_PRI;
		pSFCAttackOK->WeaponIndex						= pRFNAttackPri->WeaponIndex;
		pSFCAttackOK->ItemNum							= pAttackItemDefault->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
		pSFCAttackOK->RemainedBulletFuel				= 0;
		pSFCAttackOK->SkillNum							= 0;
		
		
		// 캐릭과의 거리를 계산하고 체크한다.
		// 20030107 cmkwon, 몬스터는 사정거리 체크는 필요없음
		fDistance = D3DXVec3Length(&(ptmFMonster->PositionVector - pTargetFMonster->PositionVector));
		
		// 타켓의 오차 각 계산
		D3DXVec3Normalize(&vFrontVel, &(A2DX(pRFNAttackPri->TargetPosition) - ptmFMonster->PositionVector));	// 공격자의 화면에서
		vExpectPos = ptmFMonster->PositionVector + vFrontVel * fDistance;

		SATTACK_PARAMETER attParam;	
		MEMSET_ZERO(&attParam, sizeof(attParam));
		attParam.MultiTargetIndex = pRFNAttackPri->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		ptmFMonster->APCalcAttckParameter(&attParam, pAttackItemDefault, pRFNAttackPri->WeaponIndex);
		fDamage = CFieldIOCPSocket::CalcDamageOfAttackMonsterToMonster(1.0f, this, ptmFMonster, &attParam, (void*)pTargetFMonster);

		///////////////////////////////////////////////////////////////////////
		// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - Attack 정보를 NPC에게 보냄
		INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, Send2NPC);
		pSetAttackChar->ChannelIndex	= pFMapCh->GetMapChannelIndex().ChannelIndex;
		pSetAttackChar->AttackIndex		= pRFNAttackPri->AttackIndex;
		pSetAttackChar->TargetIndex		= pRFNAttackPri->TargetIndex;
		pSetAttackChar->DamageAmount	= fDamage;
		pSetAttackChar->ItemKind		= pAttackItemDefault->Kind;
		pFMapCh->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));

		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-13 by cmkwon, 결과 전송
		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(pRFNAttackPri->AttackIndex, Sendbuf
			, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), ptmFMonster->m_pCurrentFieldMapChannelMonster
			, FALSE, ptmFMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW());
		
		return RES_RETURN_TRUE;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ATTACK_SECONDARY(const char* pPacket, int nLength, int &nBytesUsed)
// 공격시 처리 함수
// 공격 캐릭터 일부 정보, 공격 대상 캐릭터 (락온이 되어야 한다.)
// 응답으로 공격자와 피공격자에게
ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SECONDARY(const char* pPacket, int nLength, int &nBytesUsed)
{
	int				nRecvTypeSize = 0;
	MSG_FN_BATTLE_ATTACK_SECONDARY		*pRFNAttackSec = NULL;

	nRecvTypeSize = sizeof(MSG_FN_BATTLE_ATTACK_SECONDARY);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FN_BATTLE_ATTACK_SECONDARY, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1402C);
		return RES_RETURN_FALSE;
	}
	pRFNAttackSec = (MSG_FN_BATTLE_ATTACK_SECONDARY*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

// 2010-04-05 by cmkwon, 인피2차 M2M 2형 무기 보완 처리 - 
// 	//////////////////////////////////////////////////////////////////////////
// 	// 공격자가 Monster
// 	CFieldMonster * ptmFMonster = m_pFieldMapProjectForNPC->GetFieldMonsterW(pRFNAttackSec->ChannelIndex, pRFNAttackSec->AttackIndex, 101);
// 	if(NULL == ptmFMonster
// 		|| MS_PLAYING != ptmFMonster->m_enMonsterState
// 		|| TRUE == COMPARE_BODYCON_BIT(ptmFMonster->BodyCondition, BODYCON_DEAD_MASK))
// 	{	// 공격자가 유효한지 체크
// 
// 		return RES_BREAK;
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 인피2차 M2M 2형 무기 보완 처리 - 
	CFieldMapChannel * pCurFMChann = m_pFieldMapProjectForNPC->GetFieldMapChannelByIndex(pRFNAttackSec->ChannelIndex);
	if(NULL == pCurFMChann)
	{
		return RES_BREAK;
	}
 	CFieldMonster * ptmFMonster = pCurFMChann->GetFieldMonster(pRFNAttackSec->AttackIndex, 101);
	if(NULL == ptmFMonster
		|| FALSE == ptmFMonster->IsValidMonster())
	{
		return RES_BREAK;
	}

	// Secondary 공격무기
	ITEM * pAttackItemDefault = ptmFMonster->FindItemPtrWithItemNum(pRFNAttackSec->WeaponItemNumber);
	if(NULL == pAttackItemDefault)
	{	// 공격무기가 유효 하지 않음

		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 인피2차 M2M 2형 무기 보완 처리 - 
	vectSATTACK_PARAMETER tmOverLifeTimeAttParamList;
	if(ptmFMonster->APPopOverLifeTimeAttackParameterList(&tmOverLifeTimeAttParamList))
	{
		vectSATTACK_PARAMETER::iterator itr(tmOverLifeTimeAttParamList.begin());
		for(; itr != tmOverLifeTimeAttParamList.end(); itr++)
		{
			SATTACK_PARAMETER *pAttParam = itr;
			ProcessM2MOverLifeTimeAttackParameter(ptmFMonster, pAttParam, pCurFMChann);
		}
	}
	
	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
	SATTACK_PARAMETER attParam;	
	MEMSET_ZERO(&attParam, sizeof(attParam));
	attParam.MultiTargetIndex = pRFNAttackSec->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	ptmFMonster->APCalcAttckParameter(&attParam, pAttackItemDefault, pRFNAttackSec->WeaponIndex);

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 인피2차 M2M 2형 무기 보완 처리 - 
	attParam.TargetIndex	= pRFNAttackSec->TargetIndex;
	attParam.AttackType		= pRFNAttackSec->SecAttackType;

	ptmFMonster->APInsertAttackParameter(&attParam);		

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
//	if(pRFNAttackSec->TargetIndex < MONSTER_CLIENT_INDEX_START_NUM)
//	{	// 피공격자가 Client
//		if(FALSE == this->MonsterAttackM2C(ptmFMonster, pRFNAttackSec, pAttackItemDefault)) {
//			return RES_BREAK;
//		}
// 		CFieldIOCPSocket	*pPeerFieldIOCPSocket = NULL;
// 		CHARACTER			*pCharacter;
// 		if(!CheckValidAttackTargetCharacter(ptmFMonster->m_pCurrentFieldMapChannelMonster, pRFNAttackSec->TargetIndex, pPeerFieldIOCPSocket, pCharacter))
// 		{
// 			// 피공격자의 캐릭터가 유효한지 체크
// 			return RES_BREAK;
// 		}
// 
// 		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
// 		pSFCAttackOK->AttackIndex = pRFNAttackSec->AttackIndex;
// 		pSFCAttackOK->TargetInfo.TargetIndex = pRFNAttackSec->TargetIndex;
// 		pSFCAttackOK->TargetInfo.TargetItemFieldIndex = 0;
// 		pSFCAttackOK->TargetInfo.TargetPosition = pRFNAttackSec->TargetPosition;
// 		pSFCAttackOK->FirePosition.Reset();	
// 		pSFCAttackOK->AttackType = ATT_TYPE_GENERAL_SEC;
// 		pSFCAttackOK->WeaponIndex = pRFNAttackSec->WeaponIndex;
// 		pSFCAttackOK->ItemNum = pAttackItemDefault->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
// 		pSFCAttackOK->RemainedBulletFuel = 0;
// 		pSFCAttackOK->SkillNum = 0;
// 		
// 		///////////////////////////////////////////////////////////////////////////////	
// 		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
// 		SATTACK_PARAMETER attParam;	
// 		MEMSET_ZERO(&attParam, sizeof(attParam));
// 		ptmFMonster->APCalcAttckParameter(&attParam, pAttackItemDefault, pRFNAttackSec->WeaponIndex);
// 		ptmFMonster->APInsertAttackParameter(&attParam);		
// 
// 		float fDistance = D3DXVec3Length(&(ptmFMonster->PositionVector - pCharacter->PositionVector));
// 		// 20030107 cmkwon 몬스터는 거리 체크를 하지 않는다.
// 
// 		// 2007-10-24 by cmkwon, 몬스터 공격 수정 - 아래와 같이 타겟 유저에게 우선 보내고 나머지 유저게에 전송한다.
// 		//ms_pFieldIOCP->SendInRangeMessageAroundCharacter(pRFNAttackSec->AttackIndex, Sendbuf
// 		//	, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), ptmFMonster->m_pCurrentFieldMapChannelMonster
// 		//	, FALSE, );
// 		pPeerFieldIOCPSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
// 		ms_pFieldIOCP->SendInRangeMessageExactAroundPosition(ptmFMonster->PositionVector, Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK)
// 			, ptmFMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW()/2, ptmFMonster->m_pCurrentFieldMapChannelMonster
// 			, pPeerFieldIOCPSocket->GetCharacter()->ClientIndex);
//		return RES_RETURN_TRUE;
//	}	// --> End 공격자가 몬스터, 피공격자가 캐릭터
//	//////////////////////////////////////////////////////////////////////////
//	// 공격자가 몬스터, 피공격자도 몬스터

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	if(pRFNAttackSec->TargetIndex < MONSTER_CLIENT_INDEX_START_NUM)	{
		// 피공격자가 Client
		if(FALSE == this->MonsterAttackSecM2C(ptmFMonster, pRFNAttackSec, pAttackItemDefault)) {
			return RES_BREAK;
		}
	}
	else {
		// M -> M
		if(FALSE == this->MonsterAttackSecM2M(ptmFMonster, pRFNAttackSec, pAttackItemDefault)) {
			return RES_BREAK;
		}
	}

	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_FIND(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize	= 0;
	MSG_FN_BATTLE_ATTACK_FIND	*pRFNAttackFind	= NULL;

	nRecvTypeSize = sizeof(MSG_FN_BATTLE_ATTACK_FIND);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FN_BATTLE_ATTACK_FIND, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1402D);
		return RES_RETURN_FALSE;
	}
	pRFNAttackFind = (MSG_FN_BATTLE_ATTACK_FIND*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	///////////////////////////////////////////////////////////////////////////
	// 몬스터의 2형 공격도 FC_BATTLE_ATTACK_FIND로 처리하기로 함, 20040909, kelovon
	///////////////////////////////////////////////////////////////////////////

// 2007-09-14 by cmkwon, 주석 처리함
//	ASSERT_NEVER_GET_HERE();

	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_DROP_FIXER_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FN_BATTLE_DROP_FIXER_OK	*pRecvFixerOK = NULL;
	CFieldIOCPSocket			*pPeerFieldIOCPSocket = NULL;
	CFieldMonster				*pMonster = NULL;

	nRecvTypeSize = sizeof(MSG_FN_BATTLE_DROP_FIXER_OK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_BATTLE_DROP_FIXER_OK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvFixerOK = (MSG_FN_BATTLE_DROP_FIXER_OK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pRecvFixerOK->TargetIndex, pRecvFixerOK->ChannelIndex, pMonster))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  Process_FN_BATTLE_DROP_FIXER_OK() Error!\r\n");
		return RES_BREAK;
	}

	// send msg
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_DROP_FIXER_OK, T_FC_BATTLE_DROP_FIXER_OK, pFCDropFixerOK, pFCDropFixerOKBuf);
	pFCDropFixerOK->AttackIndex = pRecvFixerOK->AttackIndex;
	pFCDropFixerOK->TargetIndex = pRecvFixerOK->TargetIndex;
	pFCDropFixerOK->ItemFieldIndex = pRecvFixerOK->ItemFieldIndex;
	pFCDropFixerOK->ItemNum = pRecvFixerOK->ItemNum;

	CFieldMapChannel * ptmpFMapChannel = m_pFieldMapProjectForNPC->GetFieldMapChannelByIndex(pRecvFixerOK->ChannelIndex);
	if(NULL == ptmpFMapChannel) { return RES_BREAK; }

	ms_pFieldIOCP->SendInRangeMessageAroundPosition(pMonster->PositionVector, pFCDropFixerOKBuf
		, MSG_SIZE(MSG_FC_BATTLE_DROP_FIXER_OK), ptmpFMapChannel, 0, FALSE);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize = 0;
	MSG_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND	*pRecvHide = NULL;
	CFieldIOCPSocket						*pPeerFieldIOCPSocket = NULL;
	CFieldMonster							*pMonster = NULL;

	nRecvTypeSize = sizeof(MSG_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvHide = (MSG_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pRecvHide->TargetIndex, pRecvHide->ChannelIndex, pMonster))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  Process_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND() Error!\r\n");
		return RES_BREAK;
	}

	// send msg
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_HIDE_ITEM_W_KIND, T_FC_BATTLE_ATTACK_HIDE_ITEM_W_KIND, pFCHide, pFCHideBuf);
	pFCHide->TargetIndex = pRecvHide->TargetIndex;
	pFCHide->ItemKind = pRecvHide->ItemKind;
	pFCHide->TargetItemFieldIndex = pRecvHide->TargetItemFieldIndex;

	CFieldMapChannel * ptmpFMapChannel = m_pFieldMapProjectForNPC->GetFieldMapChannelByIndex(pRecvHide->ChannelIndex);
	if(NULL == ptmpFMapChannel) { return RES_BREAK; }

	ms_pFieldIOCP->SendInRangeMessageAroundPosition(pMonster->PositionVector, pFCHideBuf
		, MSG_SIZE(MSG_FC_BATTLE_ATTACK_HIDE_ITEM_W_KIND), ptmpFMapChannel
		, 0, FALSE);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SKILL(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FN_BATTLE_ATTACK_SKILL, MSG_FN_BATTLE_ATTACK_SKILL, pRMsg);
	
// 2010-04-01 by cmkwon
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Check] T_FN_BATTLE_ATTACK_SKILL Test 1, SkillNum = (%d) SkillCasterCliIdx(%d) TargetCliIdx(%d) \r\n", pRMsg->SkillItemNum, pRMsg->MonsterIndex, pRMsg->ClientIndex);

	// 2010-04-01 by cmkwon, 인피2차 추가 수정 - 
	CFieldMapChannel * pFMapChann = m_pFieldMapProjectForNPC->GetFieldMapChannelByIndex(pRMsg->MapInfo.ChannelIndex);
	if(NULL == pFMapChann)
	{
		return RES_BREAK;
	}

	CFieldMonster *pCasterFMon = pFMapChann->GetFieldMonster(pRMsg->MonsterIndex, 100);
	if(NULL == pCasterFMon
		|| FALSE == pCasterFMon->IsValidMonster())
	{
		return RES_BREAK;
	}
	
// 2010-04-01 by cmkwon
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Check] T_FN_BATTLE_ATTACK_SKILL Test 2, SkillNum = (%d), Monster \r\n", pRMsg->SkillItemNum);

	// 공격 스킬 할당
	ITEM		*pSkillItemDefault = pCasterFMon->FindItemPtrWithItemNum(pRMsg->SkillItemNum);
	if(NULL == pSkillItemDefault) {return RES_BREAK;}

// 2010-04-01 by cmkwon
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Check] T_FN_BATTLE_ATTACK_SKILL Test 3, SkillNum = (%d) \r\n", pRMsg->SkillItemNum);

///////////////////////////////////////////////////////////////////////////////
// 2010-03-31 by dhjin, 인피니티(기지방어) - 밑과 같이 수정
// 	CFieldIOCPSocket	*pPeerFieldIOCPSocket = NULL;
// 	CHARACTER			*pCharacter;
// 
// 	INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_SKILL, T_FC_MONSTER_SKILL, msgUseSkillOK, SendBuf);
// 	msgUseSkillOK->SkillItemNum	= pRMsg->SkillItemNum;
// 	msgUseSkillOK->MonsterIndex	= pRMsg->MonsterIndex;
// 	msgUseSkillOK->PositionVector = pRMsg->PositionVector;
// 	msgUseSkillOK->TargetVector	= pRMsg->TargetVector;
//
// 	if(1 < pSkillItemDefault->MultiTarget) {
// 		// 다수 적용 스킬
// 		int		MultiTargetCount  = 0;
// 		D3DXVECTOR3		vec3AttackPos = A2DX(pRMsg->PositionVector);
// 		vectorClientIndex tmClientIdxList;
// 		tmClientIdxList.reserve(10);
// 		ptmFMonster->GetAttackedInfoClientIndexList(&tmClientIdxList);
// 		int CheckSize = pSkillItemDefault->MultiTarget;
// 		if(tmClientIdxList.size() < pSkillItemDefault->MultiTarget) {
// 			// 다수 적용이 어그로 리스트 보다 많다면 어그로 리스트 수로 최대량 할당.
// 			CheckSize = tmClientIdxList.size();
// 		}
// 		vectorClientIndex::iterator itr(tmClientIdxList.begin());
// 		for(; itr != tmClientIdxList.end(); itr++) {
// 			ClientIndex_t tmClientIdx = *itr;
// 			if(IS_CHARACTER_CLIENT_INDEX(tmClientIdx)
// 				&& CheckValidAttackTargetCharacter(ptmFMonster->m_pCurrentFieldMapChannelMonster, tmClientIdx, pPeerFieldIOCPSocket, pCharacter)
// 				&& pPeerFieldIOCPSocket->IsValidCharacter(FALSE)
// 				&& FALSE == COMPARE_BODYCON_BIT(pPeerFieldIOCPSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
// 				&& D3DXVec3Length(&(pPeerFieldIOCPSocket->m_character.PositionVector - vec3AttackPos)) <= pSkillItemDefault->Range ) {
// 				// 자신과 주위의 아그들에게도 보냄
// 				pPeerFieldIOCPSocket->m_SkillManager.ApplyMonSkill(pSkillItemDefault, pRMsg);
// 				msgUseSkillOK->ClientIndex = tmClientIdx;
// 				pPeerFieldIOCPSocket->m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL));
// 				if(NULL != pPeerFieldIOCPSocket->m_pFieldParty) {
// 					// 전송하지 못한 파티원들에게 전송 (같은 맵에 없다!!!)
// 					INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING, T_FC_CHARACTER_DEBUFF_DOT_APPLYING, pSendMsg, DebuffDotSendBuf);
// 					pSendMsg->CharacterUID		= pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber;
// 					pSendMsg->SkillItemNum		= pRMsg->SkillItemNum;
// 					pPeerFieldIOCPSocket->m_pFieldParty->SendMsgToMembers(DebuffDotSendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING), pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber);
// 				}
// 				MultiTargetCount++;
// 			}
// 			if(MultiTargetCount >= CheckSize) {
// 				break;
// 			}
// 		}
// 
// 	}
//	else if (1 == pSkillItemDefault->MultiTarget){
// 	if (1 <= pSkillItemDefault->MultiTarget){
// 		// 멀티 타겟은 NPC에서 계산한다.
// 		if(IS_CHARACTER_CLIENT_INDEX(pRMsg->ClientIndex)
// 			&& CheckValidAttackTargetCharacter(ptmFMonster->m_pCurrentFieldMapChannelMonster, pRMsg->ClientIndex, pPeerFieldIOCPSocket, pCharacter)
// 			&& pPeerFieldIOCPSocket->IsValidCharacter(FALSE)
// 			&& FALSE == COMPARE_BODYCON_BIT(pPeerFieldIOCPSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)) {
// 			// 자신과 주위의 아그들에게도 보냄
// 			// 2009-09-09 ~ 2010-01-28 by dhjin, 인피니티 - 몬스터 스킬 사용 시 저항 아이템 적용
// 			if(COMPARE_BIT_FLAG(pSkillItemDefault->ItemAttribute, ITEM_ATTR_CHECK_SKILL_RESISTANCE_STATE) 
// 				&& TRUE == m_SkillManager.CheckResistance(pPeerFieldIOCPSocket)) {
// 				// 저항 정보를 전송하자~!!
// 				INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_RESISTANCE_ITEM, T_FC_INFO_APPLY_RESISTANCE_ITEM, ResistanceMsg, ResistanceSendBuf);
// 				ResistanceMsg->ResistanceUserIdx		= pPeerFieldIOCPSocket->m_character.ClientIndex;
// 				ResistanceMsg->SkillNum					= pSkillItemDefault->ItemNum;	// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 저항된 스킬 정보 추가
// 				ResistanceMsg->OnceResistanceItem		= FALSE;		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가
// 				pPeerFieldIOCPSocket->SendAddData(ResistanceSendBuf, MSG_SIZE(MSG_FC_INFO_APPLY_RESISTANCE_ITEM));
// 			}
// 			else if(COMPARE_BIT_FLAG(pSkillItemDefault->ItemAttribute, ITEM_ATTR_CHECK_SKILL_RESISTANCE_STATE) 
// 				&& TRUE == m_SkillManager.CheckOnceResistance(pPeerFieldIOCPSocket)) {
// 				// 저항 정보를 전송하자~!!
// 				INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_RESISTANCE_ITEM, T_FC_INFO_APPLY_RESISTANCE_ITEM, ResistanceMsg, ResistanceSendBuf);
// 				ResistanceMsg->ResistanceUserIdx		= pPeerFieldIOCPSocket->m_character.ClientIndex;
// 				ResistanceMsg->SkillNum					= pSkillItemDefault->ItemNum;	// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 저항된 스킬 정보 추가
// 				ResistanceMsg->OnceResistanceItem		= TRUE;		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가
// 				pPeerFieldIOCPSocket->SendAddData(ResistanceSendBuf, MSG_SIZE(MSG_FC_INFO_APPLY_RESISTANCE_ITEM));
// 			}
// 			else {
// 				pPeerFieldIOCPSocket->m_SkillManager.ApplyMonSkill(pSkillItemDefault, pRMsg);
// 				msgUseSkillOK->ClientIndex	= pRMsg->ClientIndex;
// 				pPeerFieldIOCPSocket->m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL));
// 				if(NULL != pPeerFieldIOCPSocket->m_pFieldParty
// 					&& TRUE == IS_ORBIT_SKILL(pSkillItemDefault->OrbitType)) {	// 2009-09-09 ~ 2010-01-18 by dhjin, 인피니티 - Orbit 스킬일 경우만 파티원에게 디버프, 도트 정보를 보낸다.
// 					INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING, T_FC_CHARACTER_DEBUFF_DOT_APPLYING, pSendMsg, DebuffDotSendBuf);
// 					// 전송하지 못한 파티원들에게 전송 (같은 맵에 없다!!!)
// 					pSendMsg->CharacterUID	= pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber;
// 					pSendMsg->SkillItemNum	= pRMsg->SkillItemNum;
// 					pPeerFieldIOCPSocket->m_pFieldParty->SendMsgToMembers(DebuffDotSendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING), pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber);
// 				}
// 			}
// 		}
// 	}
// 	else if(0 == pSkillItemDefault->MultiTarget){
// 		// 몬스터 자신 스킬
// 		msgUseSkillOK->ClientIndex	= pRMsg->MonsterIndex;
// 		ptmFMonster->m_pCurrentFieldMapChannelMonster->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL));
// 		ptmFMonster->MonsterSkillApply(pRMsg, pSkillItemDefault);
// 	}
	if(IS_CHARACTER_CLIENT_INDEX(pRMsg->ClientIndex))
	{	// 유저에게 사용된 스킬이다.
		this->UserApplyByMonsterSkill(pRMsg, pCasterFMon, pSkillItemDefault);
	}
	else
	{	// 몬스터에게 사용된 스킬이다.

		CFieldMonster *pTarFMon = pFMapChann->GetFieldMonster(pRMsg->ClientIndex, 11000);
		if(NULL == pTarFMon
			|| FALSE == pTarFMon->IsValidMonster())
		{
			return RES_BREAK;
		}

		INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_SKILL, T_FC_MONSTER_SKILL, msgUseSkillOK, SendBuf);
		msgUseSkillOK->SkillItemNum		= pRMsg->SkillItemNum;
		msgUseSkillOK->MonsterIndex		= pRMsg->MonsterIndex;
		msgUseSkillOK->PositionVector	= pRMsg->PositionVector;
		msgUseSkillOK->TargetVector		= pRMsg->TargetVector;
		msgUseSkillOK->ClientIndex		= pRMsg->ClientIndex;
		pFMapChann->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL));
 		pTarFMon->MonsterSkillApply(pRMsg, pSkillItemDefault);
	}

	CAtumLogSender::SendLogMessageMonsterSkill(pCasterFMon->MonsterInfoPtr->MonsterUnitKind, pRMsg->SkillItemNum);		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가, 몬스터 스킬 사용시

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		인피니티(기지방어) - 몬스터가 사용한 스킬 처리 (유저만)
/// \author		dhjin
/// \date		2010-03-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::UserApplyByMonsterSkill(MSG_FN_BATTLE_ATTACK_SKILL * i_pRMsg, CFieldMonster * i_pFMonster, ITEM * i_pSkillItemDefault)
{
	if(NULL == i_pRMsg
		|| NULL == i_pFMonster
		|| NULL == i_pSkillItemDefault)
	{
		return;
	}

	CFieldIOCPSocket	*pPeerFieldIOCPSocket = NULL;
	CHARACTER			*pCharacter;
	
	INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_SKILL, T_FC_MONSTER_SKILL, msgUseSkillOK, SendBuf);
	msgUseSkillOK->SkillItemNum	= i_pRMsg->SkillItemNum;
	msgUseSkillOK->MonsterIndex	= i_pRMsg->MonsterIndex;
	msgUseSkillOK->PositionVector = i_pRMsg->PositionVector;
	msgUseSkillOK->TargetVector	= i_pRMsg->TargetVector;
	if(CheckValidAttackTargetCharacter(i_pFMonster->m_pCurrentFieldMapChannelMonster, i_pRMsg->ClientIndex, pPeerFieldIOCPSocket, pCharacter)
		&& pPeerFieldIOCPSocket->IsValidCharacter(FALSE)
		&& FALSE == COMPARE_BODYCON_BIT(pPeerFieldIOCPSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)) {
		// 자신과 주위의 아그들에게도 보냄
		// 2009-09-09 ~ 2010-01-28 by dhjin, 인피니티 - 몬스터 스킬 사용 시 저항 아이템 적용
		if(COMPARE_BIT_FLAG(i_pSkillItemDefault->ItemAttribute, ITEM_ATTR_CHECK_SKILL_RESISTANCE_STATE) 
			&& TRUE == m_SkillManager.CheckResistance(pPeerFieldIOCPSocket)) {
			// 저항 정보를 전송하자~!!
			INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_RESISTANCE_ITEM, T_FC_INFO_APPLY_RESISTANCE_ITEM, ResistanceMsg, ResistanceSendBuf);
			ResistanceMsg->ResistanceUserIdx		= pPeerFieldIOCPSocket->m_character.ClientIndex;
			ResistanceMsg->SkillNum					= i_pSkillItemDefault->ItemNum;	// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 저항된 스킬 정보 추가
			ResistanceMsg->OnceResistanceItem		= FALSE;		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가
			pPeerFieldIOCPSocket->SendAddData(ResistanceSendBuf, MSG_SIZE(MSG_FC_INFO_APPLY_RESISTANCE_ITEM));
		}
		else if(COMPARE_BIT_FLAG(i_pSkillItemDefault->ItemAttribute, ITEM_ATTR_CHECK_SKILL_RESISTANCE_STATE) 
			&& TRUE == m_SkillManager.CheckOnceResistance(pPeerFieldIOCPSocket)) {
			// 저항 정보를 전송하자~!!
			INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_RESISTANCE_ITEM, T_FC_INFO_APPLY_RESISTANCE_ITEM, ResistanceMsg, ResistanceSendBuf);
			ResistanceMsg->ResistanceUserIdx		= pPeerFieldIOCPSocket->m_character.ClientIndex;
			ResistanceMsg->SkillNum					= i_pSkillItemDefault->ItemNum;	// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 저항된 스킬 정보 추가
			ResistanceMsg->OnceResistanceItem		= TRUE;		// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가
			pPeerFieldIOCPSocket->SendAddData(ResistanceSendBuf, MSG_SIZE(MSG_FC_INFO_APPLY_RESISTANCE_ITEM));
		}
		else {
			pPeerFieldIOCPSocket->m_SkillManager.ApplyMonSkill(i_pSkillItemDefault, i_pRMsg);
			msgUseSkillOK->ClientIndex	= i_pRMsg->ClientIndex;
			pPeerFieldIOCPSocket->m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL));
			if(NULL != pPeerFieldIOCPSocket->m_pFieldParty
				&& TRUE == IS_ORBIT_SKILL(i_pSkillItemDefault->OrbitType)) {	// 2009-09-09 ~ 2010-01-18 by dhjin, 인피니티 - Orbit 스킬일 경우만 파티원에게 디버프, 도트 정보를 보낸다.
				INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING, T_FC_CHARACTER_DEBUFF_DOT_APPLYING, pSendMsg, DebuffDotSendBuf);
				// 전송하지 못한 파티원들에게 전송 (같은 맵에 없다!!!)
				pSendMsg->CharacterUID	= pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber;
				pSendMsg->SkillItemNum	= i_pRMsg->SkillItemNum;
				pPeerFieldIOCPSocket->m_pFieldParty->SendMsgToMembers(DebuffDotSendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING), pPeerFieldIOCPSocket->m_character.CharacterUniqueNumber);
			}
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		인피니티(기지방어) - 명중시 발동되는 스킬 처리
/// \author		dhjin
/// \date		2010-03-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ProcessingHitInvokeSkill(ITEM * i_pAttackItem, ClientIndex_t i_AttackIdx)
{
	if(NULL == i_pAttackItem)
	{
		return;
	}

	for(int j=0; j < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; j++)
	{
		if(DES_HIT_INVOKE_SKILL == i_pAttackItem->ArrDestParameter[j])
		{
			this->ApplyHitInvokeSkill((ItemNum_t)i_pAttackItem->ArrParameterValue[j], i_AttackIdx);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ApplyHitInvokeSkill(ItemNum_t i_SkillNum, ClientIndex_t i_AttackIdx)
/// \brief		인피니티(기지방어) - 명중시 발동되는 스킬 적용
/// \author		dhjin
/// \date		2010-03-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyHitInvokeSkill(ItemNum_t i_SkillNum, ClientIndex_t i_AttackIdx)
{
	ITEM * HitInvokeSkill = this->ms_pFieldIOCP->GetItemInfo(i_SkillNum);

	if(NULL == HitInvokeSkill)
	{
		return;
	}

	INIT_MSG_OF_SIZE(MSG_FC_SKILL_USE_SKILL_OK, T_FC_SKILL_USE_SKILL_OK, msgUseSkillOK, SendBuf);
	msgUseSkillOK->SkillItemID.ItemNum	= i_SkillNum;
	msgUseSkillOK->AttackIndex	= i_AttackIdx;
	msgUseSkillOK->TargetIndex	= this->m_character.CharacterUniqueNumber;
	this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_SKILL_USE_SKILL_OK), TRUE);

	if(TRUE == IS_ORBIT_SKILL(HitInvokeSkill->OrbitType)) 
	{
		this->m_SkillManager.ApplyOrbitSkill(HitInvokeSkill, this->GetCharacter()->ClientIndex);
		if(NULL != this->m_pFieldParty)
		{
			INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING, T_FC_CHARACTER_DEBUFF_DOT_APPLYING, pSendMsg, DebuffDotSendBuf);
			pSendMsg->CharacterUID	= this->m_character.CharacterUniqueNumber;
			pSendMsg->SkillItemNum	= i_SkillNum;
			this->m_pFieldParty->SendMsgToMembers(DebuffDotSendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_APPLYING), this->m_character.CharacterUniqueNumber);
		}
		return;
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-05 by cmkwon, 인피2차 M2M 2형 무기 보완 처리 - 
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ProcessM2MOverLifeTimeAttackParameter(CFieldMonster *i_pAttFMon, SATTACK_PARAMETER *i_pAttParam, CFieldMapChannel *i_pCurFMapChann)
{
	// MSG_FC_BATTLE_ATTACK_FIND_OK 준비
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_FIND_OK, T_FC_BATTLE_ATTACK_FIND_OK, pMsgAttackFindOK, pMsgAttackFindOKBuf);
	pMsgAttackFindOK->AttackIndex			= i_pAttFMon->MonsterIndex;
	pMsgAttackFindOK->TargetIndex			= i_pAttParam->TargetIndex;
	pMsgAttackFindOK->TargetItemFieldIndex	= 0;
	pMsgAttackFindOK->WeaponIndex			= i_pAttParam->WeaponIndex;
	pMsgAttackFindOK->AttackType			= i_pAttParam->AttackType;

	CFieldMonster *pAttMon = NULL;
	CFieldMonster *pTarMon = NULL;
	if (FALSE == CheckValidM2M(i_pCurFMapChann, i_pAttFMon->MonsterIndex, &pAttMon, i_pAttParam->TargetIndex, &pTarMon))
	{
		pMsgAttackFindOK->TargetIndex			= 0;
		pMsgAttackFindOK->TargetItemFieldIndex	= 0;
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(i_pAttFMon->PositionVector, pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), i_pCurFMapChann);
		return;
	}
	
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 배리어 체크
	if(pTarMon->CheckBarrierHave())
	{
		if(pTarMon->CheckBarrierUsing())
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USING, T_FC_BATTLE_MONSTER_BARRIER_USING, pSendMsg, SendBuf);
			pSendMsg->MonsterIndex		= pTarMon->MonsterIndex;
			this->SendAddData(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USING));
			ms_pFieldIOCP->SendInRangeMessageAroundPosition(i_pAttFMon->PositionVector, pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), i_pCurFMapChann);
			return ;
		}
		if(pTarMon->BarrierUse())
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USE, T_FC_BATTLE_MONSTER_BARRIER_USE, pSendMsg, SendBuf);
			pSendMsg->MonsterIndex		= pTarMon->MonsterIndex;
			pSendMsg->SkillItemNum		= pTarMon->m_bBarrierInfo.SkillNum;
			ms_pFieldIOCP->SendInRangeMessageAroundPosition(i_pAttFMon->PositionVector, SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USE), i_pCurFMapChann);
			ms_pFieldIOCP->SendInRangeMessageAroundPosition(i_pAttFMon->PositionVector, pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), i_pCurFMapChann);
			return;
		}
	}
	// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 몬스터 즉시 시전 배리어 스킬(고급무기만발동)
	if(TRUE == pTarMon->CheckImmediateBarrierUsing())
	{
		return;
	}
	
	float		fDamage = CFieldIOCPSocket::CalcDamageOfAttackMonsterToMonster(1.0f, this, pAttMon, i_pAttParam, (void*)pTarMon);	
	
	///////////////////////////////////////////////////////////////////////
	// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - Attack 정보를 NPC에게 보냄
	INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, Send2NPC);
	pSetAttackChar->ChannelIndex	= i_pCurFMapChann->GetMapChannelIndex().ChannelIndex;
	pSetAttackChar->AttackIndex		= pMsgAttackFindOK->AttackIndex;
	pSetAttackChar->TargetIndex		= pMsgAttackFindOK->TargetIndex;
	pSetAttackChar->DamageAmount	= fDamage;
	pSetAttackChar->ItemKind		= i_pAttParam->pWeaponItemInfo->Kind;
	i_pCurFMapChann->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
	
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(i_pAttFMon->PositionVector, pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), i_pCurFMapChann);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityInitImputeList(vectINFINITY_IMPUTE *i_pImputeList)
{
	if(i_pImputeList->empty()){						return;}

	mt_auto_lock mtImpute(&m_mtVecInfiImpute);
	m_mtVecInfiImpute.clear();
	m_mtVecInfiImpute.reserve(i_pImputeList->size());
	m_mtVecInfiImpute.insert(m_mtVecInfiImpute.end(), i_pImputeList->begin(), i_pImputeList->end());
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityAddImpute(InfiModeUID_t i_infiModeUID, BOOL i_bUpdate2DB/*=FALSE*/)
{
	mt_auto_lock mtImpute(&m_mtVecInfiImpute);
	
	INFINITY_IMPUTE *pImputeInfo = InfinityGetImputeInfoNoLock(i_infiModeUID);
	if(pImputeInfo)
	{
		pImputeInfo->EntranceCount++;

		if(i_bUpdate2DB)
		{
			QPARAM_UPDATE_INFINITY * pQParam = new QPARAM_UPDATE_INFINITY;
			pQParam->AccountUID				= this->m_character.AccountUniqueNumber;
			pQParam->CharacterUID			= this->m_character.CharacterUniqueNumber;
			pQParam->InfinityModeUID		= i_infiModeUID;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateInfinityImpute, this, GetCharacter()->AccountUniqueNumber, pQParam);
		}
		
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity] CFieldIOCPSocket::InfinityAddImpute# %s updated !! InfiModeUID(%d) EntranceCnt(%d) UpdateDB(%d) \r\n"
//			, GetCharacterString(GetCharacter(), string()), i_infiModeUID, pImputeInfo->EntranceCount, i_bUpdate2DB);
		return;
	}

	INFINITY_IMPUTE tmImpute;		MEMSET_ZERO(&tmImpute, sizeof(tmImpute));
	tmImpute.InfinityModeUID	= i_infiModeUID;
	tmImpute.EntranceCount		= 1;
	m_mtVecInfiImpute.push_back(tmImpute);

	if(i_bUpdate2DB)
	{
		QPARAM_INSERT_INFINITY * pQParam = new QPARAM_INSERT_INFINITY;
		pQParam->AccountUID				= this->m_character.AccountUniqueNumber;
		pQParam->CharacterUID			= this->m_character.CharacterUniqueNumber;
		pQParam->InfinityModeUID		= i_infiModeUID;
		pQParam->StartTime.SetCurrentDateTime();
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertInfinityImpute, this, GetCharacter()->AccountUniqueNumber, pQParam);
	}

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity] CFieldIOCPSocket::InfinityAddImpute# %s inserted !! InfiModeUID(%d) UpdateDB(%d) \r\n"
//		, GetCharacterString(GetCharacter(), string()), i_infiModeUID, i_bUpdate2DB);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
INFINITY_IMPUTE *CFieldIOCPSocket::InfinityGetImputeInfoNoLock(InfiModeUID_t i_infiModeUID)
{
	mt_vectorInfinityImpute::iterator itr(m_mtVecInfiImpute.begin());
	
	for(; itr != m_mtVecInfiImpute.end(); itr++)
	{
		INFINITY_IMPUTE *pImpute = itr;
		if(i_infiModeUID == pImpute->InfinityModeUID)
		{
			return pImpute;
		}
	}

	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InfinitySendImputeList2AFS(void)
{
	mt_auto_lock mtImpute(&m_mtVecInfiImpute);

	vectINFINITY_IMPUTE tmImputeList;
	if(false == m_mtVecInfiImpute.empty())
	{
		tmImputeList.reserve(m_mtVecInfiImpute.size());
		tmImputeList.insert(tmImputeList.end(), m_mtVecInfiImpute.begin(), m_mtVecInfiImpute.end());
	}
	mtImpute.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_IMPUTE_LIST, T_FtoA_INFINITY_IMPUTE_LIST, pSendImputeMsg, SendImputeBuf);
	pSendImputeMsg->AFSClientIndex		= this->m_AFSClientIndex;
	pSendImputeMsg->bHaveReentryTicket	= (NULL == this->m_ItemManager.GetItemGeneralByDestParam(DES_INFINITY_REENTRY_TICKET)) ? FALSE : TRUE;	// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 

	INFINITY_IMPUTE * pInfinityImputeInfo = (INFINITY_IMPUTE*)(SendImputeBuf+MSG_SIZE(MSG_FtoA_INFINITY_IMPUTE_LIST));
	int nRecodeCnt		= 0;

	vectINFINITY_IMPUTE::iterator itr(tmImputeList.begin());
	for(; itr != tmImputeList.end(); itr++)
	{
		if(SIZE_MAX_PACKET < MSG_SIZE(MSG_FtoA_INFINITY_IMPUTE_LIST) + sizeof(INFINITY_IMPUTE) * (nRecodeCnt+1))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::InfinitySendImputeList2AFS# PacketSize error !! %s ImputeListSize(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), tmImputeList.size());
			break;
		}

		INFINITY_IMPUTE *pImpute = itr;

		pInfinityImputeInfo[nRecodeCnt].InfinityModeUID		= pImpute->InfinityModeUID;
		pInfinityImputeInfo[nRecodeCnt].EntranceCount		= pImpute->EntranceCount;
		nRecodeCnt++;
	}
	pSendImputeMsg->InfinityImputeListCount = nRecodeCnt;
	ms_pFieldIOCP->m_pArenaFieldWinSocket->Write(SendImputeBuf, MSG_SIZE(MSG_FtoA_INFINITY_IMPUTE_LIST) + sizeof(INFINITY_IMPUTE) * nRecodeCnt);
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
/// \author		cmkwon
/// \date		2010-04-05 ~ 2010-04-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InfinitySendAddDataFromAFS2MFS(BYTE * pData, int nSize)
{
	CIOCPSocket *pISoc4MFS = ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == pISoc4MFS
		|| FALSE == pISoc4MFS->IsUsing())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity] ISoc4MFS is NULL !!, %s MFSServerID(%d) \r\n", GetCharacterString(GetCharacter(), string()), this->m_AfsNeedMfsInfo.MFSServerID);
		return FALSE;
	}

	return pISoc4MFS->SendAddData(pData, nSize);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-06 by cmkwon, 인피2차 추가 수정 - 
/// \author		cmkwon
/// \date		2010-04-06 ~ 2010-04-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityOnCharacterGameEndRoutine(void)
{
	eINFINITY_STATE tmInfiState = this->m_InfinityPlayingInfo.InfinityState;
	if(FALSE == g_pFieldGlobal->IsArenaServer()
		|| INFINITY_STATE_NONE == tmInfiState)
	{
		return;
	}

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::InfinityOnCharacterGameEndRoutine# ! %s, InfiState(%d) \r\n"
//		, m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), tmInfiState);		

	INFINITY_DISCONNECTUSER_INFO DisConnectUserInfo;	MEMSET_ZERO(&DisConnectUserInfo, sizeof(DisConnectUserInfo));
	STRNCPY_MEMSET(DisConnectUserInfo.CharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	DisConnectUserInfo.InfinityCreateUID = this->m_InfinityPlayingInfo.InfinityCreateUID;
	DisConnectUserInfo.MainServerID		 = this->m_AfsNeedMfsInfo.MFSServerID;
	DisConnectUserInfo.InfinityMode		 = this->m_InfinityPlayingInfo.ModeTypeNum;

	ms_pFieldIOCP->m_InfinityManager.LeaveInfinity(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, this);	

	switch(tmInfiState)
	{
	case INFINITY_STATE_ENTERING:
	case INFINITY_STATE_MAPLOADED:
		{
			// 2010-04-06 by cmkwon, 재접속 가능하게 처리
			this->ms_pFieldIOCP->m_InfinityManager.SetDisConnectUserInfo(&DisConnectUserInfo);

			// 2010-04-06 by cmkwon, 인피2차 추가 수정 - 귀속처리는 해야함.
			INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_UPDATE_USER_MAP_INFO, T_FtoA_INFINITY_UPDATE_USER_MAP_INFO, pSMsg, SendBuf);
			pSMsg->AccountUID			= this->m_character.AccountUniqueNumber;
			pSMsg->MFSCharacterUID		= this->m_AfsNeedMfsInfo.MFSCharacterUID;
			pSMsg->MFSClientIndex		= this->m_AfsNeedMfsInfo.MFSClientIdx;
			pSMsg->InfinityMapIndex		= this->m_character.MapChannelIndex.MapIndex;
			pSMsg->InfinityChannelIndex	= this->m_character.MapChannelIndex.ChannelIndex;
			this->InfinitySendAddDataFromAFS2MFS(SendBuf, MSG_SIZE(MSG_FtoA_INFINITY_UPDATE_USER_MAP_INFO));
		}
		break;
	case INFINITY_STATE_PLAYING:
	// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
	case INFINITY_STATE_PLAYING_STEP1:
	case INFINITY_STATE_PLAYING_STEP2:
	case INFINITY_STATE_PLAYING_STEP3:
	case INFINITY_STATE_PLAYING_STEP4:
	case INFINITY_STATE_PLAYING_STEP5:
	case INFINITY_STATE_PLAYING_STEP6:
	case INFINITY_STATE_PLAYING_STEP7:
	case INFINITY_STATE_PLAYING_STEP8:
	// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
	case INFINITY_STATE_DONE_SUCCESS:
	case INFINITY_STATE_DONE_FAIL:
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
			// 2010-04-02 by cmkwon, 인피2차 추가 수정 - 
			this->GameEndAllInvokingEquipItem();

			// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
			// 기존
			// if(INFINITY_STATE_PLAYING == tmInfiState)

			// 수정
			if( TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState) )
			// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
			{// 2010-04-06 by cmkwon, 게임이 진행중일때만 재접속 가능하게 처리
				this->ms_pFieldIOCP->m_InfinityManager.SetDisConnectUserInfo(&DisConnectUserInfo);
			}
			
			// 인피 진행중이었다면 본서버에 업뎃!!
			this->InfinityFin();
		}
		break;
	}
	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-06 by cmkwon, 인피2차 추가 수정 - 
/// \author		cmkwon
/// \date		2010-04-06 ~ 2010-04-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ArenaOnCharacterGameEndRoutine(void)
{
	if(FALSE == g_pFieldGlobal->IsArenaServer()
		|| ARENA_STATE_NONE == this->m_ArenaInfo.State)
	{
		return;
	}

	// 2007-05-02 by dhjin, 종료시 아레나 상태일 때 처리해야 할 것
	//////////////////////////////////////////////////////////////////////////
	// 2007-06-04 by dhjin, 아레나 전용 아이템을 삭제한다.
	m_ItemManager.DeleteAllArenaItem();
	
	// 2007-04-23 by dhjin, 팀원 삭제
	this->ms_pFieldIOCP->m_ArenaManager.DeleteMember(this);
	
	if(ARENA_STATE_FIGHTING_WARREADY <=  this->m_ArenaInfo.State
		&& ARENA_STATE_FIGHTING_WARFINISH >=  this->m_ArenaInfo.State
		&& FALSE == this->m_ArenaInfo.WatchState)
	{// 2007-06-21 by dhjin, 아레나 대전 중이었다면 강제 종료 1증가.
		// 2008-01-15 by dhjin, 아레나 통합 - 필드 서버로 강제 종료 전송하여 처리
		this->SendArenaCharacterDisConnect();
	}	

	// start 2011-10-17 by hskim, 파트너 시스템 2차
	switch( m_ArenaInfo.State )
	{
		case ARENA_STATE_FIGHTING_WARREADY:
		case ARENA_STATE_FIGHTING_WARING:
		case ARENA_STATE_FIGHTING_WARFINISH:
		{
			this->ArenaFin();		// 아레나 진행중이라면 본서버에 업데이트
			break;
		}

		case ARENA_STATE_JOINING:
		case ARENA_STATE_READY:
		case ARENA_STATE_READY_FINISH:
		default:
		{
			break;
		}
	}
	// end 2011-10-17 by hskim, 파트너 시스템 2차
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
/// \author		cmkwon
/// \date		2010-04-20 ~ 2010-04-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::TryEnchantItem(BOOL *o_pbSuccessFlag, ITEM_GENERAL *i_pTargetItemG, int i_nEnchantCnt, ITEM_GENERAL *i_pEnchatItemG, ITEM_GENERAL *i_pPreventDestructionItemG, ITEM_GENERAL *i_pProbabilityIncreaseItemG)
{
	
	// start 2012-11-21 by khkim, GLog 2차
	MSG_FL_LOG_ITEM LogItemParameter;
	MEMSET_ZERO(&LogItemParameter, sizeof(LogItemParameter));	// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
	int EnchantBefore		= 0;
	// end 2012-11-21 by khkim, GLog 2차
	
	*o_pbSuccessFlag		= FALSE;

	// 인챈트 정보 검색
	ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(i_pEnchatItemG->ItemNum);
	if (pEnchantInfo == NULL)
	{
		return ERR_NO_SUCH_ENCHANT_INFO;
	}
	
	// 돈 확인
	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (pMoney == NULL || pMoney->CurrentCount < pEnchantInfo->EnchantCost)
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		return ERR_PROTOCOL_NOT_ENOUGH_MONEY;
	}

	Prob10K_t EnchantProbability = pEnchantInfo->ProbabilityPerLevel[i_nEnchantCnt];

	///////////////////////////////////////////////////////////////////////////////
	// 2007-10-02 by cmkwon, 하이퍼 인챈트 카드 추가로 인챈트/갬블 확률이 0인 것은 사용이 불가능 하다
	if(0 >= EnchantProbability)
	{
		return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
	}

	if(MAX_RAND10K_VALUE < EnchantProbability)
	{// 2010-04-20 by cmkwon, 이미 성공 확률 100%일 경우는 파방/확률증가 아이템 삭제하지 않는다.
		i_pPreventDestructionItemG	= NULL;
		i_pProbabilityIncreaseItemG	= NULL;
	}


	// 2013-08-12 by bckim, 신규해피아워
	Prob10K_t	TempEnchantProb_by_happyhour = 0;
	float		ftempEnchantRate = 0.0f;
#ifdef SC_RENEWER_HAPPY_HOUR_BHSOHN_BCKIM		//	Try enchant 
	
	if(IS_WEAPON(i_pTargetItemG->ItemInfo->Kind))
	{
		ftempEnchantRate = ms_pFieldIOCP->m_gameEventManager.GetWeapontEnchantRate(m_character.InfluenceType, this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
	}
	else if( ITEMKIND_DEFENSE == i_pTargetItemG->ItemInfo->Kind )
	{
		ftempEnchantRate = ms_pFieldIOCP->m_gameEventManager.GetArmorEnchantRate(m_character.InfluenceType, this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
	}
	else 
	{
		ftempEnchantRate = ms_pFieldIOCP->m_gameEventManager.GetETCItemEnchantRate(m_character.InfluenceType, this->m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);
	}
	TempEnchantProb_by_happyhour = EnchantProbability * ftempEnchantRate;
	
#endif
	// End. 2013-08-12 by bckim, 신규해피아워

	if(i_pProbabilityIncreaseItemG)
	{
		EnchantProbability = EnchantProbability + (EnchantProbability * (i_pProbabilityIncreaseItemG->ItemInfo->GetParameterValue(DES_ENCHANT_INCREASE_PROBABILITY) / (MAX_RAND10K_VALUE+1) ) );	
	}
	EnchantProbability = EnchantProbability + TempEnchantProb_by_happyhour;		// 2013-08-12 by bckim, 신규해피아워

	BOOL bEnchantSuccess	= FALSE;
	Prob10K_t nRandValue = ms_pFieldIOCP->GetRandInt32(0, MAX_RAND10K_VALUE);	// 2007-12-10 by cmkwon, 랜덤 시스템 수정 - 
	if (nRandValue <= EnchantProbability)
	{// 성공함

		//////////////////////////////////////////////////////////////////////////////////
		// start 2011-10-19 by hskim, EP4 [Free to play] - 10 회 인첸트 아이템 기능 구현
		//
		// 기존
		//

		/*
		bEnchantSuccess		= TRUE;
		i_nEnchantCnt++;

		// ENCHANT 생성, DB parameter로 넘기기 위해 new로 생성함
		ENCHANT *pNewEnchant				= new ENCHANT;
		pNewEnchant->TargetItemUniqueNumber	= i_pTargetItemG->UniqueNumber;
		pNewEnchant->TargetItemNum			= i_pTargetItemG->ItemNum;
		pNewEnchant->EnchantItemNum			= i_pEnchatItemG->ItemNum;

		// 삽입
		InsertEnchantToItem(i_pTargetItemG, *pNewEnchant);

		// Send MSG
		INIT_MSG_OF_SIZE(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pPutEnchant, pPutEnchantBuf);
		pPutEnchant->Enchant = *pNewEnchant;
		SendAddData(pPutEnchantBuf, MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));

		// Update DB
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertEnchant, this, m_character.AccountUniqueNumber, pNewEnchant);
		*/

		/////////
		// 수정

		int iApplyCount = 1;

		if( TRUE == i_pEnchatItemG->ItemInfo->IsExistDesParam(DES_ENCHANT_ONCE_APPLY) && i_pPreventDestructionItemG == NULL && i_nEnchantCnt < MAX_ENCHANT_ONCE_APPLY_COUNT )
		{
			iApplyCount = i_pEnchatItemG->ItemInfo->GetParameterValue(DES_ENCHANT_ONCE_APPLY) - i_nEnchantCnt;
		}

		bEnchantSuccess		= TRUE;

		for(int a=0; a<iApplyCount; a++)
		{	
			// start 2012-11-21 by khkim, GLog 2차	
			EnchantBefore				= i_nEnchantCnt++;	
			LogItemParameter.LogType	= GLOG_IL_LT_ENCHANT_UP;
			// end 2012-11-21 by khkim, GLog 2차
			
			// ENCHANT 생성, DB parameter로 넘기기 위해 new로 생성함
			ENCHANT *pNewEnchant				= new ENCHANT;
			pNewEnchant->TargetItemUniqueNumber	= i_pTargetItemG->UniqueNumber;
			pNewEnchant->TargetItemNum			= i_pTargetItemG->ItemNum;
			pNewEnchant->EnchantItemNum			= i_pEnchatItemG->ItemNum;
			pNewEnchant->SequenceNumber_DB		= 0;	// 2013-01-15 by bckim, 인챈트아이템 시퀀스넘버 추가

			// 삽입
			InsertEnchantToItem(i_pTargetItemG, *pNewEnchant);

			// Send MSG
			INIT_MSG_OF_SIZE(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pPutEnchant, pPutEnchantBuf);
			pPutEnchant->Enchant = *pNewEnchant;
			SendAddData(pPutEnchantBuf, MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));

			// Update DB
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertEnchant, this, m_character.AccountUniqueNumber, pNewEnchant);
		}

		// end 2011-10-19 by hskim, EP4 [Free to play] - 10 회 인첸트 아이템 기능 구현
		//////////////////////////////////////////////////////////////////////////////////
		
		// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
		if (NULL != i_pTargetItemG)
		{
			mt_auto_lock maA(&m_mapEnchant);	// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - GetAllEnchantListPtrByItemUID 호출전에 꼭 먼저 락을 걸어야 함.
			vectENCHANT tempvectEnchantList;
			this->GetAllEnchantListByItemUID(&tempvectEnchantList,i_pTargetItemG->UniqueNumber);
			CAtumLogSender::SendLogMessageITEMTryEnchantInfo(this, i_pTargetItemG, TRY_ENCHANT_SUCCESS,&tempvectEnchantList);
			this->ExsistHyperCardIn10Lv(i_pTargetItemG->UniqueNumber);  // 10인챈트이하 하이퍼카드가 적용되어있으면 로그 남기기 
		}
		// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
		
	}
	else
	{
		// start 2012-11-21 by khkim, GLog 2차
		LogItemParameter.LogType	= GLOG_IL_LT_ENCHANT_DWON;
		EnchantBefore				= i_nEnchantCnt;		
		// end 2012-11-21 by khkim, GLog 2차

		i_nEnchantCnt		= 0;		// 인챈트 카운트 초기화

		///////////////////////////////////////////////////////////////////////////////
	
		// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
		if (NULL != i_pTargetItemG)
		{
			mt_auto_lock maA(&m_mapEnchant);	// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - GetAllEnchantListPtrByItemUID 호출전에 꼭 먼저 락을 걸어야 함.
			vectENCHANT tempvectEnchantList;
			this->GetAllEnchantListByItemUID(&tempvectEnchantList,i_pTargetItemG->UniqueNumber);
			CAtumLogSender::SendLogMessageITEMTryEnchantInfo(this, i_pTargetItemG, TRY_ENCHANT_FAIL,&tempvectEnchantList);
		}
		// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
		
		// 2006-08-23 by cmkwon, 모든 인챈트를 가져온다
		vectENCHANT tmvectEnchant;
		this->PopAllEnchantByItemUID(&tmvectEnchant, i_pTargetItemG->UniqueNumber);

		if(false == tmvectEnchant.empty())
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2006-08-23 by cmkwon, 모든 인챈트 삭제
			ENCHANT *pDelEnchant				= new ENCHANT;
			pDelEnchant->TargetItemUniqueNumber	= i_pTargetItemG->UniqueNumber;
			pDelEnchant->TargetItemNum			= i_pTargetItemG->ItemNum;
			pDelEnchant->EnchantItemNum			= i_pEnchatItemG->ItemNum;
			// Update DB
#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG
			if( NULL != i_pPreventDestructionItemG )		// 파괴방지카드가 있으면 삭제 및 옥션리스트 추가 안함  
			{
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteAllEnchant, this, m_character.AccountUniqueNumber, pDelEnchant);
			}	
			else		// 파괴방지 카드가 없으면 삭제하지 말고, 옥션리스트 삽입  << 밑에서 삽입 
			{
			//	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DestroyAuction_AddItem, this, m_character.AccountUniqueNumber, pDelEnchant);	
			}
#else
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteAllEnchant, this, m_character.AccountUniqueNumber, pDelEnchant);
#endif
			// Update Client
			INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_DELETE_ALL_ENCHANT, T_FC_ITEM_DELETE_ALL_ENCHANT, pDeleteEnchant, SendBuf);
			pDeleteEnchant->ItemUniqueNumber	= i_pTargetItemG->UniqueNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_DELETE_ALL_ENCHANT));
		}

		// 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도
		BOOL bIs_DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT = FALSE;	// 파방카드 사용 여부
		if( NULL != i_pPreventDestructionItemG )
		{
			if ( TRUE == i_pPreventDestructionItemG->ItemInfo->IsExistDesParam(DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT) )
			{
				bIs_DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT = TRUE;	// 파방카드를 사용 함.
			}
			else
			{
				////////////////////////////////////
				// 핵프로그램을 사용함 강제 블락
				if( FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
				{
					SBLOCKED_ACCOUNT_INFO blockedAccInfo;
					MEMSET_ZERO(&blockedAccInfo, sizeof(SBLOCKED_ACCOUNT_INFO));
					
					blockedAccInfo.AdminFieldServerClientIndex	= GetCharacter()->ClientIndex;
					sprintf(blockedAccInfo.szBlockedAccountName, "%s", m_character.AccountName);
					sprintf(blockedAccInfo.szBlockAdminAccountName, "AutoBlockSystem");
					blockedAccInfo.enBlockedType = T_BLOCKEDACCOUNT_ITEM_RELATED;
					blockedAccInfo.atimeStartTime.SetCurrentDateTime();
					
#if defined(TEST140) || defined(WIKIGAMES_ENG)		// 2013-05-22 by bckim, 캐나다 영구블럭 정책에 따르는 기간변경 +(2000년 + 하루)
					blockedAccInfo.atimeEndTime.SetDateTime(blockedAccInfo.atimeStartTime.Year + 2000, blockedAccInfo.atimeStartTime.Month, blockedAccInfo.atimeStartTime.Day+1, 1, 1, 1);
#else
					blockedAccInfo.atimeEndTime.SetDateTime(2200, 1, 1, 1, 1, 1); //AddDateTime(0, 0, 72000);		// 데충 200년				//blockedAccInfo.atimeEndTime	= blockedAccInfo.atimeStartTime;
#endif			
					// 2014-03-10 by jekin, 캐나다 치트엔진 사용 인첸트 시도 로그 추가
					sprintf(blockedAccInfo.szBlockedReasonForUser, "Account suspended");
					sprintf(blockedAccInfo.szBlockedReasonForOnlyAdmin, "Try enchant using hack program2. Enchant:%I64d Target:%I64d Attach:%I64d IncreaseProbability:%I64d",i_pEnchatItemG?i_pEnchatItemG->UniqueNumber:0,i_pTargetItemG?i_pTargetItemG->UniqueNumber:0,i_pPreventDestructionItemG?i_pPreventDestructionItemG->UniqueNumber:0,i_pProbabilityIncreaseItemG?i_pProbabilityIncreaseItemG->UniqueNumber:0);
					
					INIT_MSG_WITH_BUFFER(MSG_FP_ADMIN_BLOCKACCOUNT, T_FP_ADMIN_BLOCKACCOUNT, pBlockAcc, SendBuf);
					pBlockAcc->blockAccInfo	= blockedAccInfo;
					ms_pFieldIOCP->Send2PreServerW(SendBuf, MSG_SIZE(MSG_FP_ADMIN_BLOCKACCOUNT));
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[HACK] CFieldIOCPSocket::TryEnchantItem _ AutoBlockSystem : Try enchant using hack program and Blocked AUID(%d) CUID(%d) Enchant:%I64d Target:%I64d Attach:%I64d IncreaseProbability:%I64d\r\n", m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber,i_pEnchatItemG?i_pEnchatItemG->UniqueNumber:0,i_pTargetItemG?i_pTargetItemG->UniqueNumber:0,i_pPreventDestructionItemG?i_pPreventDestructionItemG->UniqueNumber:0,i_pProbabilityIncreaseItemG?i_pProbabilityIncreaseItemG->UniqueNumber:0);
					// end 2014-03-10 by jekin, 캐나다 치트엔진 사용 인첸트 시도 로그 추가
				}
				else
				{
					SendString128(STRING_128_USER_POPUP, "AutoBlockSystem : Try enchant using hack program and Blocked");
				}
			}
		}
		// end 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도

//		if(i_pPreventDestructionItemG)			// 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도 - 주석처리
		if( TRUE == bIs_DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT )			// 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도
		{
			// 2013-01-08 by bckim, 10인챈트 미만 하이퍼카드 제거
			vectENCHANT::iterator itrEnchant;
			for ( itrEnchant = tmvectEnchant.begin(); itrEnchant != tmvectEnchant.end() ; )
			{
				ENCHANT_INFO *pTempEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(itrEnchant->EnchantItemNum);
				if (pTempEnchantInfo == NULL)
				{
					return ERR_NO_SUCH_ENCHANT_INFO;
				}

				// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
				// 기존 코드 주석 처리 
// 				INT64 TotalProb = 0;
// 				for( int ProbLevel = 0; ProbLevel<10; ProbLevel++)
// 				{
// 					TotalProb += pTempEnchantInfo->ProbabilityPerLevel[ProbLevel];
// 				}
				
				// 2013-04-04 by bckim, 인챈트 시퀀스 넘버 받지못하는 버그
				if( 0 == itrEnchant->SequenceNumber_DB )
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ Enchant SEQ_NUM ERROR!! ][%s][%s][%d][%I64d][%d][%d][%I64d] \r\n",this->m_character.AccountName, this->m_character.CharacterName,
							this->m_character.CharacterUniqueNumber,itrEnchant->TargetItemUniqueNumber,itrEnchant->TargetItemNum,itrEnchant->EnchantItemNum,itrEnchant->SequenceNumber_DB);						
				}
				// End. 2013-04-04 by bckim, 인챈트 시퀀스 넘버 받지못하는 버그 

				if( TRUE == IsHyperCard(pTempEnchantInfo) )
				{
					// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
					//g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Debug Info] HyperEnchant exist within below Enchant_lv10 (%s|%s|%d|%d \r\n",this->m_character.AccountName, this->m_character.CharacterName,this->m_character.CharacterUniqueNumber, itrEnchant->EnchantItemNum );
					//tmvectEnchant.erase(itrEnchant);
					// 로그 추가 
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TRY_ENCHANT_ERROR] HyperEnchant exist within below Enchant_lv10 (%s|%s|%d|%d \r\n",this->m_character.AccountName, this->m_character.CharacterName,this->m_character.CharacterUniqueNumber, itrEnchant->EnchantItemNum );
					// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
				}
				
					itrEnchant++;
				}
			// End. 2013-01-08 by bckim, 10인챈트 미만 하이퍼카드 제거

			sort(tmvectEnchant.begin(), tmvectEnchant.end(), ENCHANT_ITEM_SORT_BY_SEQUENCE_NUMBER()); 			// 2013-01-15 by bckim, 인챈트아이템 시퀀스넘버 추가
			int nRepairEnchantCnt = min(tmvectEnchant.size(), i_pPreventDestructionItemG->ItemInfo->GetParameterValue(DES_ENCHANT_PREVENTION_DELETE_SAVE_ENCHANT));
			for(int i=0; i < nRepairEnchantCnt; i++)
			{
				// ENCHANT 생성, DB parameter로 넘기기 위해 new로 생성함
				ENCHANT *pNewEnchant				= new ENCHANT;
				pNewEnchant->TargetItemUniqueNumber	= i_pTargetItemG->UniqueNumber;
				pNewEnchant->TargetItemNum			= i_pTargetItemG->ItemNum;
				pNewEnchant->EnchantItemNum			= tmvectEnchant[i].EnchantItemNum;
				pNewEnchant->SequenceNumber_DB		= tmvectEnchant[i].SequenceNumber_DB;		// 2013-01-15 by bckim, 인챈트아이템 시퀀스넘버 추가
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ENCHANT_SEQ_NUM_SORT][%d] [%I64d][%d][%d][%I64d]\r\n",i,tmvectEnchant[i].TargetItemUniqueNumber,tmvectEnchant[i].TargetItemNum,tmvectEnchant[i].EnchantItemNum,tmvectEnchant[i].SequenceNumber_DB);

				// 삽입
				InsertEnchantToItem(i_pTargetItemG, *pNewEnchant);

				// Send MSG
				INIT_MSG_OF_SIZE(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pPutEnchant, pPutEnchantBuf);
				pPutEnchant->Enchant = *pNewEnchant;
				SendAddData(pPutEnchantBuf, MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));

				// Update DB
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertEnchant, this, m_character.AccountUniqueNumber, pNewEnchant);
			}
			
			i_nEnchantCnt	= nRepairEnchantCnt;	// 인챈트 카운트 재설정

			// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
			if (NULL != i_pTargetItemG)
			{
				mt_auto_lock maA(&m_mapEnchant);	// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - GetAllEnchantListPtrByItemUID 호출전에 꼭 먼저 락을 걸어야 함.
				vectENCHANT tempvectEnchantList;
				int nPreventCount = i_pPreventDestructionItemG->ItemInfo->GetParameterValue(DES_ENCHANT_PREVENTION_DELETE_SAVE_ENCHANT);
				this->GetAllEnchantListByItemUID(&tempvectEnchantList,i_pTargetItemG->UniqueNumber);
				CAtumLogSender::SendLogMessageITEMTryEnchantInfo(this, i_pTargetItemG, nPreventCount,&tempvectEnchantList);
				this->ExsistHyperCardIn10Lv(i_pTargetItemG->UniqueNumber);			 // 10인챈트이하 하이퍼카드가 적용되어있으면 로그 남기기 
			}
			// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
		}
		else
		{
			// 실패할 경우, target item도 삭제한다
#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG
			m_ItemManager.DeleteItemFromCharacterByUID(i_pTargetItemG->UniqueNumber, IUT_ENCHANT, ITEM_IN_CHARACTER, TRUE, TRUE, TRUE,GLOG_DEFAULT_ZERO, 1);
#else
			m_ItemManager.DeleteItemFromCharacterByUID(i_pTargetItemG->UniqueNumber, IUT_ENCHANT);
#endif
			LogItemParameter.LogType		= GLOG_IL_LT_ENCHANT_DESTROY;	//	2012-11-21 by khkim, GLog 2차
		}
	}

	*o_pbSuccessFlag	= bEnchantSuccess;

	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (추가 수정) - 
	CAtumLogSender::SendLogMessageITEMUseENCHANT(this, i_pTargetItemG, i_pEnchatItemG, i_nEnchantCnt, bEnchantSuccess, i_pPreventDestructionItemG, i_pProbabilityIncreaseItemG);

	ITEM_GENERAL tmpItemForLog = *i_pEnchatItemG;
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
	m_ItemManager.UpdateItemCountByPointer(i_pEnchatItemG, -1, IUT_ENCHANT);		// Current 수정하기

	if(i_pPreventDestructionItemG)
	{
		tmpItemForLog = *i_pPreventDestructionItemG;
		tmpItemForLog.CurrentCount--;
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(i_pPreventDestructionItemG, -1, IUT_ENCHANT);	// Current 수정하기
	}

	if(i_pProbabilityIncreaseItemG)
	{
		tmpItemForLog = *i_pProbabilityIncreaseItemG;
		tmpItemForLog.CurrentCount--;
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(i_pProbabilityIncreaseItemG, -1, IUT_ENCHANT);	// Current 수정하기
	}

	if(0 < pEnchantInfo->EnchantCost)
	{
		// 돈 지우기
		tmpItemForLog = *pMoney;
		tmpItemForLog.CurrentCount = max(0, pMoney->CurrentCount - pEnchantInfo->EnchantCost);
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(pMoney, -pEnchantInfo->EnchantCost, IUT_ENCHANT);
	}

	// start 2012-11-21 by khkim, GLog 2차
	// ENCHANT GLog 패킷Send 부분
	// 2015-02-10 by bckim, 임시 허용 
	//	if(!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))		// 2013-01-18 by khkim, GLog (일반유저만 기록)	
	{
		LogItemParameter.ItemSerial		= (UID64_t)i_pTargetItemG->ItemNum;	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅
		LogItemParameter.Count1			= (UID64_t)EnchantBefore;	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅
		LogItemParameter.Count2			= (UID64_t)i_nEnchantCnt;	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅
		// 2013-05-30 by jhseol, GLog 시스템 보완
//		LogItemParameter.CharSerial		= NULL;
		LogItemParameter.CharSerial		= (UID64_t)m_character.CharacterUniqueNumber;
		// end 2013-05-30 by jhseol, GLog 시스템 보완
		LogItemParameter.CharLv			= (int)m_character.Level;	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅
		LogItemParameter.GameServerID	= g_pFieldGlobal->GetMGameServerID();
		CAtumLogSender::SendLogItem(&LogItemParameter);
	}
	// end 2012-11-21 by khkim, GLog 2차
	
	return ERR_NO_ERROR;
}

// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
BOOL CFieldIOCPSocket::IsHyperCard(ENCHANT_INFO *i_pEnchantInfo)
{
	if( NULL == i_pEnchantInfo )
	{ return FALSE; }

	INT64 nTotalProb = 0;
	for(int i=0; i<10; i++)
	{
		nTotalProb += i_pEnchantInfo->ProbabilityPerLevel[i];

		if( nTotalProb > 0 )
		{
			return FALSE;
		}
	}
	return TRUE; 
}	
BOOL CFieldIOCPSocket::ExsistHyperCardIn10Lv(UID64_t i_nItemUID)				
{
	//mt_auto_lock maA(&m_mapEnchant);	// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - 함수 호출 상위에서 이미 락을 걸기때문에 주석처리
 	vectENCHANT tempvectEnchantList;
	GetAllEnchantListByItemUID(&tempvectEnchantList,i_nItemUID);											// 리스트 가져오고 
	sort(tempvectEnchantList.begin(), tempvectEnchantList.end(), ENCHANT_ITEM_SORT_BY_SEQUENCE_NUMBER());	// 정렬 

	if( TRUE == tempvectEnchantList.empty()) // 인챈트리스트가 없으면 하이퍼카드도 없음
	{
		return FALSE; 
	}

	vectENCHANT::iterator itr = tempvectEnchantList.begin();
	int count = 0;
	while( itr != tempvectEnchantList.end() || 10 <= count)
	{
		ENCHANT_INFO *pTempEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(itr->EnchantItemNum);
		if( NULL == pTempEnchantInfo)
		{
			return FALSE;
		}
		if( TRUE == IsHyperCard(pTempEnchantInfo) )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TRY_ENCHANT_ERROR] HyperEnchant exist within below Enchant_lv10 (%s|%s|%d|%I64d \r\n",
				this->m_character.AccountName, this->m_character.CharacterName,this->m_character.CharacterUniqueNumber, i_nItemUID);
			return TRUE; 	// 하나라도 발견되면 로그 남김
		}
		itr++;
		count++;
	}

	return FALSE; 
}
// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
/// \author		cmkwon
/// \date		2010-04-20 ~ 2010-04-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::TryGambleItem(BOOL *o_pbSuccessFlag, ITEM_GENERAL *i_pTargetItemG, int i_nEnchantCnt, ITEM_GENERAL *i_pGambleCard1ItemG, ITEM_GENERAL *i_pGambleCard2ItemG)
{
	if(NULL == i_pGambleCard1ItemG && NULL == i_pGambleCard2ItemG)
	{
		// 2010-04-21 by cmkwon, 옵션카드가 없으면 에러처리
		return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
	}
	if(i_pGambleCard1ItemG && i_pGambleCard2ItemG)
	{
		// 2010-04-21 by cmkwon, 둘다 같은 옵션이면 에러 처리
		if( (i_pGambleCard1ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX) && i_pGambleCard2ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX))
			|| (i_pGambleCard1ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX)	&& i_pGambleCard2ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX)) )
		{
			return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
		}
	}

	ITEM_GENERAL	*pPrefixItemG = NULL;
	ITEM_GENERAL	*pSuffixItemG = NULL;
	BOOL			bSuccessPrefix = FALSE;
	BOOL			bSuccessSuffix = FALSE;
	if(i_pGambleCard1ItemG)
	{
		if(i_pGambleCard1ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX))
		{
			pPrefixItemG = i_pGambleCard1ItemG;
		}
		else
		{
			pSuffixItemG = i_pGambleCard1ItemG;
		}
	}
	if(i_pGambleCard2ItemG)
	{
		if(i_pGambleCard2ItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX))
		{
			pPrefixItemG = i_pGambleCard2ItemG;
		}
		else
		{
			pSuffixItemG = i_pGambleCard2ItemG;
		}
	}

	int nCostGamble = 0;

	if(pPrefixItemG)
	{
		// 인챈트 정보 검색
		ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pPrefixItemG->ItemNum);
		if (pEnchantInfo == NULL)
		{			
			return ERR_NO_SUCH_ENCHANT_INFO;
		}
		nCostGamble	+= pEnchantInfo->EnchantCost;

		Prob10K_t nRandValue			= ms_pFieldIOCP->GetRandInt32(0, MAX_RAND10K_VALUE);	// 2007-12-10 by cmkwon, 랜덤 시스템 수정 - 
		Prob10K_t EnchantProbability	= pEnchantInfo->ProbabilityPerLevel[0];					// 캠블 카드는 무조건 첫 확률만 쓴다.
		
		///////////////////////////////////////////////////////////////////////////////
		// 2007-10-02 by cmkwon, 하이퍼 인챈트 카드 추가로 인챈트/갬블 확률이 0인 것은 사용이 불가능 하다
		if(0 >= EnchantProbability)
		{
			return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
		}
		if(nRandValue <= EnchantProbability)
		{
			bSuccessPrefix	= TRUE;
		}
	}

	if(pSuffixItemG)
	{
		// 인챈트 정보 검색
		ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pSuffixItemG->ItemNum);
		if (pEnchantInfo == NULL)
		{			
			return ERR_NO_SUCH_ENCHANT_INFO;
		}
		nCostGamble	+= pEnchantInfo->EnchantCost;

		Prob10K_t nRandValue			= ms_pFieldIOCP->GetRandInt32(0, MAX_RAND10K_VALUE);	// 2007-12-10 by cmkwon, 랜덤 시스템 수정 - 
		Prob10K_t EnchantProbability	= pEnchantInfo->ProbabilityPerLevel[0];					// 캠블 카드는 무조건 첫 확률만 쓴다.
		
		///////////////////////////////////////////////////////////////////////////////
		// 2007-10-02 by cmkwon, 하이퍼 인챈트 카드 추가로 인챈트/갬블 확률이 0인 것은 사용이 불가능 하다
		if(0 >= EnchantProbability)
		{
			return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
		}
		if(nRandValue <= EnchantProbability)
		{
			bSuccessSuffix	= TRUE;
		}
	}

	// 돈 확인
	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (pMoney == NULL || pMoney->CurrentCount < nCostGamble)
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		return ERR_PROTOCOL_NOT_ENOUGH_MONEY;
	}

	if(FALSE == bSuccessPrefix && FALSE == bSuccessSuffix)
	{
		return ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED;
	}

	// start 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션

	if( NULL != pPrefixItemG && TRUE == pPrefixItemG->ItemInfo->IsExistDesParam(DES_GAMBLE_RARE_ITEM_FIX) )
	{
#ifdef S_EP4_HSKIM		// ON/OFF 기능 구현
#else
		return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
#endif

		if( FALSE == ms_pFieldIOCP->CheckFixRareCode(i_pTargetItemG->ItemInfo, TRUE, pPrefixItemG->ItemInfo->GetParameterValue(DES_GAMBLE_RARE_ITEM_FIX)) )
		{
			return ERR_PROTOCOL_CANNOT_ENCHANT_LACK_REQUIREMENT;
		}
	}

	if( NULL != pSuffixItemG && TRUE == pSuffixItemG->ItemInfo->IsExistDesParam(DES_GAMBLE_RARE_ITEM_FIX) )
	{
#ifdef S_EP4_HSKIM		// ON/OFF 기능 구현
#else
		return ERR_PROTOCOL_CANNOT_ENCHANT_ITEM;
#endif
		if( FALSE == ms_pFieldIOCP->CheckFixRareCode(i_pTargetItemG->ItemInfo, FALSE, pSuffixItemG->ItemInfo->GetParameterValue(DES_GAMBLE_RARE_ITEM_FIX)) )
		{
			return ERR_PROTOCOL_CANNOT_ENCHANT_LACK_REQUIREMENT;
		}
	}
	// end 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션

	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 0527 by cmkwon, 빠진부분 추가 - 성공여부 플래그 TRUE로 설정
	*o_pbSuccessFlag	= TRUE;

	if(pPrefixItemG)
	{
		if(bSuccessPrefix)
		{
			// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 마지막 선택된 레어 정보를 인자로 전달한다.
			ApplyGambleRareFix(pPrefixItemG->ItemInfo, i_pTargetItemG, m_pLastSelectedPrefixRareItemInfo);
			m_pLastSelectedPrefixRareItemInfo = ms_pFieldIOCP->GetRareItemInfo(i_pTargetItemG->PrefixCodeNum);
		}

		// 인챈트/갬블 사용 시 대상 아이템 로그
		CAtumLogSender::SendLogMessageITEMUseENCHANT(this, i_pTargetItemG, pPrefixItemG, i_nEnchantCnt, bSuccessPrefix);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
	}

	if(pSuffixItemG)
	{
		if(bSuccessSuffix)
		{
			// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 마지막 선택된 레어 정보를 인자로 전달한다.
			ApplyGambleRareFix(pSuffixItemG->ItemInfo, i_pTargetItemG, m_pLastSelectedSuffixRareItemInfo);
			m_pLastSelectedSuffixRareItemInfo = ms_pFieldIOCP->GetRareItemInfo(i_pTargetItemG->SuffixCodeNum);
		}

		// 인챈트/갬블 사용 시 대상 아이템 로그
		CAtumLogSender::SendLogMessageITEMUseENCHANT(this, i_pTargetItemG, pSuffixItemG, i_nEnchantCnt, bSuccessSuffix);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
	}
	
	///////////////////////////////////////////////////////////////////////////////	
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 
	// Send MSG
	INIT_MSG_OF_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX, T_FC_STORE_UPDATE_RARE_FIX, pUpdateRareFix, pUpdateRareFixBuf);
	pUpdateRareFix->ItemUID			= i_pTargetItemG->UniqueNumber;
	pUpdateRareFix->PrefixCodeNum	= i_pTargetItemG->PrefixCodeNum;
	pUpdateRareFix->SuffixCodeNum	= i_pTargetItemG->SuffixCodeNum;
	SendAddData(pUpdateRareFixBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX));
	
	// Update DB
	QPARAM_UPDATE_ITEM_RARE_FIX *pQParam = new QPARAM_UPDATE_ITEM_RARE_FIX;
	pQParam->ItemUID				= i_pTargetItemG->UniqueNumber;
	pQParam->PrefixCodeNum			= i_pTargetItemG->PrefixCodeNum;
	pQParam->SuffixCodeNum			= i_pTargetItemG->SuffixCodeNum;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemRareFix, this, m_character.AccountUniqueNumber, pQParam);
	
	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 처리 이후 재료 아이템 처리

	if(pPrefixItemG)
	{
		ITEM_GENERAL tmpItemForLog = *pPrefixItemG;
		tmpItemForLog.CurrentCount--;
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(pPrefixItemG, -1, IUT_ENCHANT);		// Current 수정하기
	}
	if(pSuffixItemG)
	{
		ITEM_GENERAL tmpItemForLog = *pSuffixItemG;
		tmpItemForLog.CurrentCount--;
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(pSuffixItemG, -1, IUT_ENCHANT);		// Current 수정하기
	}

	if(0 < nCostGamble)
	{
		// 돈 지우기
		ITEM_GENERAL tmpItemForLog = *pMoney;
		tmpItemForLog.CurrentCount = max(0, pMoney->CurrentCount - nCostGamble);
		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);
		m_ItemManager.UpdateItemCountByPointer(pMoney, -nCostGamble, IUT_ENCHANT);
	}
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래중인 아이템 여부 리턴
/// \author		cmkwon
/// \date		2010-05-12 ~ 2010-05-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckTradingItem(UID64_t i_itemUID)
{
	if(FALSE == IS_VALID_UID64(i_itemUID)
		|| FALSE == IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		return FALSE;
	}

	mt_auto_lock TILock(&m_mapTradeItem);
	mtmapUID2TradeItem::iterator itrTrade = m_mapTradeItem.find(i_itemUID);
	if (itrTrade == m_mapTradeItem.end())
	{
		return FALSE;
	}

	return TRUE;
}

// 2010-06-01 by shcho, PC방 권한 획득(캐쉬) 아이템 - 
void CFieldIOCPSocket::SetHomepremium(BOOL i_bUse)
{
	m_bIsPCBangClient = i_bUse;
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_HOMEPREMIUM_INFO, T_FC_ITEM_HOMEPREMIUM_INFO, pHomepremiumInfo, SendBuf);
	pHomepremiumInfo->bUse = i_bUse;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_HOMEPREMIUM_INFO));	
}

// 2010-08-27 by shcho&&jskim, WARPOINT 증가 아이템 구현
BOOL CFieldIOCPSocket::SetWarPoint(INT i_nAddWarPoint)
{
	if(NULL == this->GetCharacter())
	{ // 케릭터가 없으면 에러

		return FALSE;
	}
	// 워포인트 추가
	this->m_character.WarPoint				+= i_nAddWarPoint;
	this->m_character.CumulativeWarPoint	+= i_nAddWarPoint;
		
	// start 2012-01-16 by hskim, 통계 - 화패
	if( NULL != ms_pFieldIOCP->m_pStatisticsManager )
	{
		ms_pFieldIOCP->m_pStatisticsManager->Add(STATISTICS_WAR_POINT, i_nAddWarPoint);
	}
	// end 2012-01-16 by hskim, 통계 - 화패

	// 2007-05-16 by dhjin, DB에 업데이트
	QPARAM_UPDATE_WARPOINT *pQparam = new QPARAM_UPDATE_WARPOINT;
	pQparam->CharacterUID		= this->m_character.CharacterUniqueNumber;
	pQparam->AccountUID			= this->m_character.AccountUniqueNumber;
	pQparam->TotalWarPoint		= this->m_character.WarPoint;
	pQparam->CumulativeWarPoint	= this->m_character.CumulativeWarPoint;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateWarPoint, this, this->m_character.AccountUniqueNumber, pQparam);
	
	// 2007-05-16 by dhjin, 클라이언트에게 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_PAY_WARPOINT, T_FC_CHARACTER_PAY_WARPOINT, pMsg, SendBuf);
	pMsg->WarPoint				= i_nAddWarPoint;
	pMsg->TotalWarPoint			= this->m_character.WarPoint;
	pMsg->CumulativeWarPoint	= this->m_character.CumulativeWarPoint;
	pMsg->UseItemFlag			= TRUE;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_PAY_WARPOINT));
	
	// 2014-03-20 by jekim, GLog 워포통계
#if defined(TEST140)
	if(1)
#else
	if(!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
#endif
	{
		MSG_FL_LOG_ITEM LogItemParameter;
		MEMSET_ZERO(&LogItemParameter, sizeof(LogItemParameter));
		LogItemParameter.LogType			= GLOG_IL_LT_WARPOINT_ADD; 
		LogItemParameter.Count1				= (UID64_t)i_nAddWarPoint;
		LogItemParameter.Count2				= (UID64_t)this->m_character.WarPoint;
		LogItemParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
		LogItemParameter.CharLv				= (int)m_character.Level;
		LogItemParameter.GameServerID		= g_pFieldGlobal->GetMGameServerID();
		CAtumLogSender::SendLogItem(&LogItemParameter);
	}
	// end 2014-03-20 by jekim, GLog 워포통계

	return TRUE;
}
// END 2010-08-27 by shcho&&jskim, WARPOINT 증가 아이템 구현

// start 2011-09-20 by hskim, 파트너 시스템 2차
Err_t CFieldIOCPSocket::PetCancelSocketItem(ITEM *i_pItemInfo)
{
	// 사용하기전에 Lock 걸고 호출 하세요
	//mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	if(ITEMKIND_PET_SOCKET_ITEM != i_pItemInfo->Kind)
	{
		return ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED;
	}

	if( NULL == m_ItemManager.FindUsingItemByItemNumNoLock(i_pItemInfo->ItemNum) )				
	{
		return ERR_PROTOCOL_NOT_ACTIVATED_ITEM;
	}

	if(FALSE == this->m_ItemManager.DeleteUsingTimeLimitedItemList(i_pItemInfo->ItemNum) )
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] DeleteUsingTimeLimitedItemList error !!, CFieldIOCPSocket::PetCancelSocketItem User(%s) ItemNum(%d)\r\n"
			, GetCharacterString(GetCharacter(), string()), i_pItemInfo->ItemNum);
	}

	//igLock.auto_unlock_cancel();

	return ERR_NO_ERROR;
}
// end 2011-09-20 by hskim, 파트너 시스템 2차

// start 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어
BOOL CFieldIOCPSocket::TestMonsterDropItems(int MonsterIndex, int TestCount)
{
	mapMonsterDropItemTest mapMonsterDropItem;
	vectorMonsterDropItemTest vectorMonsterDropItem;
	MONSTER_INFO *pMonsterInfo = ms_pFieldIOCP->GetMonsterInfo (MonsterIndex);

	if( NULL == pMonsterInfo )
	{
		return FALSE;
	}

	for(int i=0; i<TestCount; i++)
	{
		ms_pFieldIOCP->TestDropItems(pMonsterInfo, &mapMonsterDropItem);
	}

	mapMonsterDropItemTest::iterator itrDropTest = mapMonsterDropItem.begin();
	while(itrDropTest != mapMonsterDropItem.end())
	{
		MONSTER_DROP_ITEM_TEST_INFO *pDropItemInfo = &itrDropTest->second;

		vectorMonsterDropItem.push_back(*pDropItemInfo);

		itrDropTest++;
	}

	sort(vectorMonsterDropItem.begin(), vectorMonsterDropItem.end(), Sort_MonsterDropItemTestInfo_by_CurrentCount());

	SendString128(STRING_128_DEBUG_PRINT, "----------------------------------------");
	SendString128(STRING_128_DEBUG_PRINT, "%s (%d) %ld", pMonsterInfo->MonsterName, pMonsterInfo->MonsterUnitKind, TestCount);
	SendString128(STRING_128_DEBUG_PRINT, "----------------------------------------");

	vectorMonsterDropItemTest::iterator itrDropTestVector = vectorMonsterDropItem.begin();
	while(itrDropTestVector != vectorMonsterDropItem.end())
	{
		MONSTER_DROP_ITEM_TEST_INFO *pDropItemInfo = itrDropTestVector;

		ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pDropItemInfo->ItemNum);

		if( NULL == pItemInfo )
		{
			continue;
		}

		SendString128(STRING_128_DEBUG_PRINT, "%s (%d) = %ld", pItemInfo->ItemName, pDropItemInfo->ItemNum, pDropItemInfo->CurrentCount);

		itrDropTestVector++;
	}

	SendString128(STRING_128_DEBUG_PRINT, "----------------------------------------");

	vectorMonsterDropItem.clear();
	mapMonsterDropItem.clear();	

	return TRUE;
}
// end 2012-02-13 by hskim, 몬스터 아이템 드랍 테스트 명령어

// 2010-06-01 by shcho, GLogDB 관련 -
MOSTSTAYED_MAP_INFO* CFieldIOCPSocket::FindStayedMapInfo(MapIndex_t i_MapIndex)
{
	vectStayedMapInfo::iterator iter(m_vectStayedMapInfo.begin());
	for(;iter!=m_vectStayedMapInfo.end();iter++)
	{
		if(iter->MapIndex == i_MapIndex)
		{
			return iter;
		}		
	}

	return NULL;
}

// 2010-06-01 by shcho, GLogDB 관련 -
const char * CFieldIOCPSocket::GetStayedMapName()
{
	MOSTSTAYED_MAP_INFO TempInfo;
	MEMSET_ZERO(&TempInfo,sizeof(MOSTSTAYED_MAP_INFO));

	vectStayedMapInfo::iterator iter(m_vectStayedMapInfo.begin());
	for(;iter!=m_vectStayedMapInfo.end();iter++)
	{
		if(iter->StayedTime > TempInfo.StayedTime) //총 시간이 가장 많은 맵 인덱스이면
		{
			TempInfo.MapIndex	= iter->MapIndex;
			TempInfo.StayedTime	= iter->StayedTime;
		}		
	}

	return CAtumSJ::GetMapName(TempInfo.MapIndex);
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_CHANGE_BODYCONDITION(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize = 0;
	MSG_FN_MONSTER_CHANGE_BODYCONDITION		*pRecvBody = NULL;
	
	nRecvTypeSize = sizeof(MSG_FN_MONSTER_CHANGE_BODYCONDITION);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pRecvBody = (MSG_FN_MONSTER_CHANGE_BODYCONDITION*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterChangeBodyconditionW(pRecvBody);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_SKILL_USE_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize = 0;
	MSG_FN_MONSTER_SKILL_USE_SKILL		*pReUseSkill = NULL;
	
	nRecvTypeSize = sizeof(MSG_FN_MONSTER_SKILL_USE_SKILL);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FN_MONSTER_SKILL_USE_SKILL, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14059);
		return RES_RETURN_FALSE;
	}
	pReUseSkill = (MSG_FN_MONSTER_SKILL_USE_SKILL*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	m_pFieldMapProjectForNPC->FieldOnMonsterSkillUseSkillW(pReUseSkill);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_SKILL_END_SKILL(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FN_MONSTER_SKILL_END_SKILL
		, MSG_FN_MONSTER_SKILL_END_SKILL, pReEndSkill);


	m_pFieldMapProjectForNPC->FieldOnMonsterSkillEndSkillW(pReEndSkill);
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_AUTO_DESTROYED(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-17 ~ 2006-04-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_AUTO_DESTROYED(const char* pPacket, int nLength, int &nBytesUsed)
{

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FN_MONSTER_AUTO_DESTROYED
		, MSG_FN_MONSTER_AUTO_DESTROYED, pRDestroyed);

	// 2007-11-26 by cmkwon, 몬스터 자동삭제 메시지 TCP로 전송(N->F) - 아래와 같이 수정함
	//m_pFieldMapProjectForNPC->FieldOnMonsterAutoDestroyedW(pRDestroyed);
	CFieldMapProject  *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pRDestroyed->MapChannIdx.MapIndex);
	if(NULL == pFMPro)
	{
		return RES_BREAK;
	}
	pFMPro->FieldOnMonsterAutoDestroyedW(pRDestroyed);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_HPTALK(const char* pPacket, int nLength, int &nBytesUsed)	
/// \brief		인피니티 - 몬스터 대사 클라이언트로 전송
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FN_MONSTER_HPTALK(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FN_MONSTER_HPTALK, MSG_FN_MONSTER_HPTALK, pRMsg);
	
	INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_HPTALK, T_FC_MONSTER_HPTALK, pSMsg, pSBuf);
	pSMsg->MonsterIndex		= pRMsg->MonsterIndex;
	pSMsg->MonsterUnitKind	= pRMsg->MonsterUnitKind;
	pSMsg->HPTalkImportance = pRMsg->HPTalkImportance;
	pSMsg->HPCameraTremble	= pRMsg->HPCameraTremble;
	pSMsg->TargetIndex		= pRMsg->TargetIndex;
	STRNCPY_MEMSET(pSMsg->HPTalk, pRMsg->HPTalk, SIZE_MAX_HPTALK_DESCRIPTION);

	switch (pRMsg->HPTalkImportance) {
		case HPACTION_TALK_IMPORTANCE_CHANNEL : { 
			CFieldMapChannel *pFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(pRMsg->ChannelIndex); 
			if(NULL == pFMChann) {
				return RES_BREAK;
			}
			pFMChann->SendMessageToAllInChannel(pSBuf, MSG_SIZE(MSG_FC_MONSTER_HPTALK));
		} break;
		case HPACTION_TALK_IMPORTANCE_INFL : {
			// 어떤 방식으로 세력을 구분할것인지 모른다. 아직 미구현 
		 } break;
		case HPACTION_TALK_IMPORTANCE_ALL : {
			ms_pFieldIOCP->SendMessageToAllClients(pSBuf, MSG_SIZE(MSG_FC_MONSTER_HPTALK), INFLUENCE_TYPE_ALL_MASK);
		} break;
	}

	CAtumLogSender::SendLogMessageHPActionTalk(pRMsg->MonsterUnitKind, pRMsg->HPTalk);	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가, 몬스터 대화 사용시
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SKILL_CANCEL(const char* pPacket, int nLength, int &nBytesUsed) 
/// \brief		인피니티(기지방어) - 
/// \author		dhjin
/// \date		2010-03-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SKILL_CANCEL(const char* pPacket, int nLength, int &nBytesUsed) 
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FN_BATTLE_ATTACK_SKILL_CANCEL, MSG_FN_BATTLE_ATTACK_SKILL_CANCEL, pRMsg);
	
	//g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] CFieldIOCPSocket::Process_FN_BATTLE_ATTACK_SKILL_CANCEL Map(%s) MonIdx(%d) SkillItemNum(%d) \r\n", GetMapString(pRMsg->MapInfo, string()), pRMsg->MonsterIndex, pRMsg->SkillItemNum);
	
	CFieldMonster *ptmFMonster = m_pFieldMapProjectForNPC->GetFieldMonsterW(pRMsg->MapInfo.ChannelIndex, pRMsg->MonsterIndex, 100);
	if(NULL == ptmFMonster
		|| ptmFMonster->m_enMonsterState != MS_PLAYING
		|| TRUE == COMPARE_BODYCON_BIT(ptmFMonster->BodyCondition, BODYCON_DEAD_MASK)) {
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_SKILL_CANCEL, T_FC_MONSTER_SKILL_CANCEL, msgUseSkillOK, SendBuf);
	msgUseSkillOK->SkillItemNum	= pRMsg->SkillItemNum;
	msgUseSkillOK->MonsterIndex	= pRMsg->MonsterIndex;
	ptmFMonster->m_pCurrentFieldMapChannelMonster->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MONSTER_SKILL_CANCEL));

	return RES_RETURN_TRUE;
}

BOOL CFieldIOCPSocket::CharacterGameStartRoutine(GameStartType type)
{
	CMTAutoCriticalSection mtAuto(m_mtCritSecForGameEndRoutine.GetCriticalSectionPtr());
	///////////////////////////////////////
	// GameStartType
	// * GST_GAMESTART				= 0
	// * GST_CONN_GAMESTART			= 1
	// * GST_WARP_CONN_GAMESTART	= 2
	// * GST_WARP_SAME_MAP			= 3
	// * GST_WARP_SAME_FIELD_SERVER	= 4
	///////////////////////////////////////

	BYTE SendBuf[SIZE_MAX_PACKET];
	MessageType_t msgType		= T_NA;
	switch(type)
	{
	case GST_GAMESTART:				msgType = T_FC_CHARACTER_GAMESTART;				break;
// 2005-07-21 by cmkwon, 다른 필드서버로의 GameStart는 없으므로 삭제함
//	case GST_CONN_GAMESTART:		msgType = T_FC_CHARACTER_CONNECT_GAMESTART;		break;
// 2004-12-16 by cmkwon, 다른 필드서버로의 워프는 없으므로 삭제함
//	case GST_WARP_CONN_GAMESTART:	msgType = T_FC_EVENT_WARP_CONNECT;				break;
	default:
		{
			return FALSE; 
		}
	}

	/*/////////////////////////////////////////////////////////////////////////
	// Game Start Routine
	// - pre server의 인증 및 m_character 할당은 끝났다고 가정함!!!
	//
	// * 각종 flag 및 변수 초기화
	// * m_pCurrentFieldMapChannel 할당
	// * 이동 불가 지역에 있으면 기본 위치로 이동
	// * m_mapCharacterUniqueNumber와 m_mapCharacterName에 추가
	// * party 초기화
	// * SetInitialPosition
	// * MSG_FC_CHARACTER_GAMESTART_OK 전송
	// * NPC Server에게 MSG_FN_CLIENT_GAMESTART_OK 전송
	// * MSG_FC_STORE_GET_ITEM를 DB에 요구(메시지는 서버가 만듬)
	// * SendInRangeCharacterOtherInfo
	// * init log
	// * IM Server에 IP 등록
	/////////////////////////////////////////////////////////////////////////*/

	// 각종 flag 및 변수 초기화
	m_bFlagDBStore				= TRUE;
	m_bFieldServerChangeFlag	= FALSE;
	this->SetClientState(CS_PLAYING);
	m_dwLastTickSpeedHackCheck = timeGetTime();
	m_ExperienceDelayStore		= m_character.Experience;			// 2006-05-21 by cmkwon
	this->m_dwReadyTickforSecurityCheck		= timeGetTime();		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 

// 2008-01-08 by cmkwon, CheckCurrentMapOnGameStart() 에서 체크
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-12-12 by dhjin, 맵정보 전송 부분 변경으로 유저가 올바른 맵에 있는지 체크한다.
//	if(IS_CONFERENCEROOM_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
//	{
//		CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(CFieldMapProject::GetConferenceRoomMapIndex(m_character.InfluenceType));
//		if(NULL == pFMPro
//			|| FALSE == pFMPro->IsWarpableUser(m_character.CharacterUniqueNumber, m_character.Race))
//		{	
//			CFieldMapChannel *pFMChann = this->GetCityFieldMapChannelPtr();
//			if(NULL == pFMChann)
//			{
//				return FALSE;
//			}
//			m_character.MapChannelIndex	= pFMChann->GetMapChannelIndex();
//			m_character.PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
//		}
//	}
//	else if(IS_OUTPOST_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
//		|| IS_MAP_INFLUENCE_OUTPOST(GetFieldMapChannel(&m_character.MapChannelIndex, TRUE, TRUE)->GetMapInfluenceTypeW()))
//	{	// 2007-09-28 by dhjin, 전진기지도시맵에서 시작시 소유 여단이 아니면 마을로
//		if(m_character.MapChannelIndex.MapIndex != ms_pFieldIOCP->m_OutPostManager.GetOutPostCityMapIndexByGuildUID(m_character.GuildUniqueNumber))
//		{
//			CFieldMapChannel *pFMChann = this->GetCityFieldMapChannelPtr();
//			if(NULL == pFMChann)
//			{
//				return FALSE;
//			}
//			m_character.MapChannelIndex	= pFMChann->GetMapChannelIndex();
//			m_character.PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
//		}
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - 선택창으로 갔다가 게임 시작시 처음 접속시 지속시간으로 설정
	if(LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType())
	{
		// 2012-10-30 by jhseol, 베트남 플레이타임 - 케릭터 기준 게임 시작시 리셋되도록 요청하여 플레이타임 초기화 해줌.
		//m_nGameContinueTimeInSecondOfToday = m_nGameContinueTimeInSecondOfToday4Viet;		// << 기존 - 날짜가 바뀌었을때 초기화 모드
		m_nGameContinueTimeInSecondOfToday = 0;												// << 변경 - 게임 시작시 초기화 모드
		// end 2012-10-30 by jhseol, 베트남 플레이타임 - 케릭터 기준 게임 시작시 리셋되도록 요청하여 플레이타임 초기화 해줌.
	}
	
	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 여기에서 초기화를 한다.
	m_WeaponIndexGenerator.Reset();			

	// 2006-02-09 by cmkwon, 자신이 타세력에 의해 죽을 경우 줘야 할 킬마크 설정
	this->ResetGiveKillMarkItemPtr2Killer();

// 2008-01-08 by cmkwon, 아래로 위치 이동함
//	if(FALSE == IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
//		&& COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
//	{// 2007-07-19 by cmkwon, 튜토리얼맵에서는 적용하지 않음 // 2006-05-08 by cmkwon, 관리자/운영자는 투명상태, 스텔스모드, 무적상태로 시작됨
//// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
////		SetBodyConditionBit(m_character.BodyCondition, BODYCON_STEALTH_MASK);
//		m_bIsInvisibleCharacter	= TRUE;		// 2006-11-08 by cmkwon
//		m_bStealthState			= TRUE;
//		m_bNoDamage				= TRUE;		// 2006-05-09 by cmkwon
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 프리미엄 카드 체크
	if(m_ItemManager.IsExistPremiumCard()
		&& FALSE == m_ItemManager.CashCheckPremiumCardExpire())
	{
		INIT_MSG(MSG_FI_CASH_PREMIUM_CARD_INFO, T_FI_CASH_PREMIUM_CARD_INFO, pIMSCardInfo, SendBuf); // 2006-09-14 by dhjin, IM서버에 맴버쉽정보 알려준다.
		m_ItemManager.Make_MSG_FI_CASH_PREMIUM_CARD_INFO(pIMSCardInfo);
		ms_pFieldIOCP->Send2IMServer(SendBuf, MSG_SIZE(MSG_FI_CASH_PREMIUM_CARD_INFO));
	}
	
//	m_ItemManager.CashCheckPremiumCardExpire();

	// 스트링128 출력 level 결정
	if (COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR))
	{
		m_STRING_128_print_level = STRING_128_ADMIN_CMD;
	}

// 2008-01-08 by cmkwon, 버그 수정 - CFieldIOCPSocket::ResGetCharacterInfoByName() 에서 처리
//	///////////////////////////////////////////////////////////////////////////////	
//	// 2008-01-08 by dhjin, 케릭터 선택창에서 설정 및 전송 - 2007-12-26 by cmkwon, CurrentMap 체크 시스템 수정 - 지도자, 부지도자 설정 체크
//	ms_pFieldIOCP->m_InflWarManager.SetLeader8SubLeaderRACE(&m_character);	// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, CurrentMap 체크 시스템 수정 -
	if(FALSE == this->CheckCurrentMapOnGameStart())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CharacterGameStartRoutine_1 mapchannel error !!, %s: MapChannel[%s]\n", 
			GetCharacterString(&m_character, string()), GetMapString(m_character.MapChannelIndex, string()));
		Close(0x1405E);
		return FALSE;
	}

	// 2008-01-08 by cmkwon, 위치 이동
	if(FALSE == IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
		&& COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
	{// 2007-07-19 by cmkwon, 튜토리얼맵에서는 적용하지 않음 // 2006-05-08 by cmkwon, 관리자/운영자는 투명상태, 스텔스모드, 무적상태로 시작됨
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//		SetBodyConditionBit(m_character.BodyCondition, BODYCON_STEALTH_MASK);
		m_bIsInvisibleCharacter	= TRUE;		// 2006-11-08 by cmkwon
		m_bStealthState			= TRUE;
		m_bNoDamage				= TRUE;		// 2006-05-09 by cmkwon
	}

	// m_pCurrentFieldMapChannel 할당
	SetCurrentFieldMapChannel(GetFieldMapChannel(&m_character.MapChannelIndex, TRUE, TRUE));
	if (m_pCurrentFieldMapChannel == NULL)
	{
		// ERROR! All Channels Not Available
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CharacterGameStartRoutine_2 mapchannel error !!, %s: MapChannel[%s]\n", 
			GetCharacterString(&m_character, string()), GetMapString(m_character.MapChannelIndex, string()));
		Close(0x1405D);
		return FALSE;
	}
	
	// 2010-06-01 by shcho, GLogDB 관련 -
	m_StartStayedMapTime.SetCurrentDateTime(); // 현재 시간을 넣는다.
	MOSTSTAYED_MAP_INFO tempMapInfo; // 벡터에 추가할 맵인덱스와 시간정보
	tempMapInfo.MapIndex	=  m_character.MapChannelIndex.MapIndex; // 현재 맵 인덱스
	tempMapInfo.StayedTime	=  m_StartStayedMapTime.GetTimeDiffTimeInSeconds(this->m_character.LastStartedTime);
	m_vectStayedMapInfo.push_back(tempMapInfo);// 없으면 추가한다.

	// 2013-05-22 by jhseol, 소스정리 - 주석삭제

	///////////////////////////////////////////////////////////////////////////////
	// 도시점령전시 공격측, 방어측, 관람측 구별 설정함
	this->m_byCityWarTeamType	= m_pCurrentFieldMapChannel->m_pFieldMapProject->GetCityWarTeamTypeByGuildUID(this->GetCharacter()->GuildUniqueNumber);

	// m_mapCharacterUniqueNumber와 m_mapCharacterName에 추가
	if (type == GST_GAMESTART 
		|| type == GST_CONN_GAMESTART)
	{// 서버에 접속하는 유저의 처리, GST_WARP_CONN_GAMESTART는 처리 필요없음

		ms_pFieldIOCP->m_mapCharacterUniqueNumber.insertLock(m_character.CharacterUniqueNumber, this);
		m_pFieldParty			= NULL;			// party 초기화
	}
	char tmCharacterName[SIZE_MAX_CHARACTER_NAME];
	ms_pFieldIOCP->m_mapCharacterName.insertLock(GGetLowerCase(tmCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME), this);

	// Set Initial Position
	if(FALSE == m_pCurrentFieldMapChannel->SetInitialPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
	{
		char szTemp[256];
		sprintf(szTemp, "[Error] SetInitialPosition_2 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f)\n"
			, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
			, m_character.PositionVector.x, m_character.PositionVector.z);
		DBGOUT(szTemp);
		g_pGlobal->WriteSystemLog(szTemp);
	}
	m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.insertLock(m_character.CharacterUniqueNumber, this);

	// start 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
	if( TRUE == m_pCurrentFieldMapChannel->IsEnableTriggerMapBuff() )
	{
		m_pCurrentFieldMapChannel->GetTriggerMapBuffManager()->SetMapBuff(m_character.CharacterUniqueNumber, this);
	}
	// end 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	// 시간을 전송
	time_t ltime;
	struct tm *today = NULL;
	time(&ltime);
	today = localtime(&ltime);
	INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_SYNC_TIME, T_FC_CONNECT_SYNC_TIME, pSyncTime, pSyncTimeBuf);
	pSyncTime->CurrentTime = (today->tm_hour%4)*3600 + today->tm_min*60 + today->tm_sec;	// 4시간 기준으로 지난 초
	SendAddData(pSyncTimeBuf, MSG_SIZE(MSG_FC_CONNECT_SYNC_TIME));

	// GAME START OK를 보냄
	if (type == GST_GAMESTART)
	{
		// send MSG_FC_CHARACTER_GAMESTART_OK
		INIT_MSG(MSG_FC_CHARACTER_GAMESTART_OK, T_FC_CHARACTER_GAMESTART_OK, pSendCharacterGameStartOK, SendBuf);
		pSendCharacterGameStartOK->ClientIndex		= this->GetClientArrayIndex();
		STRNCPY_MEMSET(pSendCharacterGameStartOK->FieldServerIP, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_strFieldIP, SIZE_MAX_IPADDRESS);	// set field server IP
		pSendCharacterGameStartOK->FieldServerPort	= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_sFieldListenPort;
		pSendCharacterGameStartOK->CharacterMode0	= m_character.CharacterMode;
		pSendCharacterGameStartOK->PositionVector	= m_character.PositionVector;
		pSendCharacterGameStartOK->MapWeather		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_Weather;
		pSendCharacterGameStartOK->bMemberPCBang	= m_bIsPCBangClient;			// 2007-01-25 by cmkwon, 가맹 PC방 플래그
		STRNCPY_MEMSET(pSendCharacterGameStartOK->ServerGroupName0, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);			// 2007-04-09 by cmkwon
		STRNCPY_MEMSET(pSendCharacterGameStartOK->MainORTestServerName, g_pFieldGlobal->GetMainORTestServerName(), SIZE_MAX_SERVER_NAME);	// 2007-04-09 by cmkwon
		STRNCPY_MEMSET(pSendCharacterGameStartOK->GamePublisher, g_pFieldGlobal->GetGamePublisherName(), SIZE_MAX_GAME_PUBLISHER_NAME);		// 2007-04-09 by cmkwon
		pSendCharacterGameStartOK->MapInfo			= m_pCurrentFieldMapChannel->GetMapChannelIndex();

		// 2008-04-01 by cmkwon, 도시맵에서 죽은 상태의 기어 부활시켜서 캐릭터 상태로 처리 - 클라이언트에서 부활처리를 위해 필요한 필드 전송 함
		pSendCharacterGameStartOK->BodyCondition	= m_character.BodyCondition;
		pSendCharacterGameStartOK->CurrentHP		= m_character.CurrentHP;
		pSendCharacterGameStartOK->CurrentDP		= m_character.CurrentDP;
		pSendCharacterGameStartOK->CurrentEP		= m_character.CurrentEP;
		pSendCharacterGameStartOK->CurrentSP		= m_character.CurrentSP;

		SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMESTART_OK));
	}
	
	// 2013-05-22 by jhseol, 소스정리 - 주석삭제

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아머 컬렉션 로드
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 아머 컬렉션 로드
	if ( FALSE == g_pFieldGlobal->IsArenaServer() )
	{
		m_ArmorCollection.CollectionLoad();
	}
#endif
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아머 컬렉션 로드

	// NPC Server에 Character 의 GameStart 메세지를 전송한다.
	INIT_MSG(MSG_FN_CLIENT_GAMESTART_OK, T_FN_CLIENT_GAMESTART_OK, pSendClientGameStartOK, SendBuf);
	pSendClientGameStartOK->ChannelIndex			= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSendClientGameStartOK->ClientIndex				= m_character.ClientIndex;
	pSendClientGameStartOK->mexCharacter			= m_character;
	pSendClientGameStartOK->GuildMasterCharUID		= 0;
	pSendClientGameStartOK->bStealthState1			= TRUE;			// 기본적으로 스텔스 상태로 시작된다. 아이템이 로딩되고 정상적으로 설정됨
	pSendClientGameStartOK->bInvisible				= FALSE;		// 2006-11-27 by dhjin
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMESTART_OK));

	char szSystemLog[256];
	sprintf(szSystemLog, "  GameStartRoutine(%s) %s Map(%04d) Position(%4d, %4d, %4d) IP(%s)\r\n",
			GetProtocolTypeString(msgType), GetCharacterString(&m_character, string()),
			m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
			(int)m_character.PositionVector.y, (int)m_character.PositionVector.z,
			GetPeerIP());
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
	DBGOUT(szSystemLog);

	m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	// send MSG_FC_STORE_GET_ITEM to DB Manager
	MSG_FC_STORE_GET_ITEM *pGetItem = new MSG_FC_STORE_GET_ITEM;
	pGetItem->AccountUniqueNumber	= m_character.AccountUniqueNumber;
	pGetItem->PossessCharacter		= m_character.CharacterUniqueNumber;
	pGetItem->ItemStorage0			= ITEM_IN_CHARACTER;
	if (type == GST_GAMESTART || type == GST_CONN_GAMESTART) {		pGetItem->bSendToClient = TRUE; }
	pGetItem->bMainGameStartFlag	= TRUE;		// 2012-10-08 by khkim, GLog - Main필드서버에서의 게임시작
// 2005-07-21 by hblee, 다른 필드서버로의 워프는 없으므로 삭제함
//	else if (type == GST_WARP_CONN_GAMESTART) {						pGetItem->bSendToClient = FALSE; }
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetStoreItem, this, m_character.AccountUniqueNumber, (MSG_FC_STORE_GET_ITEM*)pGetItem);

// 2008-02-18 by cmkwon, 게임 시작 동기화 수정 - CFieldIOCPSocket::Process_FC_EVENT_NOTIFY_MSG_GET() 함수로 위치 이동, 클라이언트 게임시작 준비 후 처리 필요
// 	ms_pFieldIOCP->SendInRangeCharacterOtherInfo(this, m_pCurrentFieldMapChannel);
// 
// 	// 주위에 있는 아이템의 정보를 얻어온다.
// 	SendDropItemsAroundPosition(m_character.PositionVector);

	// send log message
	if (type == GST_GAMESTART || type == GST_CONN_GAMESTART)
	{
// 2007-06-19 by cmkwon, 게임 지속 시간 수정 - 중국 5시간 후 접속 처리, 아래의 GPInitGameStartTime()함수로 처리
//		this->m_atmeGameStartTime.SetCurrentDateTime();			// 2006-11-15 by cmkwon;	// 게임 시작 시간 지정
//		if(m_atimeLastGameEndDate.Year != m_atmeGameStartTime.Year
//			|| m_atimeLastGameEndDate.Month != m_atmeGameStartTime.Month
//			|| m_atimeLastGameEndDate.Day != m_atmeGameStartTime.Day)
//		{// 2006-11-16 by cmkwon, 마지막 게임 접속 시간이 오늘이 아니면 오늘하루 접속 시간을 초기화 한다.
//			m_nGameContinueTimeInSecondOfToday		= 0;		// 2006-11-16 by cmkwon
//		}
		this->GPInitGameStartTime();		// 2007-06-19 by cmkwon, 게임 지속 시간 수정 - 중국 5시간 후 접속 처리
		this->m_nGameStartTimeInSeconds		= ms_pFieldIOCP->GetCurrentServerTime();			// 2006-11-15 by cmkwon, CAtumLogSender::SendLogMessageGAMESTART()에 있던것을 이쪽을 옮김
		m_nInsertPCBangEventItemLastCounts	= this->GetPCBangTotalPlayTimeInSeconds()/TERM_30MINUTES_BY_SECOND;		// 2007-06-28 by cmkwon, 예당 7월 PC방 콩이벤트 지급 시간 수정,,// 2007-06-13 by cmkwon, 예당 7월 PC방 프로모션(콩이벤트 구현) - 콩아이템지금 시간 설정

		CAtumLogSender::SendLogMessageGAMESTART(this);

		// 2012-10-07 by hskim, 휴식 경험치
 		QPARAM_ADDEXP_REST_EXPERIENCE_COUNT *pQParam = new QPARAM_ADDEXP_REST_EXPERIENCE_COUNT;
		pQParam->AccountUID = m_character.AccountUniqueNumber;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetAddExpRestExperienceCount, this, NULL, pQParam);
		// 2012-10-07 by hskim, 휴식 경험치
	}

	// 2014-06-10 by bckim, 세력변경 아이템		- 디비값 로드 
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetNumberOfChangeInflCount, this, NULL, NULL);
	// End. 2014-06-10 by bckim, 세력변경 아이템


	// 스텔스 설정
	if (COMPARE_RACE(m_character.Race, RACE_GUEST))
	{
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//		SetBodyConditionBit(m_character.BodyCondition, BODYCON_STEALTH_MASK);
		m_bIsInvisibleCharacter		= TRUE;
	}

#ifdef _ATUM_LOAD_TEST
	if(0 != strnicmp(m_character.AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
	{
		// IM Server에 등록
		INIT_MSG(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP, T_FI_CONNECT_NOTIFY_FIELDSERVER_IP, msgNotiryFieldIP, SendBuf);
		msgNotiryFieldIP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		msgNotiryFieldIP->FieldServerID = ms_pFieldIOCP->m_FieldServerID;

		ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP));

		// IM Server에 게임 시작을 알림
		if (type == GST_GAMESTART || type == GST_CONN_GAMESTART)
		{
			INIT_MSG(MSG_FI_CONNECT_NOTIFY_GAMESTART, T_FI_CONNECT_NOTIFY_GAMESTART, msgNotifyGameStart, SendBuf);
			msgNotifyGameStart->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			msgNotifyGameStart->FieldGameStartType = type;
			msgNotifyGameStart->MapChannelIndex = m_character.MapChannelIndex;
			
			ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_GAMESTART));
		}

		// Pre Server에 게임 시작을 알림
		if (type == GST_GAMESTART || type == GST_GAMESTART)
		{
			INIT_MSG(MSG_FP_EVENT_GAME_STARTED, T_FP_EVENT_GAME_STARTED, msgGameStarted, SendBuf);
			STRNCPY_MEMSET(msgGameStarted->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
			STRNCPY_MEMSET(msgGameStarted->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
			msgGameStarted->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			msgGameStarted->MapChannelIndex = m_character.MapChannelIndex;
			ms_pFieldIOCP->m_pPreWinSocket->Write(SendBuf, MSG_SIZE(MSG_FP_EVENT_GAME_STARTED));
		}
	}
	else
	{
		m_bIsInvisibleCharacter		= FALSE;		// 2007-01-23 by cmkwon
	}
#else
	// IM Server에 등록
	INIT_MSG(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP, T_FI_CONNECT_NOTIFY_FIELDSERVER_IP, msgNotiryFieldIP, SendBuf);
	msgNotiryFieldIP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	msgNotiryFieldIP->FieldServerID = ms_pFieldIOCP->m_FieldServerID;

	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP));

	// IM Server에 게임 시작을 알림
	if (type == GST_GAMESTART || type == GST_CONN_GAMESTART)
	{
		INIT_MSG(MSG_FI_CONNECT_NOTIFY_GAMESTART, T_FI_CONNECT_NOTIFY_GAMESTART, msgNotifyGameStart, SendBuf);
		msgNotifyGameStart->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		msgNotifyGameStart->FieldGameStartType = type;
		msgNotifyGameStart->MapChannelIndex = m_character.MapChannelIndex;

		ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_GAMESTART));
	}

	// Pre Server에 게임 시작을 알림
	if (type == GST_GAMESTART || type == GST_GAMESTART)
	{
		INIT_MSG(MSG_FP_EVENT_GAME_STARTED, T_FP_EVENT_GAME_STARTED, msgGameStarted, SendBuf);
		STRNCPY_MEMSET(msgGameStarted->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
		STRNCPY_MEMSET(msgGameStarted->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		msgGameStarted->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		msgGameStarted->MapChannelIndex = m_character.MapChannelIndex;
		ms_pFieldIOCP->m_pPreWinSocket->Write(SendBuf, MSG_SIZE(MSG_FP_EVENT_GAME_STARTED));
	}
#endif // END - _ATUM_LOAD_TEST

	////////////////////////////////////////////////////////////////////////////
	// 2012-10-05 by jhseol, NPlay pc방 모듈 - pre 서버로 정보 updata 요청
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
	if( TRUE != g_pFieldGlobal->IsArenaServer() )
	{
		INIT_MSG_WITH_BUFFER(MSG_FP_PCBANG_USER_GAME_START, T_FP_PCBANG_USER_GAME_START, pSendMsgUserInfoUpdata, SendMsgUserInfoUpdataBuf);
		STRNCPY_MEMSET(pSendMsgUserInfoUpdata->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
		STRNCPY_MEMSET(pSendMsgUserInfoUpdata->ServerGroupName, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);
		ms_pFieldIOCP->m_pPreWinSocket->Write(SendMsgUserInfoUpdataBuf, MSG_SIZE(MSG_FP_PCBANG_USER_GAME_START));
	}
#endif
	// end 2012-10-05 by jhseol, NPlay pc방 모듈 - pre 서버로 정보 updata 요청


	// 게임 시작 시간 저장, LastStartedTime 저장
	if (type == GST_GAMESTART || type == GST_CONN_GAMESTART)
	{
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLastStartedTime, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber);
	}

	// 파티원의 정보를 업데이트함
//	if (m_pFieldParty != NULL && type == GST_WARP_CONN_GAMESTART)
//	{
//		m_pFieldParty->UpdateMemberInfoAllInMap(this, m_pCurrentFieldMapChannel);
//	}
//

	// 첫 exp 정보를 전송한다
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_EXP);

	// 첫 HP 정보 전송
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

	// 첫 회복용 Timer 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_DO_MINUTELY_WORK);

	// 각종 알림 메세지 전송
	if (COMPARE_RACE(m_character.Race, RACE_ACCOUNT_TYPE_MASK))
	{
		SendString128(STRING_128_USER_NOTICE, "************************************");
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0130, GetRaceString(m_character.Race&RACE_ACCOUNT_TYPE_MASK));
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//		if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
		if(this->IsInvisibleCharacter())
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0000);
		}
		if(m_bNoDamage)
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0001);
		}
		SendString128(STRING_128_USER_NOTICE, "************************************");
	}
	if(m_bStealthState)
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0002);
	}

// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 클라이언트에서 요청(T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO)하는 것으로 변경함
//	if (type == GST_GAMESTART || type == GST_CONN_GAMESTART)
//	{// 이벤트 진행 중인 정보 전송
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 2006-08-22 by cmkwon, 함수로 변경함
//		ms_pFieldIOCP->SendGameEventMessage(this, m_character.InfluenceType);
//	}

// 2009-03-31 by dhjin, 선전 포고 - 세력전 승리 시 지급 되는 이벤트 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-04-21 by cmkwon
//	SDB_INFLUENCE_WAR_INFO *pCurWarInfo = NULL;
//	if(ms_pFieldIOCP->m_InflWarManager.GetINFLUENCE_WAR_INFO_ByInflType(&pCurWarInfo, m_character.InfluenceType))
//	{
//		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
//		pSInflData->byInfluenceType		= pCurWarInfo->InfluenceType;
//		pSInflData->fHPRepairRate		= pCurWarInfo->HPRepairRate;
//		pSInflData->fDPRepairRate		= pCurWarInfo->DPRepairRate;
//		pSInflData->fSPRepairRate		= pCurWarInfo->SPRepairRate;
//		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
//	}
	CInflWarData *pInflWarData = ms_pFieldIOCP->m_InflWarManager.GetInflWarDataByInflType(m_character.InfluenceType);
	if(pInflWarData)
	{
		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
		pSInflData->byInfluenceType		= m_character.InfluenceType;
		pSInflData->fHPRepairRate		= pInflWarData->fInflHPRepairRate;
		pSInflData->fDPRepairRate		= pInflWarData->fInflDPRepairRate;
		pSInflData->fSPRepairRate		= pInflWarData->fInflSPRepairRate;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-20 by cmkwon, 세력전보스몬스터 소환 정보 전송
	if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
	{
		BOOL	CheckBoss	= FALSE;		// 2007-07-16 by dhjin, 모선 전 시 거점 정보는 전송하지 않는다.
		INIT_MSG(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA, T_FC_WAR_BOSS_MONSTER_SUMMON_DATA, pSBossSummon, SendBuf);
		if(ms_pFieldIOCP->m_InflWarManager.GetSummonInflBossMonsterData(pSBossSummon, INFLUENCE_TYPE_VCN))
		{
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetSummonInflBossMonsterData(pSBossSummon, INFLUENCE_TYPE_ANI))
		{
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetVCNSummonedInflBossMonsterData(pSBossSummon))
		{// 2007-02-06 by dhjin, 바이제니유 보스(전함) 생성되어  있을시 정보 체크하여 보내기
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
			CheckBoss = TRUE;
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetANISummonedInflBossMonsterData(pSBossSummon))
		{// 2007-02-06 by dhjin, 알링턴 보스(전함) 생성되어  있을시 정보 체크하여 보내기
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
			CheckBoss = TRUE;
		}
		if(FALSE == CheckBoss
			&& !ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.empty())
		{// 2007-07-16 by dhjin, 거점 정보 전송.
			
			INIT_MSG(MSG_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON, T_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON, pSBossSummon, SendBuf);

			mt_auto_lock mtA(&(ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo));	// 2007-10-08 by cmkwon, lock 필요
			mtvectorSSUMMON_STRATEGYPOINT_INFO::iterator	itr = ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.begin();
			while(itr != ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.end())
			{
				pSBossSummon->InfluenceType				= itr->InfluenceType;
				pSBossSummon->MapIndex					= itr->MapIndex;
				STRNCPY_MEMSET(pSBossSummon->MapName, itr->MapName, SIZE_MAX_MAP_NAME);
				pSBossSummon->SummonStrategyPointTime	= itr->SummonStrategyPointTime;
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON));
				itr++;
			}
		}

	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-14 by dhjin, 전진기지 전쟁 정보 전송
	INIT_MSG(MSG_FC_OUTPOST_WAR_INFO, T_FC_OUTPOST_WAR_INFO, pSOutPostWarInfo, SendBuf);
	pSOutPostWarInfo->OutPostWarInfoListCount = this->ms_pFieldIOCP->m_OutPostManager.CheckAllOutPostWaringAndSendClient((SOUTPOST_WAR_INFO*)(SendBuf+MSG_SIZE(MSG_FC_OUTPOST_WAR_INFO)));
	if(0 < pSOutPostWarInfo->OutPostWarInfoListCount)
	{
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_OUTPOST_WAR_INFO)+pSOutPostWarInfo->OutPostWarInfoListCount*sizeof(SOUTPOST_WAR_INFO));
	}

	// 디버그용, 지난 시간을 저장
	m_nOldTimeStampDBG = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-26 by dhjin, 모선전 정보 표시 기획안 - 전략포인트 생성 된 정보 설정
	if(ms_pFieldIOCP->m_InflWarManager.CheckSummonBoss())
	{
		ms_pFieldIOCP->m_InflWarManager.SendMSWarInfoForUser(this);		
	}
	ms_pFieldIOCP->m_InflWarManager.SendMSWarOptionTypeForInfluenceUser(this);

	// 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점 : 접속 시 진행중인 NGC거점 정보전송
#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG	// - NGC 거점 : 접속 시 진행중인 NGC거점 정보전송
	ms_pFieldIOCP->m_pMapTriggerManager->StrategyPointDisPlayBySocket(this);
#endif
	// end 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점

	//////////////////////////////////////////////////////////////////////////
	// 2008-04-23 by dhjin, EP3 편지 시스템 - 
	this->GetDBAllLetter();

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 아레나 서버에서는 MainServer로부터 정보를 받는다.!!!!
		this->GetDBInfinityImpute();
	}

	// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
	if( this->IsCityCurrentFieldMapChannel() )
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES, T_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES, pInflVictory, pInflVictorySendBuf);
		pInflVictory->PointBCU = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(INFLUENCE_TYPE_VCN);
		pInflVictory->PointANI = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(INFLUENCE_TYPE_ANI);
		SendAddData(pInflVictorySendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES));
	}

	this->ApplyBuffSkillByTurnAround();

#ifdef SC_UNBALANCED_FORCES_ADJUST_SHOW_INFLUNCE_INFO	// 2014-06-17 by bckim, 세력 불균형 ( 세력정보 및 우세세력 표시 )
	this->InfluenceShowInfo();		
#endif

#endif
	// end 2013-05-09 by hskim, 세력 포인트 개선	

//////////////////////////////////////////////////////////////////////////
// 2007-12-12 by dhjin, 맵정보 전송 부분 변경으로 상위로 올린다.
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 접근 가능 유저 체크
//	if(IS_CONFERENCEROOM_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
//	{
//		CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(CFieldMapProject::GetConferenceRoomMapIndex(m_character.InfluenceType));
//		if(NULL == pFMPro
//			|| FALSE == pFMPro->IsWarpableUser(m_character.CharacterUniqueNumber, m_character.Race))
//		{
//			this->WarpToCityMap();
//		}
//	}
//	else if(IS_OUTPOST_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
//		|| IS_MAP_INFLUENCE_OUTPOST(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
//	{	// 2007-09-28 by dhjin, 전진기지도시맵에서 시작시 소유 여단이 아니면 마을로 귀환
//
//		if(m_character.MapChannelIndex.MapIndex != ms_pFieldIOCP->m_OutPostManager.GetOutPostCityMapIndexByGuildUID(m_character.GuildUniqueNumber))
//		{
//			this->WarpToCityMap();
//		}
//	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckCurrentMapOnGameStart(void)
/// \brief		// 2007-12-26 by cmkwon, CurrentMap 체크 시스템 수정 - CFieldIOCPSocket::CheckCurrentMapOnGameStart() 추가
/// \author		cmkwon
/// \date		2007-12-26 ~ 2007-12-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckCurrentMapOnGameStart(void)
{
	CHARACTER *pCharacter = &m_character;

	CFieldMapChannel *pCityFMapChan = this->GetCityFieldMapChannelPtr(pCharacter->InfluenceType, pCharacter->GetStartCityMapIndex());	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#

	///////////////////////////////////////////////////////////////////////////////
	// 2007-02-26 by cmkwon, 현재 캐릭터 맵과 PositionVector의 유효성 체크
	CFieldMapChannel *pFMChann = GetFieldMapChannel(&(pCharacter->MapChannelIndex), TRUE);
	if (NULL == pFMChann			// 2007-02-26 by cmkwon, 서비스되지 않는 맵채널
		|| IS_MAP_INFLUENCE_EVENT_AREA(pFMChann->m_pFieldMapProject->m_nMapInfluenceType)	// 2007-02-26 by cmkwon, 이벤트맵
		|| IS_MAP_INFLUENCE_ARENA(pFMChann->m_pFieldMapProject->m_nMapInfluenceType)		// 2007-05-07 by dhjin, 아레나 맵이면 마을로
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#, 아래와 같이 수정
//		|| IS_OTHER_INFLUENCE_MAP(pCharacter->InfluenceType, pFMChann->m_pFieldMapProject->m_nMapInfluenceType) 	// 2007-08-29 by dhjin, 다른 세력 맵에서 시작 하면 마을로 		
		|| CAtumSJ::IsOtherInfluenceMap(pCharacter->InfluenceType, pCharacter->GetStartCityMapIndex(), pFMChann->GetMapInfluenceTypeW())	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
		|| ( IS_NORMAL_INFLUENCE_TYPE(pCharacter->InfluenceType) && IS_VCN_CITY_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex) )	// 2008-01-17 by cmkwon, S_F: 일반세력이 정규군 도시에 있을 경우 맵이동
		)
	{
		// 2007-06-13 by cmkwon, loadtest 계정은 제외한다.
		if(NULL == pFMChann
			|| 0 != strnicmp(pCharacter->AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, strlen(ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME)) )
		{
			// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#,
			//pFMChann = this->GetCityFieldMapChannelPtr(pCharacter->InfluenceType);
			pFMChann = pCityFMapChan;		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			if(NULL	== pFMChann)
			{
				return FALSE;
			}
			pCharacter->PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 접근 가능 유저 체크			
	if(IS_CONFERENCEROOM_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex))
	{
		CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(CFieldMapProject::GetConferenceRoomMapIndex(pCharacter->InfluenceType));
		if(NULL ==pFMPro
			|| FALSE == pFMPro->IsWarpableUser(pCharacter->CharacterUniqueNumber, pCharacter->Race))
		{
			// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#,
			//pFMChann = this->GetCityFieldMapChannelPtr(pCharacter->InfluenceType);
			pFMChann = pCityFMapChan;		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			if(NULL	== pFMChann)
			{				
				return FALSE;
			}
			pCharacter->PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-28 by dhjin, 전진기지도시맵에서 시작시 소유 여단이 아니면 마을로 귀환
	if(IS_OUTPOST_CITY_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex)
		|| IS_MAP_INFLUENCE_OUTPOST(pFMChann->GetMapInfluenceTypeW()))
	{
		if(pCharacter->MapChannelIndex.MapIndex != ms_pFieldIOCP->m_OutPostManager.GetOutPostCityMapIndexByGuildUID(pCharacter->GuildUniqueNumber))
		{
			// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#,
			//pFMChann = this->GetCityFieldMapChannelPtr(pCharacter->InfluenceType);
			pFMChann = pCityFMapChan;		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			if(NULL	== pFMChann)
			{
				SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);
				return FALSE;
			}
			pCharacter->PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		}
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	if( ERR_NO_ERROR != pFMChann->m_pFieldMapProject->IsEnableWarpByMapProject(this, TRUE) )
	{
		CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pFMChann->m_pFieldMapProject->m_nBeforeMapIndex);

		if( NULL != pFMPro )
		{
			pFMChann = (CFieldMapChannel*)(pFMPro->GetMapChannelByIndex(0));		// 기본 채널로 이동

			if(NULL	== pFMChann)
			{
				SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);

				return FALSE;
			}

			pCharacter->PositionVector	= pFMChann->GetDefaultPointW();
		}
		else
		{
			pFMChann = pCityFMapChan;		// 혹시나 BackMap 이 설정되어 있지 않다면 마을로 보낸다

			if(NULL	== pFMChann)
			{
				SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);

				return FALSE;
			}

			pCharacter->PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		}
	}
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	// 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차
	if( IS_STONES_RUIN_MAP_INDEX(pFMChann->m_pFieldMapProject->m_nMapIndex) )
	{
		if( COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN | INFLUENCE_TYPE_ANI) )
		{
			if( TRUE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(INFLUENCE_TYPE_ANI) )
			{
				// 일반 계정이 아닌 유저가 모선전 진행 중 스톤즈 루인에서 게임을 시작할 경우 마을로 보낸다
				
				pFMChann = pCityFMapChan;
				
				if(NULL	== pFMChann)
				{
					SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);
					
					return FALSE;
				}
				
				pCharacter->PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();				
			}
		}
	}
	// end 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차

	pCharacter->MapChannelIndex		= pFMChann->GetMapChannelIndex();

	if(FALSE == pFMChann->m_pFieldMapProject->CheckCharacterPosition(&pCharacter->PositionVector, TRUE))
	{// 2007-02-26 by cmkwon, PositionVector 유효성 체크
		pCharacter->PositionVector	= pFMChann->GetDefaultPointW();
	}

	CLEAR_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_LANDED_MASK);
	if(FALSE == COMPARE_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_DEAD_MASK))
	{// 유닛이 죽은 상태가 아니면

		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::CheckCurrentMapOnGameStart#,
		//if(pFMChann == this->GetCityFieldMapChannelPtr(pCharacter->InfluenceType)
		if(pFMChann == pCityFMapChan		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			|| IS_BAZAAR_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex)
			|| IS_OUTPOST_CITY_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex))	// 2007-09-10 by dhjin, 전진기지 도시 맵도 케릭터 모드로 시작
		{// 2007-02-26 by cmkwon, 도시맵과 바자맵은 항상 캐릭터모드로 시작된다.
			pCharacter->CharacterMode	= TRUE;
		}
		else
		{// 2007-02-26 by cmkwon, 다른맵은 캐릭터모드로 시작할수 없다
			pCharacter->CharacterMode	= FALSE;
		}

		if(pCharacter->CharacterMode)
		{
// 2010-04-14 by cmkwon, 서버 메모리 부족 문제 수정 - 
// 			// 착륙 가능 지역이면 착륙 상태로 set -> HP 회복은 아래 SP 회복과 같이 있다.
// 			TILEINFO *pTile = pFMChann->m_pFieldMapProject->GetTileInfo(&pCharacter->PositionVector);
// 			if(NULL == pTile
// 				|| (EVENT_TYPE_ENTER_BUILDING != pTile->m_EventInfo.m_bEventType && EVENT_TYPE_ENTER_BUILDING_BAZAAR != pTile->m_EventInfo.m_bEventType))	// 2006-08-07 by cmkwon, 개인 상점맵도 추가
// 			{			
// 				pCharacter->PositionVector	= pFMChann->m_pFieldMapProject->GetRandomXZCityWarpTargetPosition();
// 			}
			///////////////////////////////////////////////////////////////////////////////
			// 2010-04-14 by cmkwon, 서버 메모리 부족 문제 수정 - 
			EVENTINFO *pTileEvInfo = pFMChann->GetTileEventInfoW(&pCharacter->PositionVector);
			if(NULL == pTileEvInfo
				|| (EVENT_TYPE_ENTER_BUILDING != pTileEvInfo->m_bEventType && EVENT_TYPE_ENTER_BUILDING_BAZAAR != pTileEvInfo->m_bEventType))
			{
 				pCharacter->PositionVector	= pFMChann->m_pFieldMapProject->GetRandomXZCityWarpTargetPosition();
			}
			
			SET_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_CHARACTER_MODE_STOP);
		}
	}
	else
	{// 유닛이 죽은 상태

		// 2008-04-01 by cmkwon, 도시맵에서 죽은 상태의 기어 부활시켜서 캐릭터 상태로 처리 - 
		if(FALSE == IS_CITY_MAP_INDEX(pCharacter->MapChannelIndex.MapIndex))
		{
			pCharacter->CurrentHP			= 0.0f;
			pCharacter->CurrentDP			= 0.0f;

			pCharacter->CharacterMode		= FALSE;		// 2006-10-17 by cmkwon, 죽은 상태면 기어로 처리한다.

			SET_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_DEAD_MASK);
			CLEAR_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_BOOSTER_EX_STATE_CLEAR_MASK);	// 2005-07-29 by cmkwon, 착륙 상태는 없다
		}
		else
		{
			// 2008-04-01 by cmkwon, 도시맵에서 죽은 상태의 기어 부활시켜서 캐릭터 상태로 처리 - 
			this->CharacterDeadGameStartRoutine(FALSE, m_character.HP, m_character.DP);
			this->m_bDeadReasonByPK			= FALSE;
			pCharacter->CharacterMode		= TRUE;			// 캐릭터상태로 
			pCharacter->PositionVector		= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		}
	}

	return TRUE;
}


BOOL CFieldIOCPSocket::CharacterSaveCriticalData(BOOL i_bSynchExec /* = FALSE */)
{
	if(g_pFieldGlobal->IsArenaServer())
	{// 2008-01-31 by dhjin, 아레나 서버에서는 저장하지 않는다.
		return FALSE;
	}	
	
	if (!IS_VALID_UNIQUE_NUMBER(m_character.CharacterUniqueNumber)
		|| m_character.CharacterUniqueNumber == 0
		|| !IS_VALID_CLIENT_INDEX(m_character.ClientIndex))
	{
		DBGOUT2(DO2_DBGOUT|DO2_SYSLOG, "---> CFieldIOCPSocket::CharacterSaveCriticalData()_1 INVALID %s\r\n", GetCharacterString(&m_character, string()));
		return FALSE;
	}

#ifdef _DEBUG
	DBGOUT("---> CFieldIOCPSocket::CharacterSaveCriticalData()_2 %s\r\n", GetCharacterString(&m_character, string()));
#endif

	///////////////////////////////////////////////////////////////////////////
	// DB에 현재의 Bullet Count를 저장한다.
	SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemProwOut.ItemNum);	// 1형 무기
	SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemWingOut.ItemNum);	// 2형 무기

	///////////////////////////////////////////////////////////////////////////
	// 카운터블 아이템 카운트가 다른것만 저장한다
	m_ItemManager.StoreCountableItem();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-05-21 by cmkwon, 경험치 지연저장 시스템
	this->StoreExperienceDelayStore();

	///////////////////////////////////////////////////////////////////////////////
	// 사용 시간 제한 아이템 사용시간 계산하여 DB에 저장
	m_ItemManager.StoreTimeStampUsingTimeLimitedIteList();

	///////////////////////////////////////////////////////////////////////////////
	// 중요 데이타 모두 저장
	QPARAM_CHARACTER_SAVE_CRITICAL_DATA *pQCharacData = new QPARAM_CHARACTER_SAVE_CRITICAL_DATA;
	pQCharacData->CharacterUID		= m_character.CharacterUniqueNumber;
	pQCharacData->Level				= m_character.Level;
	pQCharacData->CharacterMode0	= m_character.CharacterMode;
	pQCharacData->Experience		= m_character.Experience;
	pQCharacData->DownExperience	= (FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK)) ? 0.0f : m_character.DownExperience;
	pQCharacData->DownSPIOnDeath0	= (FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK)) ? 0 : m_character.DownSPIOnDeath;	// 2006-04-10 by cmkwon
	pQCharacData->BodyCondition		= (m_character.BodyCondition&BODYCON_KEEPING_MASK);	// 지속형 body condition만을 저장
	pQCharacData->PetLevel			= m_character.PetLevel;
	pQCharacData->PetExperience		= m_character.PetExperience;
	pQCharacData->Position_X		= m_character.PositionVector.x;
	pQCharacData->Position_Y		= m_character.PositionVector.y;
	pQCharacData->Position_Z		= m_character.PositionVector.z;
	pQCharacData->MapIndex			= m_character.MapChannelIndex.MapIndex;
	pQCharacData->ChannelIndex		= m_character.MapChannelIndex.ChannelIndex;
	pQCharacData->HP				= m_character.HP;
	pQCharacData->DP				= m_character.DP;
	pQCharacData->SP				= m_character.SP;
	pQCharacData->EP				= m_character.EP;
	pQCharacData->CurrentHP			= m_character.CurrentHP;
	pQCharacData->CurrentDP			= m_character.CurrentDP;
	pQCharacData->CurrentSP			= m_character.CurrentSP;
	pQCharacData->CurrentEP			= m_character.CurrentEP;
	pQCharacData->TotalPlayTime		= GetTotalPlayTimeInSeconds();
	pQCharacData->LastGameEndDate.SetCurrentDateTime();													// 2006-11-16 by cmkwon
	pQCharacData->GameContinueTimeInSecondOfToday	= this->GetCurGameContinueTimeInSecondOfToday();	// 2006-11-16 by cmkwon
// 2007-05-29 by cmkwon, 필요없음
//	pQCharacData->WarPoint			= m_character.WarPoint;												// 2007-04-25 by dhjin
	pQCharacData->PCBangTotalPlayTime	= GetPCBangTotalPlayTimeInSeconds();
	pQCharacData->SecretInfoOption	= m_character.SecretInfoOption;				// 2008-06-23 by dhjin, EP3 유저정보옵션 -

	// 2007-06-13 by cmkwon, 예당 7월 PC방 프로모션(콩이벤트 구현) - 콩아이템지급 시간 체크
	if(this->m_bIsPCBangClient
		&& m_nInsertPCBangEventItemLastCounts < (int)(pQCharacData->PCBangTotalPlayTime/TERM_30MINUTES_BY_SECOND))		// 2007-06-28 by cmkwon, 예당 7월 PC방 콩이벤트 지급 시간 수정
	{
		pQCharacData->PCBangTotalPlayTime = max(0, pQCharacData->PCBangTotalPlayTime-120);	// 2분을 빼서 저장한다
	}

	this->m_atimeLastGameEndDate					= pQCharacData->LastGameEndDate;					// 2006-11-16 by cmkwon

	if (i_bSynchExec)
	{
		// Synchronous Execution
		ms_pFieldIOCP->m_pAtumDBManager->ExecuteQuery(QT_SaveCharacterCriticalData, this, pQCharacData);
	}
	else
	{
		// Asynchronous Execution
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SaveCharacterCriticalData, this, m_character.AccountUniqueNumber, pQCharacData);
	}

	return TRUE;
}

void CFieldIOCPSocket::CharacterGameEndRoutine(void)
{
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리, 아레나 플레이 유저인지 체크
	BOOL bArenaPlayUser = FALSE;

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 게임 종료 루틴
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 게임 종료 루틴
	m_ArmorCollection.CollectionFinish();
#endif
	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 게임 종료 루틴
		
	this->m_mtCritSecForGameEndRoutine.Enter();
	{
		if(CS_PLAYING > this->GetClientState()				// 2008-02-11 by dhjin, 아레나 통합 -
			|| FALSE == m_bFlagDBStore
			|| m_character.CharacterUniqueNumber == 0)
		{	// 종료 루틴을 처리하지 않음.
#ifdef _DEBUG
			DBGOUT2(DO2_DBGOUT|DO2_SYSLOG, STRMSG_S_F2NOTIFY_0131, GetCharacterString(&m_character, string()), GetClientState(), m_bFlagDBStore);
#endif
			this->m_mtCritSecForGameEndRoutine.Leave();
			return;
		}

		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리, 아레나 플레이 유저인지 체크
		if(CS_ARENASERVER_PLAYING == this->GetClientState()) {
			bArenaPlayUser = TRUE;
		}

		this->SetClientState(CS_LOGINED);	// 캐릭터의 상태 변수를 다시 설정함.
		m_bFlagDBStore = FALSE;				// 정상적인 GameEnd, 종료 위치를 DB에 저장 하였기 때문에 Close시에 저장 할 필요 없음
	}
	this->m_mtCritSecForGameEndRoutine.Leave();

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  GameEndRoutine %s Map(%04d) Position(%4d, %4d, %4d)\r\n",
		GetCharacterString(&m_character, string()), m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
		(int)m_character.PositionVector.y, (int)m_character.PositionVector.z);

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-06 by cmkwon, 인피2차 추가 수정 - 
	this->InfinityOnCharacterGameEndRoutine();
	this->ArenaOnCharacterGameEndRoutine();

	///////////////////////////////////////////////////////////////////////////////
	// 2008-04-11 by cmkwon, 게임 종료시에 모든 스킬 초기화 - 76(Yedang_Kor) 버그 수정
	this->ResetAllSkill();

	BYTE						SendBuf[SIZE_MAX_PACKET];
	MSG_FN_CLIENT_GAMEEND_OK	*pSendClientGameEndOK = NULL;	
	// MSG 미리 만들어 두기
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GAMEEND_OK, T_FC_CHARACTER_GAMEEND_OK, pMsgGameEndOK, pMsgGameEndOKBuf);
	pMsgGameEndOK->ClientIndex = m_character.ClientIndex;

	// PK중이었다면, PK Reset 처리
	if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
		OnP2PPKEnd(pPeerPKSocket, this);
	}

	// 파티전 결과 처리
	if (this->IsPartyBattleState())
	{
		OnPartyBattleMemberDead(TRUE);
	}


	vectCFieldIOCPSocket vectCFISockList;	// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리

	// 파티원이면 파티원 리스트에서 삭제
	CFieldParty *ptmFParty = m_pFieldParty;
	if ( NULL != ptmFParty)
	{		
		mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);
		mt_auto_lock pmlock(&ptmFParty->m_ListPartyMember);		// lock m_ListPartyMember
			
		// 파티원들에게 GAMEEND 전송
		ptmFParty->SendMsgToMembersMap(pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK), m_pCurrentFieldMapChannel, m_character.CharacterUniqueNumber);
			
		FieldPartyMember tmpMember;
		if (ptmFParty->DeleteByCharacterUniqueNumber(m_character.CharacterUniqueNumber, tmpMember))
		{
			// 성공적으로 지워진 경우
// 2007-09-14 by cmkwon, 필요 없어서 주석 처리함
//			assert(this == tmpMember.PM_CharacterSocket);
		}
		else
		{
			// 이러면 안 되는데...
			g_pFieldGlobal->WriteSystemLogEX(TRUE, STRMSG_S_F2NOTIFY_0132, GetCharacterString(&m_character, string()));
		}

#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN				// 2013-02-28 by bckim, 복귀유져 버프추가
		if( NULL != m_pFieldParty)					//	2013-07-07 by bckim, 서버 데드락 보완 
		{
			m_pFieldParty->SetReturnUserBuffSkill(this); // DeleteByCharacterUniqueNumber후에 지나고 정리 
		}
#endif

		ptmFParty->GetAllMembers(&vectCFISockList);		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
		
		// 파티원이 없어지면 삭제
		if (ptmFParty->empty())
		{
			ms_pFieldIOCP->m_MapParties.deleteLock(ptmFParty->m_PartyID);
			pmlock.auto_unlock_cancel();
			ms_pFieldIOCP->DeleteFieldParty(ptmFParty);			
		}
	}
	m_pFieldParty = NULL;

	CFieldIOCPSocket::ArrangeAllPartyMember(&vectCFISockList);		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
	this->CleanPartyMemberList();									// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리

	// 각종 자료 구조에서 삭제
	ms_pFieldIOCP->m_mapCharacterUniqueNumber.deleteLock(m_character.CharacterUniqueNumber);
	char tmCharacterName[SIZE_MAX_CHARACTER_NAME];	
	ms_pFieldIOCP->m_mapCharacterName.deleteLock(GGetLowerCase(tmCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME));

	// 2010-06-15 by shcho&hslee 펫시스템 - 게임 종료시 메모리 해제
	
	// this->m_ItemManager.DeleteItemPetDataGameEnd();
	// END 2010-06-15 by shcho&hslee 펫시스템 - 게임 종료시 메모리 해제
	
	///////////////////////////////////////////////////////////////////////////
	// 거래 reset하기
	if (m_peerTraderCharacterUniqueNumber != INVALID_UNIQUE_NUMBER)
	{
		CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
		if (NULL != pPeerTraderSocket)
		{
			INIT_MSG(MSG_FC_TRADE_CANCEL_TRADE_OK, T_FC_TRADE_CANCEL_TRADE_OK, msgCancelTradeOK, SendBuf);
			msgCancelTradeOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			pPeerTraderSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_TRADE_OK));

			pPeerTraderSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
			pPeerTraderSocket->m_bOKTradeChecked = FALSE;
			pPeerTraderSocket->m_mapTradeItem.clearLock();
		}
		m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
		m_bOKTradeChecked = FALSE;
		m_mapTradeItem.clearLock();
	}

	// 뿌려놓은 마인 지우기
	ClearAllCharacterMines();

	if (m_pCurrentFieldMapChannel != NULL)
	{
		///////////////////////////////////////////////////////////////////////////
		// NPC Server에 GameEndOK 메세지를 전송한다.
		INIT_MSG(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, SendBuf);
		pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));
	}

	if (!m_bFieldServerChangeFlag)
	{
		///////////////////////////////////////////////////////////////////////////
		// IM Server에 GameEndOK 메세지를 전송한다.
		*(MessageType_t*)SendBuf = T_FI_CONNECT_NOTIFY_GAMEEND;
		MSG_FI_CONNECT_NOTIFY_GAMEEND	*pMsgChatGameEnd = NULL;
		pMsgChatGameEnd = (MSG_FI_CONNECT_NOTIFY_GAMEEND*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
		pMsgChatGameEnd->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		ms_pFieldIOCP->m_pIMWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_GAMEEND));
	}

	// 2008-02-11 by dhjin, 아레나 통합 - 자기 자신에게 무조건 보내게 수정
	
	///////////////////////////////////////////////////////////////////////////
	// 자신과 주위의 캐릭터에게 GameEndOK 메세지를 전송한다.
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(this->GetClientArrayIndex(), pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK)
		, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
	this->SendAddData(pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK));

	///////////////////////////////////////////////////////////////////////////
	// 자신과 주위의 캐릭터에게 GameEndOK 메세지를 전송한다.
//	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(this->GetClientArrayIndex(), pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK)
//		, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

	///////////////////////////////////////////////////////////////////////////
	// 자신의 정보를 맵 Block에서 삭제 한다.
	if (m_pCurrentFieldMapChannel != NULL)
	{
		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
		{
			char szTemp[256];
			sprintf(szTemp, "[Error] DeleteBlockPosition_3 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f) \r\n"
				, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
				, m_character.PositionVector.x, m_character.PositionVector.z);
			DBGOUT(szTemp);
			g_pFieldGlobal->WriteSystemLog(szTemp);
		}
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
	}

// 2005-03-22 by cmkwon, 테스트
//	if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK) == TRUE
//		|| m_character.CurrentHP <= 0.0f)
//	{
//		// 죽었다면 마을로 보냄
//		m_character.MapChannelIndex.MapIndex		= this->GetDefaultCityMapProject()->m_nMapIndex;
//		m_character.PositionVector					= this->GetDefaultCityMapProject()->GetDefaultPoint();
//		m_character.MapChannelIndex.ChannelIndex	= 0;	// check: MapChannel 도입중, 20040322, kelovon
//
//		this->CharacterDeadGameStartRoutine(FALSE);
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다
	this->DeleteMeFromMonsterAttackedList();

	///////////////////////////////////////////////////////////////////////////
	// character cache update
	this->UpdateCharacterCacheLock(m_character.CharacterUniqueNumber, &m_character);

	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리, 밑과 같이 수정
//	// DB에 현재 캐릭터 데이타를 저장
//	CharacterSaveCriticalData();
	if(FALSE == bArenaPlayUser) {
		CharacterSaveCriticalData();
	}

	// 종료시에 로그를 전송한다.
	CAtumLogSender::SendLogMessageGAMEEND(this);

	// 2012-10-07 by hskim, 휴식 경험치
 	QPARAM_ADDEXP_REST_EXPERIENCE_COUNT *pQParam = new QPARAM_ADDEXP_REST_EXPERIENCE_COUNT;
	pQParam->AccountUID = m_character.AccountUniqueNumber;
	pQParam->RestExperienceCount = m_nRestExperienceCount;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SetAddExpRestExperienceCount, this, NULL, pQParam);
	// 2012-10-07 by hskim, 휴식 경험치

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-14 by cmkwon, 게임 지속 시간 제한 기본 시스템으로 수정 - PlayTime 버그 수정, 캐릭터 변경시 처리를 위해
	// 2007-11-07 by cmkwon, 게임 지속 시간 버그 수정 - 지속지간이 두번 더해졌던 버그 수정, 위에 있던것을 여기로 이동
	this->m_nGameContinueTimeInSecondOfToday = this->GetCurGameContinueTimeInSecondOfToday();
	// 배트남 게임 플레이 시간 주는 버그 수정
	this->m_nGameContinueTimeInSecondOfToday4Viet = this->m_nGameContinueTimeInSecondOfToday;

	// member 변수 초기화
	ResetAllVariables(RVT_GAME_END);
}

// 캐릭터가 죽고 GameEndRoutine() 혹은 DEAD_GAMESTART 하기 이전(사이)에 처리될 사항들
void CFieldIOCPSocket::CharacterDeadRoutine(BYTE damageType
											, CFieldMonster *i_pAttackMonster/*=NULL*/
											, CFieldIOCPSocket *i_pAttackUser/*=NULL*/)
{	
	m_TimerManager.m_TEIDGradualHPUP			= NULL;		// Timer 중지하기

	m_TimerManager.m_nRemainedTimeOfGradualHPUP = 0;
	m_TimerManager.m_nRemainedTimeOfGradualDPUP = 0;
	m_TimerManager.m_nRemainedTimeOfGradualSPUP = 0;
	m_TimerManager.m_nRemainedTimeOfGradualEPUP = 0;
	// 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점 : 기여도 초기화
#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG	// - NGC 거점 : 기여도 초기화
	if (NULL != this->GetCurrentFieldMapChannel() &&
		NULL != i_pAttackMonster &&
		NULL != i_pAttackMonster->MonsterInfoPtr)
	{
		ms_pFieldIOCP->m_pMapTriggerManager->DeleteContribute(this->GetCurrentFieldMapChannel()->GetMapChannelIndex(), m_character.CharacterUniqueNumber, i_pAttackMonster->MonsterInfoPtr->MonsterUnitKind);
	}
#endif
	// end 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점 : 기여도 초기화
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	this->m_SkillManager.ResetDebuffSkill();
	this->m_SkillManager.ResetDotSkill();
	if(g_pFieldGlobal->IsArenaServer()
		&& INFINITY_STATE_PLAYING <= this->m_InfinityPlayingInfo.InfinityState) {
		// 인피 로그용
		m_InfinityPlayingInfo.DeathCount++;
 		if(0 != m_InfinityPlayingInfo.TimePenaltyValue || 0 != m_InfinityPlayingInfo.HPPenaltyValue ) {		// 2011-06-14 by hskim, 인피니티 3차 - 패널티 기능 추가 (HP 및 시간 동시 지원을 위해)
 			// 2010-03-31 by dhjin, 인피니티(기지방어) - 밑과 같이 수정 // 2009-09-09 ~ 2010-01-13 by dhjin, 인피니티 - 죽은 유저 이름 정보 전송 추가, // 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 사망시 패널티 추가
// 			this->ms_pFieldIOCP->m_InfinityManager.CalcLimitTimeByUserDeathW(this->m_character.CharacterName, m_InfinityPlayingInfo.ModeTypeNum, m_InfinityPlayingInfo.InfinityCreateUID);
			this->ms_pFieldIOCP->m_InfinityManager.ProcessingInfinityPenalty(this->m_character.CharacterName, m_InfinityPlayingInfo.ModeTypeNum, m_InfinityPlayingInfo.InfinityCreateUID);
 		}
	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사망시 체프 존재하면 삭제한다.
	if(FALSE != m_mtvectFieldDummy.empty()) {
		mt_auto_lock mtA(&m_mtvectFieldDummy);
		m_bDummyCheck			= FALSE;
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_DELETE_DUMMY_OK, T_FC_BATTLE_DELETE_DUMMY_OK, pDummySMsg, DummySendBuf);
		pDummySMsg->AttackIndex		= GetCharacter()->ClientIndex;
		mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
		for(; itr != m_mtvectFieldDummy.end(); itr++)
		{
			FIELD_DUMMY *pFDummy	= *itr;
			pDummySMsg->ItemFieldIndex	= pFDummy->ItemFieldIndex;
			
			// 2006-12-06 by cmkwon, 주위의 모든 캐릭터에게 전송
			this->SendInRangeMessageAroundMe(DummySendBuf, MSG_SIZE(MSG_FC_BATTLE_DELETE_DUMMY_OK), TRUE);
		}
		this->DeleteAllFieldDummy();			// 2006-12-06 by cmkwon, 모든 체프를 제거한다.
		mtA.auto_unlock_cancel();
	}

	m_character.CurrentHP						= 0.0f;		// HP 초기화
	m_character.CurrentDP						= 0.0f;		// DP 초기화
// 2006-04-10 by cmkwon, ProcessSPIPenaltyOnDead() 함수에서 초기화 한다.
// 	m_character.DownExperience					= 0.0f;		// 유닛이 죽을때 다운된 경험치 초기화
// 	m_character.DownSPIOnDeath					= 0;		// 2006-04-10 by cmkwon, 캐릭터가 죽을때 떨어지는 SPI

	SetBodyConditionBit(m_character.BodyCondition, BODYCON_DEAD_MASK);
	QPARAM_CHARACTER_CHANGE_BODYCONDITION *pQBodyCondition = new QPARAM_CHARACTER_CHANGE_BODYCONDITION;
	pQBodyCondition->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pQBodyCondition->BodyCondition			= m_character.BodyCondition;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeBodyCondition, this, m_character.AccountUniqueNumber, pQBodyCondition);
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

	// 자신과 주위의 캐릭터들에게 자신이 폭파되었다는 정보를 보냄
	ms_pFieldIOCP->SendInRangeChangeBodyCondition(m_character.ClientIndex, m_pCurrentFieldMapChannel, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

	// NPC에게도 보냄
	m_pCurrentFieldMapChannel->SendBodyCondition2NPCServer(m_character.ClientIndex, m_character.BodyCondition);

	// 경험치 다운 처리, PK(파티전 포함)에 의한 전사는 처리하지 않음
	if (GCheckLimitLevel(CHECK_TYPE_PENALTY_ON_DEAD, m_character.Level)
		&& damageType != DAMAGE_BY_PK)
	{// 2006-02-28 by cmkwon, 세력전 몬스터에 의해 죽은 경우 제외

		if(DAMAGE_BY_MONSTER != damageType
			|| (DAMAGE_BY_MONSTER == damageType && i_pAttackMonster && FALSE == IS_INFLWAR_MONSTER(i_pAttackMonster->MonsterInfoPtr->Belligerence)))
		{
			ProcessSPIPenaltyOnDead();
		}
	}
// 2006-02-28 by cmkwon, 위와 같이 수정함
// 	if (GCheckLimitLevel(CHECK_TYPE_PENALTY_ON_DEAD, m_character.Level)
// 		&& damageType != DAMAGE_BY_PK)
// 	{
// 
// 		if(NULL == m_pCurrentFieldMapChannel->m_pRefCityWar1
// 			|| m_pCurrentFieldMapChannel->m_pRefCityWar1->MapIndex != m_pCurrentFieldMapChannel->m_MapChannelIndex.MapIndex
// 			|| CITYWAR_STATE_STARTED != m_pCurrentFieldMapChannel->m_pRefCityWar1->GetCityWarState())
// 		{// 도시점령전 진행중일때 점령전 맵에서는 경험치 다운이 없다
// 
// 			ProcessSPIPenaltyOnDead();
// 
// // 2005-06-29 by cmkwon, SPI 다운으로 처리
// //			///////////////////////////////////////////////////////////////////////////////
// //			// 레벨별 경험치 다운 처리
// //			Experience_t expDecrement	= CAtumSJ::GetLevelExperience(m_character.Level)->ExperienceLossOnDeath;
// //			expDecrement				= max(0, expDecrement - expDecrement*GetPlusRateExpRepair());
// //
// //			Experience_t expOfLevel		= CAtumSJ::GetInitialExperienceOfLevel(m_character.Level);
// //			if (m_character.Experience - expDecrement <= expOfLevel)
// //			{
// //				CAtumLogSender::SendLogMessageEXP(this, expOfLevel - m_character.Experience, expOfLevel);	// Send Log
// //				this->m_character.DownExperience	= m_character.Experience - expOfLevel;
// //				m_character.Experience				= expOfLevel;
// //			}
// //			else
// //			{
// //				m_character.Experience				-= expDecrement;
// //				CAtumLogSender::SendLogMessageEXP(this, -expDecrement, m_character.Experience);				// Send Log
// //				this->m_character.DownExperience	= expDecrement;
// //			}
// //
// //			QPARAM_CHARACTER_CHANGE_EXP *pQChangeEXP	= new QPARAM_CHARACTER_CHANGE_EXP;
// //			pQChangeEXP->CharacterUniqueNumber			= m_character.CharacterUniqueNumber;
// //			pQChangeEXP->Experience						= m_character.Experience;
// //			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeExp, this, m_character.AccountUniqueNumber, pQChangeEXP);
// //			SendCharacterInfo(T_FC_CHARACTER_CHANGE_EXP);
// 		}
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-27 by cmkwon, 세력전 명성 처리
	if( i_pAttackUser
		&& i_pAttackUser->IsValidCharacter(FALSE)
		&& this->GetCharacter()->InfluenceType != i_pAttackUser->GetCharacter()->InfluenceType
		&& COMPARE_INFLUENCE(this->GetCharacter()->InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI)
		&& COMPARE_INFLUENCE(i_pAttackUser->GetCharacter()->InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI) )
	{
		//////////////////////////////////////////////////////////////////////////
		// 2008-03-11 by dhjin, 아레나 통합 - 아레나 서버에서는 명성치, 세력전, 킬마크 관련 처리를 하지 않는다.
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			if(ms_pFieldIOCP->GetP2PPKFamePoint(i_pAttackUser->GetCharacter()->CharacterName, GetCharacter()->CharacterName))
			{
				i_pAttackUser->InfluenceWarBonus2Killer(this);

// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
#else
				///////////////////////////////////////////////////////////////////////////////
				// 2006-04-14 by cmkwon, 세력전 기여도 증가
				ms_pFieldIOCP->m_InflWarManager.AddContributionPoint(i_pAttackUser->GetCharacter()->InfluenceType, 1);
#endif
			}
		}

		//////////////////////////////////////////////////////////////////////////
		// 2008-02-21 by dhjin, 아레나 통합 - 아레나 서버에서 유저 이름 '\xxx' 띠고 보여주기, 다음과 같이 수정
		if(g_pFieldGlobal->IsArenaServer())
		{
			CHAR SendArenaCharacterName[SIZE_MAX_CHARACTER_NAME];
			MEMSET_ZERO(SendArenaCharacterName, SIZE_MAX_CHARACTER_NAME);
			CHAR ArenaCharacterName[SIZE_MAX_CHARACTER_NAME];
			STRNCPY_MEMSET(ArenaCharacterName, i_pAttackUser->GetCharacter()->CharacterName, SIZE_MAX_CHARACTER_NAME);
			ms_pFieldIOCP->ConvertArenaRenderUserName(ArenaCharacterName, SendArenaCharacterName);
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_061107_0000, SendArenaCharacterName);
			//////////////////////////////////////////////////////////////////////////
			// 2008-04-28 by dhjin, 아레나 통합 - 상대방 격추 시 스트링 추가, 아레나 맵에서만
			MEMSET_ZERO(SendArenaCharacterName, SIZE_MAX_CHARACTER_NAME);
			STRNCPY_MEMSET(ArenaCharacterName, this->GetCharacter()->CharacterName, SIZE_MAX_CHARACTER_NAME);
			ms_pFieldIOCP->ConvertArenaRenderUserName(ArenaCharacterName, SendArenaCharacterName);
			i_pAttackUser->SendString128(STRING_128_USER_NOTICE, STRMSG_080428_0001, SendArenaCharacterName);		
		}	
		else
		{
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_061107_0000, i_pAttackUser->GetCharacter()->CharacterName);
		}
//		// 2006-11-07 by cmkwon, 추가됨
//		this->SendString128(STRING_128_USER_NOTICE, STRMSG_061107_0000, i_pAttackUser->GetCharacter()->CharacterName);

		// 2006-03-06 by cmkwon, 세력전시에 상대 세력에 의해 내가 죽은 로그
		CAtumLogSender::SendLogMessagePvELOSS(this, i_pAttackUser->GetCharacter()->CharacterUniqueNumber);

		// 2006-03-06 by cmkwon, 세력전시 상대세력이 나를 죽인 로그
		CAtumLogSender::SendLogMessagePvEWIN(i_pAttackUser, this->GetCharacter()->CharacterUniqueNumber);
	}

	// 일대일 대결 결과 처리
	if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
		OnP2PPKEnd(pPeerPKSocket, this);
		if(DAMAGE_BY_PK == damageType)
		{// 캐릭에 의해서 죽었을 때만 워프게이트에서 부활
			m_bDeadReasonByPK				= TRUE;
		}
	}

	// 파티전 결과 처리
	if (this->IsPartyBattleState())
	{
		OnPartyBattleMemberDead();
	}

	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가 - 밑과 같이 수정
//	// DEAD Log 전송
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
//	CAtumLogSender::SendLogMessageDEAD(this, damageType);	// 2012-08-30 by jhseol, 풀로그 남기기 - 변경전의 함수 임으로 주석 해제 안함.
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
	if(NULL != i_pAttackUser) {
		CAtumLogSender::SendLogMessageDEAD(this, damageType, i_pAttackUser->GetCurrentAttackItemNum());
	}
	else if(NULL != i_pAttackMonster) {
		CAtumLogSender::SendLogMessageDEAD(this, damageType, i_pAttackMonster->GetCurrentAttackItemNum());
	}
	else {
		CAtumLogSender::SendLogMessageDEAD(this, damageType, 0);
	}
	
	///////////////////////////////////////////////////////////////////////////
	// 거래 reset하기
	if (IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
		if (pPeerTraderSocket
			&& pPeerTraderSocket->IsValidCharacter(FALSE))
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_TRADE_CANCEL_TRADE_OK, T_FC_TRADE_CANCEL_TRADE_OK, msgCancelTradeOK, msgCancelTradeOKBuf);
			msgCancelTradeOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			pPeerTraderSocket->SendAddData(msgCancelTradeOKBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_TRADE_OK));

			pPeerTraderSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
			pPeerTraderSocket->m_bOKTradeChecked = FALSE;
			pPeerTraderSocket->m_mapTradeItem.clearLock();
		}
		m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
		m_bOKTradeChecked = FALSE;
		m_mapTradeItem.clearLock();
	}

	// 뿌려놓은 마인 지우기
	ClearAllCharacterMines();

	// 쉴드 끄기
	if (m_ItemWingOut.Kind == ITEMKIND_SHIELD && COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_SHIELD_MASK))
	{
		StopItemKindShield(((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->ItemInfo);
	}

	// 디코이 끄기
	if (m_ItemWingOut.Kind == ITEMKIND_DECOY && COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DECOY_MASK))
	{
		StopItemKindDecoy(((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->ItemInfo);
	}

	// 차징 스킬 제거
	m_SkillManager.ClearChargingSkill();

	// 2007-07-11 by cmkwon, BigBoom이 PrepareUse 상태 여부 - 캐릭터가 죽을때 FALSE로 설정, 해제함
	m_SkillManager.SetPrepareUseBigBoom(FALSE);

	//
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DEAD_NOTIFY, T_FC_CHARACTER_DEAD_NOTIFY, pFCDead, SendBuf);
	pFCDead->ClientIndex		= m_character.ClientIndex;
	pFCDead->byDamageKind		= damageType;
	pFCDead->bDeadByP2PPK		= this->m_bDeadReasonByPK;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEAD_NOTIFY));

	// IM Server에 DEAD 메세지를 전송한다.
	INIT_MSG(MSG_FI_CONNECT_NOTIFY_DEAD, T_FI_CONNECT_NOTIFY_DEAD, pMsgDead, SendBuf);
	pMsgDead->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pMsgDead->AttackerGuildUID		= this->m_uidAttackerGuildUID;
	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_DEAD));

	// 2005-08-30 by cmkwon, 몬스터 사냥 퀘스트 몬스터 카운트 처리
	if(i_pAttackMonster)
	{
		this->CheckSuccessAllQuestByAttackMonsterNum(i_pAttackMonster->MonsterInfoPtr->MonsterUnitKind);
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-04-24 by dhjin, ARENA_STATE_WARING 상태이면 아레나 맵이므로 아레나에서 처리할 것 처리
	if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())
		&& ARENA_STATE_FIGHTING_WARING == this->m_ArenaInfo.State)
	{
		if(i_pAttackUser
			&& i_pAttackUser->IsValidCharacter(FALSE))
		{		
			i_pAttackUser->m_ArenaInfo.ShootingDown++;
			this->m_ArenaInfo.SufferingAttack++;
		}
		else
		{// 2007-06-01 by dhjin, 격추 당하지 않고 죽었을 때 LostPoint증가
			this->m_ArenaInfo.LostPoint++;
		}
		ms_pFieldIOCP->m_ArenaManager.SendDeathMatchRoomInfo(this->m_ArenaInfo.TeamNum, this->m_ArenaInfo.DeathMatchRoomNum, this->m_character.InfluenceType);
	}

	m_mtvectActionInfoAggroList.clearLock();		// 2006-07-21 by cmkwon, Aggro 리스트 초기화

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - CFieldIOCPSocket::CharacterDeadRoutine(), 캐릭터 죽을때 초기화 처리
	m_ItemManager.SetUsingFieldStore(FALSE);
	m_ItemManager.SetUsingStore(FALSE);				// 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
}

BOOL CFieldIOCPSocket::CharacterDeadGameStartRoutine(BOOL i_bNotify
													 , int i_nRecoverHP/*=0*/
													 , int i_nRecoverDP/*=0*/
													 , int i_nRecoverSP/*=0*/
													 , int i_nRecoverEP/*=0*/)
{
	// 피 채워줌
	if(i_nRecoverHP){		m_character.CurrentHP	= i_nRecoverHP;}
	if(i_nRecoverDP){		m_character.CurrentDP	= i_nRecoverDP;}
	if(i_nRecoverSP){		m_character.CurrentSP	= i_nRecoverSP;}
	if(i_nRecoverEP){		m_character.CurrentEP	= i_nRecoverEP;}	// 2007-05-11 by dhjin, 연료도 채워 줄 수 있도록 추가
	else{	m_character.CurrentEP	= max(1, m_character.CurrentEP);}	// 2005-12-14 by cmkwon, 연료를 1 채워준다
// 2005-11-18 by cmkwon, SP, 연료, 총알는 보급상점을 이용해야한다.
//	m_character.CurrentSP	= m_character.SP;
//	///////////////////////////////////////////////////////////////////////////////
//	// 2005-08-02 by cmkwon
//	// 1형, 2형 총알을 가득 채워 준다.	
//	ITEM_GENERAL *pPriItem = (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
//	ITEM_GENERAL *pSecItem = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
//	if (m_ItemProwOut.ItemNum != 0){			RechargeBullet(pPriItem, FALSE);}
//	if (m_ItemWingOut.ItemNum != 0){			RechargeBullet(pSecItem, FALSE);}


// 2005-06-29 by cmkwon, 모두 채줘 주는 것으로 변경
//	if(i_nRecoverHP <= 0)
//	{
//		if (m_character.Level < 10)
//		{
//			m_character.CurrentHP = m_character.HP;
//		}
//		else
//		{
//			m_character.CurrentHP = 0.3f * (float)m_character.HP;
//		}
//	}
//	else
//	{
//		m_character.CurrentHP = min(i_nRecoverHP, m_character.HP);
//		m_character.CurrentDP = min(i_nRecoverDP, m_character.DP);
//		m_character.CurrentSP = min(i_nRecoverSP, m_character.SP);
//	}

	// Body Condition 바꿔줌
	m_character.BodyCondition = BODYCON_FLY_MASK;
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_BOOSTER_EX_STATE_CLEAR_MASK|BODYCON_LANDED_MASK);
	if(FALSE == i_bNotify)
	{// 캐릭터가 죽은 상태에서 게임을 종료하는 상황
		return TRUE;
	}

	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pBodyCon, SendBuf);
	pBodyCon->ClientIndex		= m_character.ClientIndex;
	pBodyCon->BodyCondition		= m_character.BodyCondition;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION));

	INIT_MSG(MSG_FI_CONNECT_NOTIFY_DEAD_GAMESTART, T_FI_CONNECT_NOTIFY_DEAD_GAMESTART, pSIMServer, SendBuf);
	pSIMServer->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_DEAD_GAMESTART));

	// NPC 에게도 보냄
	INIT_MSG(MSG_FN_CHARACTER_CHANGE_BODYCONDITION, T_FN_CHARACTER_CHANGE_BODYCONDITION, pSBodyCon, SendBuf);
	pSBodyCon->ChannelIndex		= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSBodyCon->ClientIndex		= m_character.ClientIndex;
	pSBodyCon->BodyCondition	= m_character.BodyCondition;
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_BODYCONDITION));

	///////////////////////////////////////////////////////////////////////////
	// NPC Server에 GameEndOK 메세지를 전송한다.
	INIT_MSG(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, SendBuf);
	pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));
	return TRUE;
}

LONGLONG CFieldIOCPSocket::GetTotalPlayTimeInSeconds()
{
	return m_character.TotalPlayTime + GetCurrentPlayTimeInSeconds();
}

LONGLONG CFieldIOCPSocket::GetCurrentPlayTimeInSeconds()
{
	if(0 == m_nGameStartTimeInSeconds){			return 0;}			// 2006-05-07 by cmkwon

	return ms_pFieldIOCP->GetCurrentServerTime() - m_nGameStartTimeInSeconds;
}

//////////////////////////////////////////////////////////////////////////
// 2007-06-07 by dhjin, PC방 총 플레이 시간 만들기.
LONGLONG CFieldIOCPSocket::GetPCBangTotalPlayTimeInSeconds()
{
	if(FALSE == m_bIsPCBangClient)
	{
		return m_character.PCBangTotalPlayTime;
	}

	return m_character.PCBangTotalPlayTime + GetCurrentPlayTimeInSeconds();
}

BOOL CFieldIOCPSocket::CompareCharacterName(char *i_szCharacterName)
{
	if(0 == strnicmp(i_szCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME))
	{
		return TRUE;
	}

	return FALSE;
}

CFieldMapProject *CFieldIOCPSocket::GetDefaultCityMapProject(void)
{
	if(NULL == m_pCurrentFieldMapChannel)
	{
		return NULL;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 모든 유저는 기본적으로 도시맵으로 설정
	CFieldMapProject *pFMPro = m_pCurrentFieldMapChannel->GetDeadDefaultMapProjectW();

	///////////////////////////////////////////////////////////////////////////////
	// 도시점령 여단원은 점령도시맵으로 설정
	if(IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
	{
		CCityWar *pCityWar = ms_pFieldIOCP->m_cityWarManager.GetCityWarPtrByOccupyGuildUID(m_character.GuildUniqueNumber);
		if(pCityWar)
		{
			pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pCityWar->CityMapIndex);
		}
	}

	return pFMPro;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			CFieldMapProject *CFieldIOCPSocket::GetCityFieldMapProjectPtr(void)
/// \brief		
///				// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 인자추가(MapIndex_t i_nStartCityMapIdx)
/// \author		cmkwon
/// \date		2005-07-26 ~ 2005-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CFieldMapProject *CFieldIOCPSocket::GetCityFieldMapProjectPtr(BYTE i_byInfluence/*=INFLUENCE_TYPE_UNKNOWN*/, MapIndex_t i_nStartCityMapIdx/*=VCN_CITY_MAP_INDEX*/)
{
	if(INFLUENCE_TYPE_UNKNOWN == i_byInfluence)
	{
		i_byInfluence = m_character.InfluenceType;
		i_nStartCityMapIdx	= m_character.GetStartCityMapIndex();	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::GetCityFieldMapProjectPtr#
	}
	
	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::GetCityFieldMapProjectPtr#
	return ms_pFieldIOCP->GetCityFieldMapProjectPtrByInfluenceW(i_byInfluence, i_nStartCityMapIdx);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			CFieldMapChannel *CFieldIOCPSocket::GetCityFieldMapChannelPtr(BYTE i_byInfluence/*=INFLUENCE_TYPE_UNKNOWN*/)
/// \brief		
///				// 2007-02-27 by cmkwon, 인자추가(BYTE i_byInfluence=INFLUENCE_TYPE_UNKNOWN)
///				// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 인자추가(MapIndex_t i_nStartCityMapIdx)
/// \author		cmkwon
/// \date		2005-07-26 ~ 2005-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CFieldMapChannel *CFieldIOCPSocket::GetCityFieldMapChannelPtr(BYTE i_byInfluence/*=INFLUENCE_TYPE_UNKNOWN*/, MapIndex_t i_nStartCityMapIdx/*=VCN_CITY_MAP_INDEX*/)
{
	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::GetCityFieldMapChannelPtr#
	CFieldMapProject *pFMPro = this->GetCityFieldMapProjectPtr(i_byInfluence, i_nStartCityMapIdx);
	if(NULL == pFMPro)
	{
		return NULL;
	}

	return pFMPro->GetFirstFieldMapChannel(FALSE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::GetGardenFieldMapProjectPtr# 추가
/// \author		cmkwon
/// \date		2009-10-13 ~ 2009-10-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CFieldMapProject *CFieldIOCPSocket::GetGardenFieldMapProjectPtr(BYTE i_byInfluence/*=INFLUENCE_TYPE_UNKNOWN*/, MapIndex_t i_nStartCityMapIdx/*=VCN_CITY_MAP_INDEX*/)
{
	if(INFLUENCE_TYPE_UNKNOWN == i_byInfluence)
	{
		i_byInfluence		= m_character.InfluenceType;
		i_nStartCityMapIdx	= m_character.GetStartCityMapIndex();	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::GetCityFieldMapProjectPtr#
	}

	BOOL bMotherShipWar = ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(INFLUENCE_TYPE_ANI);		// 2012-07-02 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가

	MapIndex_t nGardenMapIdx = CAtumSJ::GetGargenMapIndexByInfluence(i_byInfluence, i_nStartCityMapIdx, bMotherShipWar);		// 2012-07-02 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가

	return ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nGardenMapIdx);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		캐릭터가 죽었을 때 떨굴 SPI량을 리턴한다.
/// \author		cmkwon
/// \date		2005-06-29 ~ 2005-06-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
INT CFieldIOCPSocket::GetDownSPICountOnDead(void)
{
	return CAtumSJ::GetSPIPenaltyOnDead(m_character.Level);
// 2006-09-14 by cmkwon, 모두다 위와 같이 수정함
// // 2006-09-05 by cmkwon, 아래와 같이 수정함
// // 	if (0 == m_ItemCenter.ItemNum 
// // 		|| m_ItemCenter.Kind != ITEMKIND_DEFENSE)
// // 	{// 아머 장착하지 않은 상태, 무조건 20000 스피만 차감
// // 		return 20000;
// // 	}
// // 
// // 	return ((float)m_ItemCenter.Price) * 15.0f / 100.0f;	// 2005-11-09 by cmkwon, 35%를 15%로 변경함
// 	switch(g_pFieldGlobal->GetLanguageType())
// 	{
// 	case LANGUAGE_TYPE_KOREAN:
// 		{
// 			return CAtumSJ::GetSPIPenaltyOnDead(m_character.Level);
// 		}
// 		break;
// 	case LANGUAGE_TYPE_ENGLISH:
// 	case LANGUAGE_TYPE_VIETNAMESE:
// 	default:
// 		{
// 			if (0 == m_ItemCenter.ItemNum 
// 				|| m_ItemCenter.Kind != ITEMKIND_DEFENSE)
// 			{// 아머 장착하지 않은 상태, 무조건 20000 스피만 차감
// 				return 20000;
// 			}
// 
// 			return ((float)m_ItemCenter.Price) * 15.0f / 100.0f;	// 2005-11-09 by cmkwon, 35%를 15%로 변경함
// 		}
// 	}
//
//	return 0;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ProcessSPIPenaltyOnDead(BYTE i_nItemUpdateType=IUT_PENALTY_ON_DEAD)
/// \brief		
/// \author		cmkwon
/// \date		2005-08-19 ~ 2005-08-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ProcessSPIPenaltyOnDead(BYTE i_nItemUpdateType/*=IUT_PENALTY_ON_DEAD*/)
{
	m_character.DownExperience			= 0.0f;		// 유닛이 죽을때 다운된 경험치 초기화
	m_character.DownSPIOnDeath			= 0;		// 2006-04-10 by cmkwon, 캐릭터가 죽을때 떨어지는 SPI

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	INT nDownSPI = GetDownSPICountOnDead();

	///////////////////////////////////////////////////////////////////////////////	
	// 2009-06-30 by cmkwon, 캐릭터 사망시 패널티 적용시 버그 수정 - 회복율을 적용한 금액으로 체크해야 한다.
	nDownSPI -= (nDownSPI * GetPlusRateExpRepair());

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (pMoney == NULL 
		|| pMoney->CurrentCount < nDownSPI)
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}

		Experience_t expDecrement	= CAtumSJ::GetLevelExperience(m_character.Level)->ExperienceLossOnDeath;
		expDecrement				= max(0, expDecrement - expDecrement*GetPlusRateExpRepair());

		Experience_t expOfLevel		= CAtumSJ::GetInitialExperienceOfLevel(m_character.Level);
		if (m_character.Experience - expDecrement <= expOfLevel)
		{
			CAtumLogSender::SendLogMessageEXP(this, expOfLevel - m_character.Experience, expOfLevel);	// Send Log
			this->m_character.DownExperience	= m_character.Experience - expOfLevel;
			m_character.Experience				= expOfLevel;
		}
		else
		{
			m_character.Experience				-= expDecrement;
			CAtumLogSender::SendLogMessageEXP(this, -expDecrement, m_character.Experience);				// Send Log
			this->m_character.DownExperience	= expDecrement;
		}

		QPARAM_CHARACTER_CHANGE_EXP *pQChangeEXP	= new QPARAM_CHARACTER_CHANGE_EXP;
		pQChangeEXP->CharacterUniqueNumber			= m_character.CharacterUniqueNumber;
		pQChangeEXP->Experience						= m_character.Experience;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeExp, this, m_character.AccountUniqueNumber, pQChangeEXP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_EXP);

// 2006-02-28 by cmkwon, 위와 같이 경험치 다운으로 처리
// 		m_character.Propensity -= m_character.Level;			// 명성 수치를 캐릭터의 Level 만큼 차감한다.
// 		
// 		QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPropensity = new QPARAM_CHARACTER_CHANGE_PKPOINT;
// 		pQChangePKPropensity->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
// 		pQChangePKPropensity->Propensity			= m_character.Propensity;
// 		pQChangePKPropensity->PKWinPoint			= m_character.PKWinPoint;
// 		pQChangePKPropensity->PKLossPoint			= m_character.PKLossPoint;
// 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, this
// 			, m_character.AccountUniqueNumber, pQChangePKPropensity);
// 
// 		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_PROPENSITY, T_FC_CHARACTER_CHANGE_PROPENSITY, pSPropensity, SendBuf);
// 		pSPropensity->ClientIndex		= m_character.ClientIndex;
// 		pSPropensity->byUpdateType		= i_nItemUpdateType;
// 		pSPropensity->Propensity		= m_character.Propensity;
// 		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_PROPENSITY));
	}
	else
	{
		// 2009-06-30 by cmkwon, 캐릭터 사망시 패널티 적용시 버그 수정 - 위에서 적용함.
		//nDownSPI -= (nDownSPI * GetPlusRateExpRepair());	// 2006-10-19 by cmkwon, SPI도 감소율 적용한다

		if(0 >= nDownSPI)
		{
			m_character.DownSPIOnDeath		= 0;				// 2006-04-10 by cmkwon, 죽을때 떨어지는 SPI 저장
		}
		else
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2006-10-27 by cmkwon, 로그 남기기 추가
			CAtumLogSender::SendLogMessageITEMSPI(this, pMoney, i_nItemUpdateType, -nDownSPI, max(0, pMoney->CurrentCount-nDownSPI));

			m_character.DownSPIOnDeath		= nDownSPI;				// 2006-04-10 by cmkwon, 죽을때 떨어지는 SPI 저장
			m_ItemManager.UpdateItemCountByPointer(pMoney, -nDownSPI, i_nItemUpdateType);
		}
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsCityCurrentFieldMapChannel(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-11-03 ~ 2005-11-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsCityCurrentFieldMapChannel(void)
{
	if(NULL == m_pCurrentFieldMapChannel){			return FALSE;}

	CFieldMapProject *pFMPro = this->GetCityFieldMapProjectPtr();

	return pFMPro == m_pCurrentFieldMapChannel->m_pFieldMapProject;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsValidCharacter(BOOL i_bLiveCheck/*=TRUE*/)
/// \brief		
///				// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
/// \author		cmkwon
/// \date		2005-11-18 ~ 2005-11-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsValidCharacter(BOOL i_bLiveCheck/*=TRUE*/, BOOL i_bPermissionArenaState/*=FALSE*/)
{
	if(FALSE == this->IsUsing())
	{
		return FALSE;
	}

	if(ST_CLIENT_TYPE != m_PeerSocketType)
	{
		return FALSE;
	}

	if(CS_PLAYING != GetClientState())
	{
		// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
		if(FALSE == i_bPermissionArenaState
			|| CS_ARENASERVER_PLAYING != GetClientState())
		{
			return FALSE;
		}
	}

	if(0 == m_character.AccountUniqueNumber
		|| 0 == m_character.CharacterUniqueNumber)
	{
		return FALSE;
	}

	if(i_bLiveCheck)
	{// 살아 있는지 체크
		if(COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
		{// 죽은 상태임
			return FALSE;
		}
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::IsEnableWarp(int i_nMapInfluenceTy, BOOL i_bConflictAraeMap, int i_nRequetCompletionQuestIndex/*=0*/)
/// \brief		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 
/// \author		cmkwon
/// \date		2005-11-24 ~ 2005-11-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::IsEnableWarp(int i_nMapInfluenceTy, BOOL i_bConflictAraeMap, int i_nRequetCompletionQuestIndex/*=0*/, BOOL i_bCancelTrade/*=FALSE*/,  CFieldMapProject *i_pTargetFieldMapProject /*= NULL*/)		// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
{
	if(FALSE == this->IsValidCharacter())
	{
		return ERR_INVALID_CHARACTER;
	}

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
	{// 이미 워프 중임
		return ERR_WARPING;
	}

	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{// 2006-03-23 by cmkwon, 거래중이다

		///////////////////////////////////////////////////////////////////////////////
		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 거래취소 처리
		if(FALSE == i_bCancelTrade)
		{
			return ERR_CANNOT_WARP_BY_TRADING;
		}
		SendTradeCanceledAndReset(NULL, TRUE);
	}

	if(m_pCurrentBuildingNPC)
	{// 2006-03-23 by cmkwon, 상점 이용중이다
		return ERR_CANNOT_WARP_BY_SHOPPING;
	}

	if(IS_MAP_INFLUENCE_CONFLICT_AREA(i_nMapInfluenceTy))
	{// 2006-02-09 by cmkwon, 분쟁 지역 맵이면 워프 불가
		return ERR_CANNOT_WARP_CONNFLICT_AREA;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2009-01-12 by dhjin, 선전 포고 - 밑과 같이 수정. // 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현으로 수정
	if(i_bConflictAraeMap
		&& MAP_INFLUENCE_NEUTRALITY != i_nMapInfluenceTy // 2009-01-12 by dhjin, 선전 포고 - 양세력 다 소유한 상태인지 체크
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::IsEnableWarp#
//		&& FALSE == IS_SAME_CHARACTER_8_MAP_INFLUENCE(m_character.InfluenceType, i_nMapInfluenceTy)
		&& FALSE == CAtumSJ::IsSameCharacterInfluence8MapInfluence(m_character.InfluenceType, i_nMapInfluenceTy)	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
		)
	{
		return ERR_CANNOT_WARP_POSSESSED_CONNFLICT_AREA;
 	}

// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::IsEnableWarp#, 아래에서 체크
// 	// 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현	
// 	if(IS_MAP_INFLUENCE_CITY(i_nMapInfluenceTy)
// 		&& FALSE == IS_SAME_CHARACTER_8_MAP_INFLUENCE(m_character.InfluenceType, i_nMapInfluenceTy))
// 	{// 2007-05-22 by cmkwon, 다른세력의 도시맵으로 워프 불가
// 		return ERR_CANNOT_WARP_TO_CITY;
// 	}	

	// 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현
	if(i_bConflictAraeMap
		|| MAP_INFLUENCE_NEUTRALITY == i_nMapInfluenceTy
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::IsEnableWarp#,
//		|| IS_SAME_CHARACTER_8_MAP_INFLUENCE(m_character.InfluenceType, i_nMapInfluenceTy))
		|| CAtumSJ::IsSameCharacterInfluence8MapInfluence(m_character.InfluenceType, i_nMapInfluenceTy))	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
	{// 2005-12-28 by cmkwon, 캐릭터와 맵의 세력이 같다, // 2006-08-28 by cmkwon, 분쟁지역, 중립지역도 퀘스트인덱스를 체크한다
		if(0 != i_nRequetCompletionQuestIndex
			&& FALSE == IsCheckQuestComplited(i_nRequetCompletionQuestIndex))
		{
			// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 워프 체크시 퀘스트완료 체크 하지 않음
			if(FALSE == g_pFieldGlobal->GetIsJamboreeServer())
			{
				return  ERR_REQ_WARP_COMPLETIONQUEST_NOT_MATCHED;
			}
		}
	}

// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::IsEnableWarp#,
// 	// 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현
// 	if(IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType)
// 		&& IS_MAP_INFLUENCE_ANI(i_nMapInfluenceTy))
// 	{// 2007-05-22 by cmkwon, 일반세력은 ANI세력맵으로 워프 불가
// 		return ERR_PROTOCOL_CANNOT_WARP;
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::IsEnableWarp#,
	if(IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType))
	{
		if(IS_MAP_INFLUENCE_CITY(i_nMapInfluenceTy))
		{
			MapIndex_t nStartCityMapIdx = m_character.GetStartCityMapIndex();

			if( (IS_ANI_CITY_MAP_INDEX(nStartCityMapIdx) && IS_MAP_INFLUENCE_VCN(i_nMapInfluenceTy))
				|| (FALSE == IS_ANI_CITY_MAP_INDEX(nStartCityMapIdx) && IS_MAP_INFLUENCE_ANI(i_nMapInfluenceTy)) )
			{
				return ERR_PROTOCOL_CANNOT_WARP;
			}
		}
		else if(IS_MAP_INFLUENCE_ANI(i_nMapInfluenceTy))
		{// 2009-10-13 by cmkwon, 일반세력은 도시맵이 아닌 ANI세력맵으로 워프 불가
		 	return ERR_PROTOCOL_CANNOT_WARP;
		}
	}
	else if(IS_MAP_INFLUENCE_CITY(i_nMapInfluenceTy)
		&& FALSE == CAtumSJ::IsSameCharacterInfluence8MapInfluence(m_character.InfluenceType, i_nMapInfluenceTy))
	{// 2007-05-22 by cmkwon, 다른세력의 도시맵으로 워프 불가
		return ERR_CANNOT_WARP_TO_CITY;
	}

	if (this->IsPartyBattleState())
	{// 파티전 체크
		return ERR_IN_PARTY_BATTLE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-27 by cmkwon, 개인 상점 체크
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{
		return ERR_USING_BAZAAR;
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	if( NULL != i_pTargetFieldMapProject )
	{
		Err_t nErr = i_pTargetFieldMapProject->IsEnableWarpByMapProject(this);
		if( ERR_NO_ERROR != nErr  )
		{
			return nErr;
		}
	}
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	// 2012-07-02 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가
	if( NULL != i_pTargetFieldMapProject )
	{
		if( IS_STONES_RUIN_MAP_INDEX(i_pTargetFieldMapProject->m_nMapIndex) )
		{
			if( COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_ANI) )		// 모선전 진행시 ANI 스톤즈 루인 입장 불가 
			{
				if( TRUE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(INFLUENCE_TYPE_ANI) )
				{
					return ERR_CANNOT_WARP_DURING_MSWAR;
				}
			}
		}
	}
	// end 2012-07-02 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::IsEnableWarpToCityMap(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-24 ~ 2006-07-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::IsEnableWarpToCityMap(void)
{
	CFieldMapProject *pFMapPro = this->GetCityFieldMapProjectPtr();
	if(NULL == pFMapPro)
	{
		return ERR_PROTOCOL_REQ_MAP_AREA_NOT_MATCHED;
	}
	
	return IsEnableWarp(pFMapPro->m_nMapInfluenceType, pFMapPro->IsConflictAreaMap(), pFMapPro->m_nQuestIndexForWarp);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::ClearCharacterForWarp(void)
/// \brief		// 2009-02-05 by cmkwon, 전쟁시 강제 워프 관련 처리 수정 - 
/// \author		cmkwon
/// \date		2009-02-05 ~ 2009-02-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::ClearCharacterForWarp(void)
{
	// 2009-02-05 by cmkwon, 편대전 처리 - 자신이 죽은것으로 처리
	if(this->IsPartyBattleState())
	{
		this->OnPartyBattleMemberDead();
	}

	// 2009-02-05 by cmkwon, 상점 체크
	if(m_pCurrentBuildingNPC)
	{
		m_pCurrentBuildingNPC		= NULL;		// 2009-02-05 by cmkwon, 상점 초기화

		INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_LEAVE_BUILDING_OK, T_FC_EVENT_LEAVE_BUILDING_OK, pLeaveOK, SendBuf);
		pLeaveOK->PositionVector	= m_character.PositionVector;
		pLeaveOK->TargetVector		= m_character.TargetVector*1000.0f;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_LEAVE_BUILDING_OK));
	}

	// 2009-02-05 by cmkwon, 거래 체크 - 거래 중일 경우 초기화 처리
	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
		if(this->m_bOKTradeChecked
			&& pPeerTraderSocket
			&& pPeerTraderSocket->IsValidCharacter()
			&& pPeerTraderSocket->m_bOKTradeChecked)
		{// 2009-02-05 by cmkwon, 1:1 거래시 둘다 거래승인을 누른 상태는 워프 불가
			return ERR_CANNOT_WARP_BY_TRADING;
		}

		SendTradeCanceledAndReset(pPeerTraderSocket, TRUE);
	}

	// 2009-02-05 by cmkwon, 죽은 상태 체크
	if(COMPARE_BODYCON_BIT(this->GetCharacter()->BodyCondition, BODYCON_DEAD_MASK))
	{
		this->CharacterDeadGameStartRoutine(TRUE, this->GetCharacter()->HP, this->GetCharacter()->DP);
		this->m_bDeadReasonByPK		= FALSE;
	}

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsCheckInfluenceTypeANDSocketType(BYTE i_bySenderInfluenceTyMask, int i_nOnlySocketTy/*=ST_ALL*/, BOOL i_bGameMasterOK/*=TRUE*/)
/// \brief		
///				// 2008-01-10 by cmkwon, IsCheckInfluenceTypeANDSocketType() 버그 수정 - IsCheckInfluenceTypeANDSocketType() 인자 추가
///				// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - IsCheckInfluenceTypeANDSocketType, 인자추가(i_nStartCityMapIdx)
/// \author		cmkwon
/// \date		2005-12-22 ~ 2005-12-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsCheckInfluenceTypeANDSocketType(BYTE i_bySenderInfluenceTyMask, int i_nOnlySocketTy/*=ST_ALL*/, BOOL i_bGameMasterOK/*=TRUE*/, MapIndex_t i_nStartCityMapIdx/*=0*/)
{
	if(ST_ALL != i_nOnlySocketTy
		&& m_PeerSocketType != i_nOnlySocketTy)
	{
		return FALSE;
	}

	// 2008-01-10 by cmkwon, IsCheckInfluenceTypeANDSocketType() 버그 수정 - i_bGameMasterOK 가 참일때만 RACE_GAMEMASTER 를 체크한다.
	if(i_bGameMasterOK
		&& COMPARE_RACE(m_character.Race, RACE_GAMEMASTER))
	{
		return TRUE;
	}

	if(FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, i_bySenderInfluenceTyMask))
	{
		return FALSE;
	}

	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 자신이 일반세력일 경우는 시작맵인덱스가 같아야 같은 세력이다. 0 일때는 
	if(INFLUENCE_TYPE_ALL_MASK != i_bySenderInfluenceTyMask
		&& 0 != i_nStartCityMapIdx
		&& COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{
		if(i_nStartCityMapIdx != GetCharacter()->Material
			&& !(0 == GetCharacter()->Material && IS_VCN_CITY_MAP_INDEX(i_nStartCityMapIdx)))
		{
			return FALSE;
		}
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsCheckLevel(BYTE i_byMinLevel, BYTE i_byMaxLevel)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-21 ~ 2006-07-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsCheckLevel(BYTE i_byMinLevel, BYTE i_byMaxLevel)
{
	if(0 != i_byMinLevel
		&& GetCharacter()->Level < i_byMinLevel)
	{
		return FALSE;
	}

	if(0 != i_byMaxLevel
		&& GetCharacter()->Level > i_byMaxLevel)
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::AddCharacterFame(int i_nAddCharacterFameValues/*=1*/, int i_nAddGuildFameValues/*=1*/)
/// \brief		// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 개인명성, 여단명성 인자 두개로 수정
/// \author		cmkwon
/// \date		2005-12-27 ~ 2005-12-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::AddCharacterFame(int i_nAddCharacterFameValues/*=1*/, int i_nAddGuildFameValues/*=1*/)
{

	if(0 < i_nAddCharacterFameValues)
	{// 2008-09-12 by cmkwon, 추가개인명성치가 0보다 클 경우만 처리

		// 자신의 명성치를 올린다.
		// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 
		//m_character.Propensity++;			// 캐릭터의 명성치는 항상 1을 올린다

		m_character.Propensity	+= i_nAddCharacterFameValues;		// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 

		// 변경 정보를 클라이언트로 전송한다.
		CheckAndUpdateStatus();
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
		
		// DB에 저장
		QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointLoser = new QPARAM_CHARACTER_CHANGE_PKPOINT;
		pQChangePKPointLoser->CharacterUniqueNumber		= m_character.CharacterUniqueNumber;
		pQChangePKPointLoser->Propensity				= m_character.Propensity;
		pQChangePKPointLoser->PKWinPoint				= m_character.PKWinPoint;
		pQChangePKPointLoser->PKLossPoint				= m_character.PKLossPoint;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, this, m_character.AccountUniqueNumber, pQChangePKPointLoser);
	}

	if(FALSE == this->IsValidGuild()
		|| 0 >= i_nAddGuildFameValues)	// 2008-09-12 by cmkwon, 추가여단명성치가 0보다 작으면 리턴 
	{// 여단이 없으면 리턴
		return;
	}

	// 여단 명성 
	INIT_MSG_WITH_BUFFER(MSG_FI_GUILD_ADD_GUILD_FAME, T_FI_GUILD_ADD_GUILD_FAME, pSGuildFame, SendBuf);
	pSGuildFame->guildUID	= m_character.GuildUniqueNumber;
// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 
//	pSGuildFame->addValues	= i_nAddFameValues;
	pSGuildFame->addValues	= i_nAddGuildFameValues;		// 2008-09-12 by cmkwon, "/명성" 명령어 추가 - 
	ms_pFieldIOCP->Send2IMServer(SendBuf, MSG_SIZE(MSG_FI_GUILD_ADD_GUILD_FAME));
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsGoToInfluenceCity(BYTE i_byCharInfluenceTy, INT i_nMapInfluenceTy)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-28 ~ 2005-12-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsGoToInfluenceCity(BYTE i_byCharInfluenceTy, INT i_nMapInfluenceTy)
{
	if(IS_MAP_INFLUENCE_EVENT_AREA(i_nMapInfluenceTy))
	{// 2006-07-18 by cmkwon, 이벤트맵 이면 도시맵으로 이동
		return TRUE;
	}

	if(COMPARE_INFLUENCE(i_byCharInfluenceTy, INFLUENCE_TYPE_NORMAL|INFLUENCE_TYPE_VCN))
	{
		return MAP_INFLUENCE_ANI_START == i_nMapInfluenceTy;
	}
	if(COMPARE_INFLUENCE(i_byCharInfluenceTy, INFLUENCE_TYPE_ANI))
	{
		return MAP_INFLUENCE_VCN_START == i_nMapInfluenceTy;
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsValidGuild(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-28 ~ 2005-12-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsValidGuild(void)
{
	return IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::StoreDB_QPARAM_CHARACTER_CHANGE_STAT(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-04 ~ 2006-04-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::StoreDB_QPARAM_CHARACTER_CHANGE_STAT(void)
{
	QPARAM_CHARACTER_CHANGE_STAT	*pQChangeStat = new QPARAM_CHARACTER_CHANGE_STAT;
	pQChangeStat->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pQChangeStat->byAutoStatType		= m_character.AutoStatType;
	pQChangeStat->GearStat1				= m_character.GearStat;
	pQChangeStat->HP					= m_character.HP;
	pQChangeStat->DP					= m_character.DP;
	pQChangeStat->SP					= m_character.SP;
	pQChangeStat->EP					= m_character.EP;
	pQChangeStat->BonusStat				= m_character.BonusStat;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeStat, this, m_character.AccountUniqueNumber, pQChangeStat);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::StoreExperienceDelayStore(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-05-21 ~ 2006-05-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::StoreExperienceDelayStore(void)
{
	if(m_character.Experience != m_ExperienceDelayStore)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2006-05-21 by cmkwon
		QPARAM_CHARACTER_CHANGE_EXP *pQChangeEXP	= new QPARAM_CHARACTER_CHANGE_EXP;
		pQChangeEXP->CharacterUniqueNumber			= m_character.CharacterUniqueNumber;
		pQChangeEXP->Experience						= m_character.Experience;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeExp, this, m_character.AccountUniqueNumber, pQChangeEXP);

		///////////////////////////////////////////////////////////////////////////////
		// 2007-01-15 by cmkwon, 시스템 로그에도 남긴다
		CAtumLogSender::SendLogMessageEXP(this, m_character.Experience - m_ExperienceDelayStore, m_character.Experience);	// Send Log

		m_ExperienceDelayStore						= m_character.Experience;
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CharacterChangeModeRoutine(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-07-25 ~ 2005-07-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CharacterChangeModeRoutine(void)
{
	if(FALSE == m_character.CharacterMode)
	{// 기어모드 일때 - 캐릭터모드가 아닐때
	
	}
	else
	{// 캐릭터모드 일때 

	}


}




void CFieldIOCPSocket::OnWarpDone(EnumWarpType warpType)
{
#ifdef _DEBUG
	SendString128(STRING_128_ADMIN_CMD, "ATTACKPROBABILITY01: %d @OnWarpDone", m_ParamFactor.pfp_ATTACKPROBABILITY_01);
#endif
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);

	CharacterSaveCriticalData();


	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-16 by cmkwon, 파티원의 워프 처리 - 맵채널 시스템 때문에 여기에서 처리
	if(m_bQuestRequestWarp)
	{
		CFieldMapChannel *pBeforeFMapChann	= ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(m_beforeMapChannIdxQuestRequestWarp);	// 2006-10-16 by cmkwon
		CFieldMapProject *pMapProject		= GetCurrentFieldMapProject();	// 2006-10-16 by cmkwon
		CFieldParty *pFParty				= this->m_pFieldParty;			// 2006-07-04 by cmkwon

		if(pBeforeFMapChann && pMapProject && pFParty)
		{
			m_dwLastQuestRequestWarpTick		= timeGetTime();					// 2006-10-16 by cmkwon

			INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_PARTY_WARP, T_FC_QUEST_REQUEST_PARTY_WARP, pPartyWarp, SendBuf);
			pPartyWarp->callerCharacterUID		= m_character.CharacterUniqueNumber;
			pPartyWarp->dwRemainTime			= TERM_QUEST_REQUEST_WARP_EFFECTIVE_TIME;	// 2006-10-16 by cmkwon, 20초
			pPartyWarp->warpMapChannIndex		= m_character.MapChannelIndex;

			///////////////////////////////////////////////////////////////////////////////
			// 2006-10-16 by cmkwon
			CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
			MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);

			//////////////////////////////////////////////////////////////////////////
			// 2008-12-16 by dhjin, 미션마스터 - 미션마스터는 다른 맵에 있어도 워프가능
			// 2007-06-26 by cmkwon, 파티 경험치 관련 수정 - 살아 있는 캐릭터만 처리
//			int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, pBeforeFMapChann, TRUE);
			int nMemCount = pFParty->QuestWarpGetMembers(ArrayPartyMember, pBeforeFMapChann);

			for(int i=0; i<nMemCount; i++)
			{
				if(ArrayPartyMember[i]
					&& ArrayPartyMember[i] != this
					&& ERR_NO_ERROR == ArrayPartyMember[i]->IsEnableWarp( pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp))
				{
					ArrayPartyMember[i]->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_PARTY_WARP));
				}
			}
		}
	}// END - if(m_bQuestRequestWarp)
	m_bQuestRequestWarp			= FALSE;		// 2006-10-16 by cmkwon

	//////////////////////////////////////////////////////////////////////////
	// 2009-01-06 by dhjin, 전쟁 보상 추가안
	if(this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint()
		|| this->ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring() )
	{
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::OnWarpDone#, 아래와 같이 수정
//		if(IS_OTHER_INFLUENCE_MAP(this->m_character.InfluenceType, this->GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())
		if(CAtumSJ::IsOtherInfluenceMap(m_character.InfluenceType, m_character.GetStartCityMapIndex(), GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			&& (0 == this->GetCurrentFieldMapChannel()->GetMapChannelIndex().ChannelIndex ))
		{
			ms_pFieldIOCP->WarOtherInflStayTime(this, TRUE);
		}
		else
		{
			ms_pFieldIOCP->WarOtherInflStayTime(this, FALSE);
		}
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	this->GetCurrentFieldMapProject()->InsertEnterOneTimeLimited(m_character.CharacterUniqueNumber);
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
}

void CFieldIOCPSocket::SetBodyConditionBit(BodyCond_t &VAR, BodyCond_t MASK)
{
	SET_BODYCON_BIT(VAR, MASK);
}

void CFieldIOCPSocket::ClearBodyConditionBit(BodyCond_t &VAR, BodyCond_t MASK)
{
	CLEAR_BODYCON_BIT(VAR, MASK);
}

/*
BOOL CFieldIOCPSocket::CompareBodyConditionBit(BodyCondtionMask_t &VAR, BodyCondtionMask_t MASK)
{
	return COMPARE_BODYCON_BIT(VAR, MASK);
}
*/

// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 아래와 같이 함수명 변경
//void CFieldIOCPSocket::UpdateRenderInfo()
void CFieldIOCPSocket::InitRenderInfo(void)
{
// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - ShapeItemNum 필드 추가
// 	m_UnitRenderInfo.RI_Prow		= ((m_ItemProw.ItemNum!=0)?((ITEM_BASE*)m_ItemProw.ItemNum)->ItemInfo->ItemNum:0);
// 	m_UnitRenderInfo.RI_ProwOut		= ((m_ItemProwOut.ItemNum!=0)?((ITEM_BASE*)m_ItemProwOut.ItemNum)->ItemInfo->ItemNum:0);
// 	m_UnitRenderInfo.RI_WingOut		= ((m_ItemWingOut.ItemNum!=0)?((ITEM_BASE*)m_ItemWingOut.ItemNum)->ItemInfo->ItemNum:0);
// 	m_UnitRenderInfo.RI_WingIn		= ((m_ItemWingIn.ItemNum!=0)?((ITEM_BASE*)m_ItemWingIn.ItemNum)->ItemInfo->ItemNum:0);		// 2006-07-25 by cmkwon
// 	if(0 == m_ItemCenter.ItemNum)
// 	{
// 		m_UnitRenderInfo.RI_Center	= 0;
// 	}
// 	else
// 	{
// 		m_UnitRenderInfo.RI_Center			= ((ITEM_BASE*)m_ItemCenter.ItemNum)->ItemInfo->ItemNum;
// 		m_UnitRenderInfo.RI_ArmorColorCode	= ((ITEM_GENERAL*)m_ItemCenter.ItemNum)->ColorCode;			// 2005-12-08 by cmkwon, 아머 색상 튜닝 정보
// 	}
// 	m_UnitRenderInfo.RI_Rear		= ((m_ItemRear.ItemNum!=0)?((ITEM_BASE*)m_ItemRear.ItemNum)->ItemInfo->ItemNum:0);
// 	m_UnitRenderInfo.RI_Attachment	= ((m_ItemAttachment.ItemNum!=0)?((ITEM_BASE*)m_ItemAttachment.ItemNum)->ItemInfo->ItemNum:0);
	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - ShapeItemNum 필드 추가, 아래와 같이 수정
	int nItemNum, nShapeItemNum, nEffectItemNum, nPetLevel = 0;		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
	
	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	/*for(int i = POS_PROW; i <= POS_ACCESSORY_TIME_LIMIT; i++)*/
	for(int i = POS_PROW; i <= POS_PET; i++)
	{
		if(FALSE == this->UpdateItemRenderInfoByPOS(&nItemNum, &nShapeItemNum, &nEffectItemNum, i, &nPetLevel))		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::InitRenderInfo# invalid attached Pos(%d) ItemNum(%d) ShapeItemNum(%d) EffectItemNum(%d) !! \r\n", i, nItemNum, nShapeItemNum, nEffectItemNum);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
/// \author		cmkwon
/// \date		2009-08-26 ~ 2009-08-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::UpdateItemRenderInfoByPOS(INT *o_pnItemNum, INT *o_pnShapeItemNum, INT *o_pnEffectItemNum, INT i_nPos, INT *o_pnPetLevel)		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
{
	*o_pnItemNum		= 0;
	*o_pnShapeItemNum	= 0;
	*o_pnEffectItemNum	= 0;
	*o_pnPetLevel	= 0;		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
	switch(i_nPos)
	{
	case POS_PROW:			// 레이더 - 외형변경가능
		{
			if(0 != m_ItemProw.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemProw.ItemNum)->ItemInfo->ItemNum;
				*o_pnShapeItemNum	= ((ITEM_GENERAL*)m_ItemProw.ItemNum)->GetShapeItemNum();
			}
		}
		break;
	case POS_PROWIN:		// CPU 컴퓨터 - 
		{
			if(0 != m_ItemProwIn.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemProwIn.ItemNum)->ItemInfo->ItemNum;
			}
		}
		break;
	case POS_PROWOUT:		// 1형 무기 - 외형변경가능 + 탄두이펙트변경가능
		{
			if(0 != m_ItemProwOut.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemProwOut.ItemNum)->ItemInfo->ItemNum;
				*o_pnShapeItemNum	= ((ITEM_GENERAL*)m_ItemProwOut.ItemNum)->GetShapeItemNum();
				*o_pnEffectItemNum	= ((ITEM_GENERAL*)m_ItemProwOut.ItemNum)->GetEffectItemNum();
			}
		}
		break;
	case POS_WINGIN:		// 마크 - 외형변경가능
		{
			if(0 != m_ItemWingIn.ItemNum)
			{
				*o_pnItemNum			= ((ITEM_GENERAL*)m_ItemWingIn.ItemNum)->ItemInfo->ItemNum;
				*o_pnShapeItemNum		= ((ITEM_GENERAL*)m_ItemWingIn.ItemNum)->GetShapeItemNum();
			}
		}
		break;
	case POS_WINGOUT:		// 2형 무기 - 외형변경가능 + 탄두이펙트변경가능
		{
			if(0 != m_ItemWingOut.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->ItemInfo->ItemNum;
				*o_pnShapeItemNum	= ((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->GetShapeItemNum();
				*o_pnEffectItemNum	= ((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->GetEffectItemNum();
			}
		}
		break;
	case POS_CENTER:		// 아머 - 외형변경가능
		{
			if(0 != m_ItemCenter.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemCenter.ItemNum)->ItemInfo->ItemNum;
				*o_pnShapeItemNum	= ((ITEM_GENERAL*)m_ItemCenter.ItemNum)->GetShapeItemNum();
			}
		}
		break;
	case POS_REAR:			// 엔진 - 
		{
			if(0 != m_ItemRear.ItemNum)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemRear.ItemNum)->ItemInfo->ItemNum;
			}
		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_ATTACHMENT:	// 연료탱크 or 지도자의광휘 - 
	case POS_ACCESSORY_UNLIMITED :
		{
			if(0 != m_ItemAccessoryUnLimited.ItemNum/*m_ItemAttachment.ItemNum*/)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemAccessoryUnLimited.ItemNum/*m_ItemAttachment.ItemNum*/)->ItemInfo->ItemNum;
			}
		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			// 시간제한 악세사리 - 
	case POS_ACCESSORY_TIME_LIMIT :
		{
			if(0 != m_ItemAccessoryTimeLimit.ItemNum/*m_ItemPet.ItemNum*/)
			{
				*o_pnItemNum		= ((ITEM_GENERAL*)m_ItemAccessoryTimeLimit.ItemNum/*m_ItemPet.ItemNum*/)->ItemInfo->ItemNum;
			}
		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템
	case POS_PET :
		{
			if( 0 != m_ItemPet.ItemNum )
			{
				*o_pnItemNum = ((ITEM_GENERAL*)m_ItemPet.ItemNum)->ItemInfo->ItemNum;

				tPET_CURRENTINFO *psPetCurInfo = m_ItemManager.GetItemPetByUID ( ((ITEM_GENERAL *)m_ItemPet.ItemNum)->UniqueNumber );
				if ( psPetCurInfo && ms_pFieldIOCP->m_cPetDataManager.GetPetLevelData ( psPetCurInfo->PetIndex , psPetCurInfo->PetLevel ) )
				{	// 펫의 ShapeItemNum은 2개(City & Field)이기 때문에 레벨값을 넣어 활용한다.
					*o_pnShapeItemNum =((ITEM_GENERAL*)m_ItemPet.ItemNum)->GetShapeItemNum();		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
					*o_pnPetLevel = psPetCurInfo->PetLevel;		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
				}
			}
		}
		break;

	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::UpdateItemRenderInfoByPOS# invalid attached Pos(%d) !! \r\n", i_nPos);
			return FALSE;
		}
	}

	return m_UnitRenderInfo.SetRenderInfoWithPOS(i_nPos, *o_pnItemNum, *o_pnShapeItemNum, *o_pnEffectItemNum);
}

void CFieldIOCPSocket::UpdateItemRenderInfo(INT WinPos, BOOL bSendMsg)
{
// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
// 	INT ItemNum = 0;
// 	int	nArmorColorCode = 0;
// 	switch(WinPos) {
// 	case POS_PROW:
// 		ItemNum
// 			= (m_UnitRenderInfo.RI_Prow
// 			= ((m_ItemProw.ItemNum!=0)?((ITEM_BASE*)m_ItemProw.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	case POS_PROWOUT:
// 		ItemNum
// 			= (m_UnitRenderInfo.RI_ProwOut
// 			= ((m_ItemProwOut.ItemNum!=0)?((ITEM_BASE*)m_ItemProwOut.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	case POS_WINGOUT:
// 		ItemNum
// 			= (m_UnitRenderInfo.RI_WingOut
// 			= ((m_ItemWingOut.ItemNum!=0)?((ITEM_BASE*)m_ItemWingOut.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	case POS_WINGIN:		// 2006-07-25 by cmkwon, 추가함
// 		ItemNum	= (m_UnitRenderInfo.RI_WingIn
// 			= ((m_ItemWingIn.ItemNum!=0)?((ITEM_BASE*)m_ItemWingIn.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	case POS_CENTER:
// 		{
// 			if(0 == m_ItemCenter.ItemNum)
// 			{
// 				ItemNum = m_UnitRenderInfo.RI_Center = 0;
// 			}
// 			else
// 			{
// 				ItemNum			= ((ITEM_BASE*)m_ItemCenter.ItemNum)->ItemInfo->ItemNum;
// 				nArmorColorCode = ((ITEM_GENERAL*)m_ItemCenter.ItemNum)->ColorCode;			// 2005-12-08 by cmkwon, 아머 색상 튜닝 정보
// 			}
// 		}
// 		break;
// 	case POS_REAR:
// 		ItemNum
// 			= (m_UnitRenderInfo.RI_Rear
// 			= ((m_ItemRear.ItemNum!=0)?((ITEM_BASE*)m_ItemRear.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	case POS_ATTACHMENT:
// 		ItemNum
// 			= (m_UnitRenderInfo.RI_Attachment
// 			= ((m_ItemAttachment.ItemNum!=0)?((ITEM_BASE*)m_ItemAttachment.ItemNum)->ItemInfo->ItemNum:0));
// 		break;
// 	default:
// 		ItemNum = -1;
// 		break;
// 	}
// 
// 	if (bSendMsg 
// 		&& ItemNum != -1)
// // 2006-07-03 by cmkwon, 캐릭터 모드에서도 전송이 필요함 - 세력지도자 이펙트 아이템,...
// //		&& FALSE == this->m_character.CharacterMode)
// 	{
// 		// 주위에 있는 캐릭들에게 전송
// 		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_UPDATE_ITEM_POS, T_FC_ITEM_UPDATE_ITEM_POS, pPos, pPosBuf);
// 		pPos->ClientIndex	= m_character.ClientIndex;
// 		pPos->ItemPosition	= WinPos;
// 		pPos->ItemNum		= ItemNum;
// 		pPos->ColorCode		= nArmorColorCode;
// 		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pPosBuf, MSG_SIZE(MSG_FC_ITEM_UPDATE_ITEM_POS)
// 			, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
// 
// 		if (m_pFieldParty != NULL)
// 		{
// 			// 파티원들에게는 모두 전송(IM Server를 이용)
// 			INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_UPDATE_ITEM_POS, T_FI_PARTY_UPDATE_ITEM_POS, pPartyPos, pPartyPosBuf);
// 			pPartyPos->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
// 			pPartyPos->ItemPosition				= WinPos;
// 			pPartyPos->ItemNum					= ItemNum;
// 			pPartyPos->ColorCode				= nArmorColorCode;
// 			ms_pFieldIOCP->m_pIMWinSocket->Write(pPartyPosBuf, MSG_SIZE(MSG_FI_PARTY_UPDATE_ITEM_POS));
// 		}
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
	INT nItemNum		= 0;
	INT nShapeItemNum	= 0;
	INT nEffectItemNum	= 0;	
	INT nPetLevel		= 0;		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
	if(FALSE == this->UpdateItemRenderInfoByPOS(&nItemNum, &nShapeItemNum, &nEffectItemNum, WinPos, &nPetLevel))		// 2012-12-05 by hskim, 파트너 기간제 외형 변경
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::UpdateItemRenderInfo# invalid attached Pos(%d) Send(%d) !! ItemNum(%d) ShapeItemNum(%d) EffectItemNum(%d) \r\n", WinPos, bSendMsg, nItemNum, nShapeItemNum, nEffectItemNum);
		return;
	}

	if(FALSE == bSendMsg)
	{
		return;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_UPDATE_ITEM_POS, T_FC_ITEM_UPDATE_ITEM_POS, pPos, pPosBuf);
	pPos->ClientIndex	= m_character.ClientIndex;
	pPos->ItemPosition	= WinPos;
	pPos->ItemNum		= nItemNum;
	pPos->nShapeItemNum		= nShapeItemNum;		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 외형을 위한 ItemNum이 전달된다.
	pPos->nEffectItemNum	= nEffectItemNum;		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
	pPos->nPetLevel		= nPetLevel;				// 2012-12-05 by hskim, 파트너 기간제 외형 변경
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pPosBuf, MSG_SIZE(MSG_FC_ITEM_UPDATE_ITEM_POS)
		, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
	
	if (m_pFieldParty != NULL)
	{
		// 파티원들에게는 모두 전송(IM Server를 이용)
		INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_UPDATE_ITEM_POS, T_FI_PARTY_UPDATE_ITEM_POS, pPartyPos, pPartyPosBuf);
		pPartyPos->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pPartyPos->ItemPosition				= WinPos;
		pPartyPos->ItemNum					= nItemNum;
		pPartyPos->nShapeItemNum			= nShapeItemNum;		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 외형을 위한 ItemNum이 전달된다.
		pPartyPos->nEffectItemNum			= nEffectItemNum;		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
		ms_pFieldIOCP->m_pIMWinSocket->Write(pPartyPosBuf, MSG_SIZE(MSG_FI_PARTY_UPDATE_ITEM_POS));
	}


// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 전체를 재설정하는 것은 필요하지 않음
// 	// 재설정
// 	UpdateRenderInfo();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-18 by cmkwon, 몬스터변신 구현 - 
/// \author		cmkwon
/// \date		2010-03-18 ~ 2010-03-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::UpdateItemRenderInfoForTransformer(INT i_nMonUnitKind, BOOL i_bAttachFlag, BOOL i_bSendToAround/*=TRUE*/)
{
	if(i_bAttachFlag)
	{ 
	    // 2010-05-26 shcho 몬스터 변신카드 추가수정 - 변신상태에서 바로 변신되도록 수정
		if(m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer && i_nMonUnitKind)
		{
			m_ItemManager.DeleteUsingTimeLimitedItemListByDestParameter(DES_TRANSFORM_TO_MONSTER);
		}
		if(0 != m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer &&
		  m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer == i_nMonUnitKind)
		{
			return FALSE;
		}
	}

	m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer	= i_nMonUnitKind;


	if(i_bSendToAround)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_UPDATE_TRANSFORMER_OK, T_FC_ITEM_UPDATE_TRANSFORMER_OK, pSMsg, SendBuf);
		pSMsg->CharacUID		= GetCharacter()->CharacterUniqueNumber;
		pSMsg->ClientIdx		= GetCharacter()->ClientIndex;
		pSMsg->MonsterUnitKind	= m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer;
		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_ITEM_UPDATE_TRANSFORMER_OK)
			, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

		if (m_pFieldParty != NULL)
		{
			// 파티원들에게는 모두 전송(IM Server를 이용)
			INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_UPDATE_ITEM_TRANSFORMER_OK, T_FI_PARTY_UPDATE_ITEM_TRANSFORMER_OK, pPMsg, pPSendBuf);
			pPMsg->CharacUID		= GetCharacter()->CharacterUniqueNumber;
			pPMsg->ClientIdx		= GetCharacter()->ClientIndex;
			pPMsg->MonsterUnitKind	= m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer;
			ms_pFieldIOCP->Send2IMServer(pPSendBuf, MSG_SIZE(MSG_FI_PARTY_UPDATE_ITEM_TRANSFORMER_OK));
		}
	}
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		이 함수를 호출한 곳에서 m_ItemManager를 Lock한 상태이다
///				// 2010-03-10 by cmkwon, 인피에서 시간제한 액세서리 추가 관련 버그 수정 - 
/// \author		cmkwon
/// \date		2005-03-10 ~ 2005-03-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InitCharacterInventoryItem(BOOL i_bStartFromArena/*=FALSE*/)
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));		// 2010-03-10 by cmkwon, 인피에서 시간제한 액세서리 추가 관련 버그 수정 - 

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	ITEM_GENERAL *pAccesoryTimeLimiteItemG = GetAttachItemGeneralByPosition( POS_ACCESSORY_TIME_LIMIT /*POS_PET*/);

	if(pAccesoryTimeLimiteItemG)
	{// 2006-04-24 by cmkwon, 액세서리 시간제한 아이템을 추가한다, m_ItemManager.ResetTimeStampUsingTimeLimitedItemList()함수 호출전에 추가해야한다.
		m_ItemManager.Add2UsingTimeLimitedItemList(pAccesoryTimeLimiteItemG);
	}
	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	ITEM_GENERAL *pPetTimeItemG = GetAttachItemGeneralByPosition( POS_PET );
	
	if(pPetTimeItemG)
	{
		m_ItemManager.Add2UsingTimeLimitedItemList(pPetTimeItemG);
	}

	// end 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현

	// 1. 모든 시간 제한 카드 아이템을 클라이언트로 전송하고 적용한다
	m_ItemManager.ResetTimeStampUsingTimeLimitedItemList();

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
//	// 2. 컴퓨터 아이템 스탯 포함 전체 스탯 계산
//	this->CheckArmor_SendTotalStat(TRUE);
	// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
	// 2010-03-10 by cmkwon, 인피에서 시간제한 액세서리 추가 관련 버그 수정 - 
	if(FALSE == i_bStartFromArena)
	{
		this->RearrangeCharacterTatalStat(FALSE);	// called CFieldIOCPSocket::InitCharacterInventoryItem#
	}
	else
	{
		this->RearrangeCharacterTatalStat();		// called CFieldIOCPSocket::InitCharacterInventoryItem#
	}

	// 3. skill and enchant 적용
	this->ResetAllSkillAndEnchant();		// called CFieldIOCPSocket::InitCharacterInventoryItem#

	// 4. Item Requirement 체크
	m_ItemManager.CheckRequirementAllGeneralItems();

	if(FALSE == this->GetStealthState() )		// 2013-05-09 by hskim, 세력 포인트 개선
	{
		INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);
			pSMsg->ChannelIndex		= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
			pSMsg->ClientIndex		= m_character.ClientIndex;
			pSMsg->bStealthState2	= this->GetStealthState();		// 2013-05-09 by hskim, 세력 포인트 개선

		m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
	}
	return TRUE;
}

// 장전된 아이템(무기)에 대해서만 해당됨
BOOL CFieldIOCPSocket::ResetAllSkillAndEnchant()
{
	mt_auto_lock mta(&m_ItemManager.m_mapItemGeneral);

	m_ParamFactor.Reset();									// 모든 ParamFactor 초기화
	this->m_InvokingItemManager.Init();		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 초기화


// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 	m_SkillManager.ApplyAllPermanentAndAtivatedSkills();	// PermanentSill 적용
// 	ApplyEnchant(&m_ItemProwOut);							// 1형 무기 Enchant 적용(모든 인챈트가 적용됨)
// 	ApplyEnchant(&m_ItemWingOut);							// 2형 무기 Enchant 적용(모든 인챈트가 적용됨)
// 	ApplyRareFix(((ITEM_GENERAL*)m_ItemProwOut.ItemNum));	// 1형 무기 Rare 적용
// 	ApplyRareFix(((ITEM_GENERAL*)m_ItemWingOut.ItemNum));	// 2형 무기 Rare 적용
// 	
// 	ApplyEnchant(&m_ItemCenter);							// 아머 Enchant 적용(HP,DP를 제외한 인챈트 적용)
// 	ApplyArmorParamFactor();								// 아머 3,4번 Param 적용
// 	
// 	// 2008-09-23 by dhjin, 신규 인첸트
// 	ApplyEnchant(&m_ItemRear);		// 엔진 적용
// 	ApplyEnchant(&m_ItemProw);		// 레이더 적용
// 	
// 	ChangeHP(GetCharacterTotalHP());
// 	ChangeDP(GetCharacterTotalDP());
// 	
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2006-04-24 by cmkwon
// 	this->ApplyParamFactorWithAllUsingTimeLimitedOnlyCardItemW();
// 	
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2006-04-24 by cmkwon
// 	ITEM_GENERAL *pAccesoryTimeLimiteItemG = GetAttachItemGeneralByPosition(POS_PET);
// 	if(pAccesoryTimeLimiteItemG)
// 	{
// 		ApplyParamFactorWithAccesoryTimeLimiteItem(pAccesoryTimeLimiteItemG->ItemInfo);
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템	
	m_SkillManager.ApplyAllPermanentAndAtivatedSkills();	// PermanentSill 와 ActivateSkill 기능 적용
	ApplyDestParam8Enchant8RareOfAttachedItems();			// 모든 장착아이템의 기능적용

	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-24 by cmkwon, 장착아이템을 제외한 사용중 아이템 파라미터 적용
	this->ApplyParamFactorWithAllUsingTimeLimitedOnlyCardItemW();


	this->ChangeHP(this->GetCharacterTotalHP());
	this->ChangeDP(this->GetCharacterTotalDP());
	this->ChangeEP(this->GetCharacterTotalEP());		// 2010-03-31 by cmkwon, 연료 관련 버그 수정(K0002796) - DP와 같은 방식으로 변경
	this->ChangeSP(this->GetCharacterTotalSP());		// 2010-08-26 by shcho&jsKim, 밤 아이템 구현

	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	// Update DB
	QPARAM_CHARACTER_CHANGE_HPDPSPEP *pQChangeHPDPSPEP = new QPARAM_CHARACTER_CHANGE_HPDPSPEP;
	pQChangeHPDPSPEP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	pQChangeHPDPSPEP->HP = m_character.HP;
	pQChangeHPDPSPEP->DP = m_character.DP;
	pQChangeHPDPSPEP->SP = m_character.SP;
	pQChangeHPDPSPEP->EP = m_character.EP;
	pQChangeHPDPSPEP->CurrentHP = m_character.CurrentHP;
	pQChangeHPDPSPEP->CurrentDP = m_character.CurrentDP;
	pQChangeHPDPSPEP->CurrentSP = m_character.CurrentSP;
	pQChangeHPDPSPEP->CurrentEP = m_character.CurrentEP;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeHPDPSPEP, this, m_character.AccountUniqueNumber, pQChangeHPDPSPEP);
	return TRUE;
}

// 2013-05-22 by jhseol, 소스정리 - 주석삭제

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB(vectITEM_GENERALPtr *i_pvectItemGPtrList, vectENCHANT *i_pvectEnchantList, vectItemSkillPtr *i_pvectItemSkillPtrList)
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// wbrief		2010-06-15 by shcho&hslee 펫시스템 - 아이템 펫일 경우 추가 정보 생성 인자 추가(vectCurrentDataInfo *i_vectPetInfo)
/// \author		dhjin
/// \date		2007-12-21 ~ 2007-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB(vectITEM_GENERALPtr *i_pvectItemGPtrList, vectENCHANT *i_pvectEnchantList, vectItemSkillPtr *i_pvectItemSkillPtrList,vecPetCurrentInfo *i_vectPetCurInfo) // 2007-12-21 by dhjin, 게임 시작 루틴 DB값 설정과 Client전송 부분 분리
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));
	m_ItemManager.ResetAllCharacterItems();


	///////////////////////////////////////////////////////////////////////
	// START 2010-06-15 by shcho&hslee 펫시스템 - 아이템 펫일 경우 추가 정보 생성
	// 저장할 데이터  m_vectPetInfo
	// 받아온 데이터  i_vectPetInfo
	mt_auto_lock vtlock(&this->m_ItemManager.m_vectPetCurrentInfo);
	//m_vectPetInfo.clear();
	int nPetInfoCnt		= i_vectPetCurInfo->size();
	if(0 < nPetInfoCnt)
	{
		for(int i=0; i < nPetInfoCnt; i++)
		{
			tPET_CURRENTINFO *pCurrentInfo = (*i_vectPetCurInfo)[i];
			this->m_ItemManager.InsertItemPetByPointer( pCurrentInfo );
		}
		i_vectPetCurInfo->clear();
	}// END
	vtlock.auto_unlock_cancel();	
	// END 2010-06-15 by shcho&hslee 펫시스템 - 아이템 펫일 경우 추가 정보 생성
	////////////////////////////////////////////////////////////////////////

	////////////////////////////////////////////////////////////////////////
	// 2010-06-15 by shcho&hslee 펫시스템 - 펫 아이템 정보 클라이언트로 전송.
	SendPetItemList ();
	// END 2010-06-15 by shcho&hslee 펫시스템 - 펫 아이템 정보 클라이언트로 전송.
	////////////////////////////////////////////////////////////////////////


	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, 1. 인벤토리 아이템 추가
	int nItemCnt		= i_pvectItemGPtrList->size();
	if(0 < nItemCnt)
	{// 2007-12-26 by cmkwon, 인벤토리 아이템 추가
		for(int i=0; i < nItemCnt; i++)
		{
			ITEM_GENERAL *pItemG = (*i_pvectItemGPtrList)[i];

			if(COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_TIME_LIMITE|ITEM_ATTR_DELETED_TIME_LIMITE_AFTER_USED)	// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 
				&& ITEM_NOT_USING != pItemG->UsingTimeStamp
// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB#, 
//				&& ITEMKIND_ACCESSORY_TIMELIMIT != pItemG->Kind
				&& FALSE == IS_ATTACHABLE_ITEM(pItemG->ItemInfo))		// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB#, 창착 불가 아이템만 처리, 장착 가능 아이템은 장착시 처리됨
			{
				if(TRUE == g_pFieldGlobal->IsArenaServer()) {
					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가, 인피 시작시 아이템 로그
					CAtumLogSender::SendLogMessageInfinityStartItem(this, pItemG);
				}

				this->m_ItemManager.Add2UsingTimeLimitedItemList(pItemG);

#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN				// 2013-02-28 by bckim, 복귀유져 버프추가
				if( pItemG->ItemInfo->IsExistDesParam(DES_BUFF_TO_RETURN_USER) )
				{
					m_character.bUsingReturnItem  = TRUE;	// 안해줘도  되는데 ..
					this->SendCharacterOtherInfo( m_character.ClientIndex, TRUE );
				}
#endif

				continue;
			}

			this->m_ItemManager.m_mapItemGeneral.insertLock(pItemG->UniqueNumber, pItemG);
			// 2013-06-25 by jhseol, 아이템 UID '0' 추적용 디버깅 로그
#ifdef S_ITEMUID_ZERO_DEBUG_LOG_JHSEOL
			if (IS_COUNTABLE_ITEM(pItemG->Kind))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DEBUG] SPI ItemUID Zero : CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB - CUID(%d), ItemNum(%d), Count(%d), ItemUID(%d)\r\n"
					, this->m_character.CharacterUniqueNumber, pItemG->ItemNum, pItemG->CurrentCount, pItemG->UniqueNumber);
			}
#endif
			// end 2013-06-25 by jhseol, 아이템 UID '0' 추적용 디버깅 로그
			this->m_ItemManager.SetDelayStoredItemCounts(pItemG);
			if(TRUE == g_pFieldGlobal->IsArenaServer()) {
				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가, 인피 시작시 아이템 로그
				CAtumLogSender::SendLogMessageInfinityStartItem(this, pItemG);
			}

			if(WEAR_ATTACHED == pItemG->Wear)
			{
				BOOL bWearValid = this->CheckItemWindowPosition(pItemG->ItemWindowIndex, pItemG->ItemInfo);
				if (bWearValid)
				{
					bWearValid = this->AttachItem(pItemG->ItemWindowIndex, pItemG, TRUE);
				}
				
				if(FALSE == bWearValid)
				{
					// 장착 정보가 유효하지 않으므로 초기화
					pItemG->Wear				= WEAR_NOT_ATTACHED;
					pItemG->ItemWindowIndex		= POS_INVALID_POSITION;
				}

				// 2010-04-02 by cmkwon, 인피2차 추가 수정 - 
				//g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity] %s WEAR_ATTACHED %s, MainSvrItemUID(%I64d) WearValid(%d) \r\n"
				//	, GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemG, string()), pItemG->MainSvrItemUID, bWearValid);
			}
		}
		i_pvectItemGPtrList->clear();
	}

	m_ItemManager.CalcInventoryHiddenItemCounts();		// start 2011-10-21 by hskim, 파트너 시스템 2차 - 현재 가지고 있는 숨겨진 아이템 (POS_HIDDEN_ITEM) 갯수 갱신

	///////////////////////////////////////////////////////////////////////////////
	// 2007-01-29 by cmkwon, 2. 인챈트 추가
	mt_auto_lock enlock(&m_mapEnchant);
	m_mapEnchant.clear();
	int nEnchantCnt		= i_pvectEnchantList->size();
	if(0 < nEnchantCnt)
	{
		for(int i=0; i < nEnchantCnt; i++)
		{
			ENCHANT *pEnchant		= &(*i_pvectEnchantList)[i];
			ITEM_GENERAL *pItemG	= m_ItemManager.GetItemGeneralByUID(pEnchant->TargetItemUniqueNumber, ITEM_IN_CHARACTER);
			if(NULL == pItemG)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] %s Enchant: TargetItemUID(%I64d) TargetItemNum(%d), EnchantItemNum(%d)\r\n"
					, GetCharacterString(GetCharacter(), string()), pEnchant->TargetItemUniqueNumber, pEnchant->TargetItemNum, pEnchant->EnchantItemNum);
				continue;
			}
			///////////////////////////////////////////////////////////////////////////////
			// 2007-01-30 by cmkwon, 인챈트 추가
			this->InsertEnchantToItem(pItemG, *pEnchant);
		}
		i_pvectEnchantList->clear();
	}// END - if(0 < nEnchantCnt)


	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, 3. 아이템과 인챈트 클라이언트로 전송
	SendCharacterItemList();		// 2007-12-26 by dhjin, 정보 클라이언트로 전송 - 인벤토리 아이템

	enlock.auto_unlock_cancel();	// 2007-12-26 by cmkwon, 인챈트 lock 해제

	///////////////////////////////////////////////////////////////////////////////
	// 2007-03-29 by cmkwon, 4. 중복 countable item 정리
	this->m_ItemManager.RearrangeCountableItems(ITEM_IN_CHARACTER);

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-12-26 by cmkwon, 5. Skill 추가
	int nSkillCnt		= i_pvectItemSkillPtrList->size();
	if(0 < nSkillCnt)
	{
		for(int i=0; i < nSkillCnt; i++)
		{
			ITEM_SKILL *pItemSkill = (*i_pvectItemSkillPtrList)[i];

			///////////////////////////////////////////////////////////////////////////////
			// 2007-01-29 by cmkwon, 
			if(FALSE == this->m_ItemManager.InsertItemSkillByPointer(pItemSkill->UniqueNumber, pItemSkill))
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-23 by cmkwon, 아이템 복사 버그 체크 추가
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertItemSkillByPointer error !!, CharInfo(%s) SkillItemInfo(%s)\r\n"
					, GetCharacterString(GetCharacter(), string()), GetItemSkillString(pItemSkill, string()));
				SAFE_DELETE(pItemSkill);
			}
		}
		i_pvectItemSkillPtrList->clear();
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, 6. 스킬 클라이언트로 전송
	SendSkillItemList();

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, 7. 캐릭터 아이템 관련 초기화
	InitCharacterInventoryItem();
	// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - InitRenderInfo()로 함수명 변경
	//UpdateRenderInfo();
	InitRenderInfo();

	//////////////////////////////////////////////////////////////////////////
	// 2008-01-09 by dhjin, 아레나 통합 -
	if(g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버이면 아레나 전용 아이템 지급
		this->ms_pFieldIOCP->m_ArenaManager.ArenaItemSupply(this, this->m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex);
	}	

	igLock.auto_unlock_cancel();		// 2007-12-26 by cmkwon, lock 해제
	
	
	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-26 by cmkwon, 8. 퀘스트 클라이언트로 전송
	//////////////////////////////////////////////////////////////////////////
	// 2008-01-09 by dhjin, 아레나 통합 -
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버가 아니면 퀘스트 전송
		this->SendQuestList();
	 	////////////////////////////////////////////////////////////////////////////////	
		// 2007-07-23 by dhjin, 이벤트 기간안에 회원 가입한 유저에게 지급하는 이벤트 아이템 체크 추가
		// 2008-02-11 by cmkwon, 아이템이 로딩이 완료 된 후에 처리 해야하는 것임 - CFieldIOCPSocket::InsertItemListByCharacterFirstGameStartFromDB() 로 위치 이동
		vectItemEventInfo		vectItemEventInfo0;

		// start 2011-08-25 by shcho, 횟수별 아이템 지급기능 구현 - 0인경우 사용안함으로 처리. 2값일 경우, 하루에 한번 기한까지 2번 접속해야 지급
		// 먼저 체크를 한다. 최초 접속시에 한번 입력해야한다.
		int Logincount = 0;
		Logincount = ms_pFieldIOCP->m_pFieldODBC->CheckLoginEventDBData(m_character.AccountUniqueNumber);	// 이벤트 넘버는 1번으로 디폴트로 정해져 있음
		// end 2011-08-25 by shcho, 횟수별 아이템 지급기능 구현 - 0인경우 사용안함으로 처리. 2값일 경우, 하루에 한번 기한까지 2번 접속해야 지급

		// 2010-06-16 by jskim, 레벨별 이벤트 체크 기능 -
		//ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemGameStart(&vectItemEventInfo0, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, m_character.InfluenceType, m_character.UnitKind, &m_AccountRegisteredDate, &m_atimeLastGameEndDate);
		// 2011-08-25 by shcho, 횟수별 아이템 지급기능 구현
		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemGameStart(&vectItemEventInfo0, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, m_character.InfluenceType, m_character.UnitKind, &m_AccountRegisteredDate, &m_atimeLastGameEndDate, m_character.Level, m_character.AccountUniqueNumber, Logincount, m_nChannelingNum);		// 2014-02-10 by jhseol&bckim, 체널링 ( m_nChannelingNum 추가)
		// end 2011-08-25 by shcho, 횟수별 아이템 지급기능 구현
		//end 2010-06-16 by jskim, 레벨별 이벤트 체크 기능 -
		for (int i=0; i < vectItemEventInfo0.size(); i++)
		{
			// 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경
			if ( FALSE == ms_pFieldIOCP->ItemEventSubTypeCheck(m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, vectItemEventInfo0[i]) )
			{
				continue;
			}
			// end 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경

			QPARAM_CHECK_EVENTITEM *pQParam = new QPARAM_CHECK_EVENTITEM;
			pQParam->AccountUID		= m_character.AccountUniqueNumber;
			pQParam->ItemEventUID	= vectItemEventInfo0[i].ItemEventUID;
			pQParam->ItemEventType  = vectItemEventInfo0[i].ItemEventType;
			pQParam->ItemNum		= vectItemEventInfo0[i].ItemNum;
			pQParam->Count			= vectItemEventInfo0[i].Count;
			pQParam->PrefixCodeNum	= vectItemEventInfo0[i].PrefixCodeNum;
			pQParam->SuffixCodeNum	= vectItemEventInfo0[i].SuffixCodeNum;
			pQParam->CharacterUID	= m_character.CharacterUniqueNumber; // 2014-03-12 by jekim, 주민번호당 아이템 지급	// 2009-11-19 by cmkwon, 아이템 이벤트에 Account/Character 체크 기능 추가 - 
			pQParam->CheckWithCharacterUID = vectItemEventInfo0[i].CheckWithCharacterUID; // 2014-03-12 by jekim, 주민번호당 아이템 지급
			pQParam->UseFixedPeriod	= vectItemEventInfo0[i].UseFixedPeriod;			// 2013-02-28 by bckim, 복귀유져 버프추가
			pQParam->FixedPeriod_DAY= vectItemEventInfo0[i].FixedPeriod_DAY;		// 2013-02-28 by bckim, 복귀유져 버프추가

			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckEventItem, this, m_character.AccountUniqueNumber, pQParam);
		}
	}
	
	return TRUE;
}

// 2013-05-22 by jhseol, 소스정리 - 주석삭제

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendCharacterItemList()
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendCharacterItemList()
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));			// lock m_mapItemGeneral, @InsertItemListFromDB

	int nItemCnt		= m_ItemManager.m_mapItemGeneral.size();
	int nTotalSend		= 0;
	int nSendCnt		= 0;
	
	INIT_MSG_WITH_BUFFER(MSG_FC_STORE_PUT_ITEM_HEADER, T_FC_STORE_PUT_ITEM_HEADER, pSPutHeader, SendBuf);
	pSPutHeader->PossessCharacter	= this->m_character.CharacterUniqueNumber;
	pSPutHeader->ItemStorage0		= ITEM_IN_CHARACTER;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_PUT_ITEM_HEADER));

	INIT_MSG(MSG_FC_STORE_INSERT_ITEM, T_FC_STORE_INSERT_ITEM, pSInsertItem, SendBuf);
	mtmapUID2ItemGeneral::iterator itr = m_ItemManager.m_mapItemGeneral.begin();
	for(; m_ItemManager.m_mapItemGeneral.end() != itr; itr++)
	{
		ITEM_GENERAL *pItemG = itr->second;

		pSInsertItem->FromCharacterUniqueNumber		= m_character.CharacterUniqueNumber;
		pSInsertItem->ItemInsertionType				= IUT_LOADING;
		pSInsertItem->ItemGeneral					= *pItemG;
		nSendCnt++;
		nTotalSend++;

		if((nSendCnt+1)*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) > SIZE_MAX_PACKET)
		{
			this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_STORE_INSERT_ITEM));
			nSendCnt		= 0;
			MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM)) ) = T_FC_STORE_INSERT_ITEM;
			pSInsertItem	= (MSG_FC_STORE_INSERT_ITEM*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) + SIZE_FIELD_TYPE_HEADER);
		}
		else
		{
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM)) ) = T_FC_STORE_INSERT_ITEM;
			pSInsertItem	= (MSG_FC_STORE_INSERT_ITEM*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) + SIZE_FIELD_TYPE_HEADER);
		}
	}

	if(0 < nSendCnt)
	{
		this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_STORE_INSERT_ITEM));
		nSendCnt		= 0;
	}

	INIT_MSG(MSG_FC_STORE_PUT_ITEM_DONE, T_FC_STORE_PUT_ITEM_DONE, pSPutItemDone, SendBuf);
	pSPutItemDone->NumOfItem		= nTotalSend;
	pSPutItemDone->ItemStorage0		= ITEM_IN_CHARACTER;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_PUT_ITEM_DONE));

	//////////////////////////////////////////////////////////////////////////
	//	인첸트 정보 전송
	this->SendAddMessageType(T_FC_ITEM_PUT_ENCHANT_HEADER);

	m_mapEnchant.lock();

	mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.begin();
	for(; itrEnchantList != m_mapEnchant.end(); itrEnchantList++)
	{
		// 2008-01-10 by cmkwon, 버그 수정 - pSPutEnchant 초기화가 빠진것이 원인 이었음, 여기에서 초기화 하는 것으로 수정
		INIT_MSG(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pSPutEnchant, SendBuf);
		vectENCHANT::iterator itrVEnchant = itrEnchantList->second.begin();
		for(; itrVEnchant != itrEnchantList->second.end(); itrVEnchant++)
		{
			ITEM_GENERAL *pItemG	= m_ItemManager.GetItemGeneralByUID((*itrVEnchant).TargetItemUniqueNumber, ITEM_IN_CHARACTER);
			if(NULL == pItemG)
			{
				break;
			}
			pSPutEnchant->Enchant	= *itrVEnchant;
			nSendCnt++;
			nTotalSend++;

			if((nSendCnt+1)*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) > SIZE_MAX_PACKET)
			{
				this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));
				nSendCnt		= 0;
				MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
				*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT)) ) = T_FC_ITEM_PUT_ENCHANT;
				pSPutEnchant	= (MSG_FC_ITEM_PUT_ENCHANT*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) + SIZE_FIELD_TYPE_HEADER);
			}
			else
			{
				*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT)) ) = T_FC_ITEM_PUT_ENCHANT;
				pSPutEnchant	= (MSG_FC_ITEM_PUT_ENCHANT*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) + SIZE_FIELD_TYPE_HEADER);
			}
		}
		if(0 < nSendCnt)
		{
			this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));
			nSendCnt		= 0;
		}
	}
	this->SendAddMessageType(T_FC_ITEM_PUT_ENCHANT_DONE);

	// unlock
	m_mapEnchant.unlock();

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - arena 서버에서 main 서버 복귀시 타이머 재전송
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - arena 서버에서 main 서버 복귀시 타이머 재전송
	mtmapUID2ItemGeneral::iterator itr2 = m_ItemManager.m_mapItemGeneral.begin();
	for(; m_ItemManager.m_mapItemGeneral.end() != itr2; itr2++)
	{
		ITEM_GENERAL *pItemG = itr2->second;
		if ( TRUE == pItemG->FixedTermShape.bActive && IS_ENABLE_CHANGE_ShapeItemNum(pItemG->Kind) )
		{
			INT nCalcMin = 0;
			ATUM_DATE_TIME CurrentDate(TRUE);
			
			nCalcMin = pItemG->FixedTermShape.EndDate.GetTimeDiffTimeInMinutes(CurrentDate);
			pItemG->FixedTermShape.TimerUID = this->m_TimerManager.StartTimerField(TE_TYPE_FIXED_TERM_SHAPE, max(nCalcMin, 0) * TIMER_DO_MINUTELY_WORK, 0, 0);
		}
	}

	m_ArmorCollection.SendCollectionInfoAllData();
	// 2013-04-18 by jhseol,bckim 이달의 아머 - 컬렉션의 이달의 아머 이벤트 정보도 재전송
	#ifdef S_MONTHL_ARMOR_EVENT_JHSEOL_BCKIM	// - 컬렉션의 이달의 아머 이벤트 정보도 재전송
	if ( NULL != ms_pFieldIOCP && NULL != ms_pFieldIOCP->m_pMonthlyArmorManager)
	{
		ms_pFieldIOCP->m_pMonthlyArmorManager->SendMonthlyArmorEventAllCollectionList(this);
	}
	#endif
	// end 2013-04-18 by jhseol,bckim 이달의 아머 - 컬렉션의 이달의 아머 이벤트 정보도 재전송
#endif
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - arena 서버에서 main 서버 복귀시 타이머 재전송

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertStoreItemListFromDB(vectITEM_GENERALPtr *i_pvectItemGPtrList, vectENCHANT *i_pvectEnchantList, UID32_t i_possessCharacterUID, vecPetCurrentInfo *i_vectPetCurInfo)
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
///				// 2008-01-10 by cmkwon, 개인 창고 버그 수정 - CFieldIOCPSocket::InsertStoreItemListFromDB() 에 인자 추가
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertStoreItemListFromDB(vectITEM_GENERALPtr *i_pvectItemGPtrList, vectENCHANT *i_pvectEnchantList, UID32_t i_possessCharacterUID, vecPetCurrentInfo *i_vectPetCurInfo)		// 2012-01-14 by hskim, 파트너 시스템 2차 - 창고에서 꺼낼 때 클라 튕기는 문제 수정
{
	if(FALSE == this->IsValidCharacter(FALSE)){				return FALSE;}

	// start 2012-01-14 by hskim, 파트너 시스템 2차 - 창고에서 꺼낼 때 클라 튕기는 문제 수정
	if( NULL != i_vectPetCurInfo )
	{
		mt_auto_lock vtlock(&this->m_ItemManager.m_vectPetCurrentInfo);

		vecPetCurrentInfo::iterator itr(i_vectPetCurInfo->begin());
		while(itr != i_vectPetCurInfo->end())
		{
			tPET_CURRENTINFO *pCurrentInfo = *itr;
			if( TRUE == this->m_ItemManager.InsertItemPetByPointer(pCurrentInfo) )
			{
				itr = i_vectPetCurInfo->erase(itr);
				continue;
			}

			itr++;
		}

		vtlock.auto_unlock_cancel();

		SendPetItemList();
	}
	// end 2012-01-14 by hskim, 파트너 시스템 2차 - 창고에서 꺼낼 때 클라 튕기는 문제 수정

	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));			// lock m_mapItemGeneral, @InsertItemListFromDB
	m_ItemManager.ResetAllItemGeneralsInStore();
	m_ItemManager.m_uid32StoreCharacterUID = i_possessCharacterUID;		// 2008-01-10 by cmkwon, 개인 창고 버그 수정 - 해당 CharacterUID 로 설정해야 한다.

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-27 by cmkwon, 1. 창고 아이템 추가
	int nItemCnt		= i_pvectItemGPtrList->size();
	if(0 < nItemCnt)
	{
		for(int i=0; i < nItemCnt; i++)
		{
			ITEM_GENERAL *pItemG = (*i_pvectItemGPtrList)[i];
			if(FALSE == this->m_ItemManager.InsertStoreItemByPointer(pItemG->UniqueNumber, pItemG))
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-23 by cmkwon, 아이템 복사 버그 체크 추가
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertStoreItemByPointer error !!, CharInfo(%s), StoreCharacterUID(%d), ItemInfo(%s) ItemPossess(%d)\r\n"
					, GetCharacterString(GetCharacter(), string()), m_ItemManager.m_uid32StoreCharacterUID 
					, GetItemGeneralString(pItemG, string()), pItemG->Possess);
				SAFE_DELETE(pItemG);
			}
		}
		i_pvectItemGPtrList->clear();

	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-27 by cmkwon, 2. countable item 중복 정리
	this->m_ItemManager.RearrangeCountableItems(ITEM_IN_STORE);

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-27 by cmkwon, 3. 창고 아이템의 인챈트 처리
	int nEnchantCnt		= i_pvectEnchantList->size();
	if(0 < nEnchantCnt)
	{
		mt_auto_lock enlock(&m_mapEnchant);			// 2007-12-27 by cmkwon, 추가함
		for(int i=0; i < nEnchantCnt; i++)
		{
			ENCHANT *pEnchant		= &(*i_pvectEnchantList)[i];
			ITEM_GENERAL *pItemG	= m_ItemManager.GetItemGeneralByUID(pEnchant->TargetItemUniqueNumber, ITEM_IN_STORE);
			if(NULL == pItemG)
			{
				g_pGlobalGameServer->WriteSystemLogEX(TRUE, "[Error] Enchant error !! , %s TargetItemUID(%I64d) TargetItemNum(%d), EnchantItemNum(%d)\r\n",
					GetCharacterString(&m_character, string()),	pEnchant->TargetItemUniqueNumber, pEnchant->TargetItemNum, pEnchant->EnchantItemNum);
				continue;
			}
			///////////////////////////////////////////////////////////////////////////////
			// 2007-01-30 by cmkwon, 인챈트 추가
			this->InsertEnchantToItem(pItemG, *pEnchant);
		}
		i_pvectEnchantList->clear();
	}// END - if(0 < nEnchantCnt)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-20 by cmkwon, 창고 개수관련 오류 수정 - 창고에 SPI 아이템이 없다면 0원으로 추가를 한다.
	if(NULL == m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER, ITEM_IN_STORE))
	{
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-12-27 by cmkwon, 4. 클라이언트로 전송하기
	this->SendStoreItemList();			// 2007-12-26 by cmkwon, 위치 옮김
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendStoreItemList()
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendStoreItemList()
{
	// 2009-10-30 by cmkwon, 창고 아이템 가져오기 관련 버그 수정 - lock을 잘 못 잡았음, 아래와 같이 m_ItemManager.m_mapItemGeneral로 처리 해야 함.
	//mt_auto_lock igLock(&(m_ItemManager.m_mapItemInStore));			// lock m_mapItemGeneral, @InsertItemListFromDB
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));			// lock m_mapItemGeneral, @InsertItemListFromDB

	int nItemCnt		= m_ItemManager.m_mapItemInStore.size();
	int nTotalSend		= 0;
	int nSendCnt		= 0;
	
	INIT_MSG_WITH_BUFFER(MSG_FC_STORE_PUT_ITEM_HEADER, T_FC_STORE_PUT_ITEM_HEADER, pSPutHeader, SendBuf);
	pSPutHeader->PossessCharacter	= this->m_character.CharacterUniqueNumber;
	pSPutHeader->ItemStorage0		= ITEM_IN_STORE;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_PUT_ITEM_HEADER));

	INIT_MSG(MSG_FC_STORE_INSERT_ITEM, T_FC_STORE_INSERT_ITEM, pSInsertItem, SendBuf);
	mtmapUID2ItemGeneral::iterator itr = m_ItemManager.m_mapItemInStore.begin();
	for(; m_ItemManager.m_mapItemInStore.end() != itr; itr++)
	{

		ITEM_GENERAL *pItemG = itr->second;

		pSInsertItem->FromCharacterUniqueNumber		= m_character.CharacterUniqueNumber;
		pSInsertItem->ItemInsertionType				= IUT_LOADING;
		pSInsertItem->ItemGeneral					= *pItemG;
		nSendCnt++;
		nTotalSend++;

		if((nSendCnt+1)*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) > SIZE_MAX_PACKET)
		{
			this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_STORE_INSERT_ITEM));
			nSendCnt		= 0;
			MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM)) ) = T_FC_STORE_INSERT_ITEM;
			pSInsertItem	= (MSG_FC_STORE_INSERT_ITEM*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) + SIZE_FIELD_TYPE_HEADER);
		}
		else
		{
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM)) ) = T_FC_STORE_INSERT_ITEM;
			pSInsertItem	= (MSG_FC_STORE_INSERT_ITEM*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_STORE_INSERT_ITEM) + SIZE_FIELD_TYPE_HEADER);
		}
	}// END - for(int i=0; i < nItemCnt; i++)

	if(0 < nSendCnt)
	{
		this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_STORE_INSERT_ITEM));
		nSendCnt		= 0;
	}

	INIT_MSG(MSG_FC_STORE_PUT_ITEM_DONE, T_FC_STORE_PUT_ITEM_DONE, pSPutItemDone, SendBuf);
	pSPutItemDone->NumOfItem		= nTotalSend;
	pSPutItemDone->ItemStorage0		= ITEM_IN_STORE;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_PUT_ITEM_DONE));

	//////////////////////////////////////////////////////////////////////////
	//	인첸트 정보 전송
	
	mt_auto_lock enlock(&m_mapEnchant);			// 2007-12-27 by cmkwon, 수정
	mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.begin();
	for(; itrEnchantList != m_mapEnchant.end(); itrEnchantList++)
	{
		// 2008-01-10 by cmkwon, 버그 수정 - pSPutEnchant 초기화가 빠진것이 원인 이었음, 여기에서 초기화 하는 것으로 수정
		INIT_MSG(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pSPutEnchant, SendBuf);
		vectENCHANT::iterator itrVEnchant = itrEnchantList->second.begin();
		for(; itrVEnchant != itrEnchantList->second.end(); itrVEnchant++)
		{
			ITEM_GENERAL *pItemG	= m_ItemManager.GetItemGeneralByUID((*itrVEnchant).TargetItemUniqueNumber, ITEM_IN_STORE);
			if(NULL == pItemG)
			{
				break;
			}

			pSPutEnchant->Enchant	= *itrVEnchant;
			nSendCnt++;
			nTotalSend++;

			if((nSendCnt+1)*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) > SIZE_MAX_PACKET)
			{
				this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));
				nSendCnt		= 0;
				MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
				*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT)) ) = T_FC_ITEM_PUT_ENCHANT;
				pSPutEnchant	= (MSG_FC_ITEM_PUT_ENCHANT*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) + SIZE_FIELD_TYPE_HEADER);
			}
			else
			{
				*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT)) ) = T_FC_ITEM_PUT_ENCHANT;
				pSPutEnchant	= (MSG_FC_ITEM_PUT_ENCHANT*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT) + SIZE_FIELD_TYPE_HEADER);
			}
		}
		if(0 < nSendCnt)
		{
			this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));
			nSendCnt		= 0;
		}
	}
	enlock.auto_unlock_cancel();	// unlock

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertSkillListFromDB(vectItemSkillPtr *i_pvectItemSkillPtrList)
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertSkillListFromDB(vectItemSkillPtr *i_pvectItemSkillPtrList)
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));

	int nSkillCnt		= i_pvectItemSkillPtrList->size();
	if(0 >= nSkillCnt)
	{
		return FALSE;
	}

	for(int i=0; i < nSkillCnt; i++)
	{
		ITEM_SKILL *pItemSkill = (*i_pvectItemSkillPtrList)[i];

		///////////////////////////////////////////////////////////////////////////////
		// 2007-01-29 by cmkwon, 
		if(FALSE == this->m_ItemManager.InsertItemSkillByPointer(pItemSkill->UniqueNumber, pItemSkill))
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2008-07-23 by cmkwon, 아이템 복사 버그 체크 추가
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertItemSkillByPointer error !!, CharInfo(%s) SkillItemInfo(%s)\r\n"
				, GetCharacterString(GetCharacter(), string()), GetItemSkillString(pItemSkill, string()));
			SAFE_DELETE(pItemSkill);
		}
	}

	i_pvectItemSkillPtrList->clear();

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendSkillItemList()
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendSkillItemList()
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));
	
	int nTotalSend			= 0;
	int nSendCnt			= 0;

	this->SendAddMessageType(T_FC_SKILL_SETUP_SKILL_OK_HEADER);
	INIT_MSG_WITH_BUFFER(MSG_FC_SKILL_SETUP_SKILL_OK, T_FC_SKILL_SETUP_SKILL_OK, pSSetupSkillOK, SendBuf);

	vectItemSkillPtr::iterator itr = m_ItemManager.m_vectItemSkillPtr.begin();
	while (itr != m_ItemManager.m_vectItemSkillPtr.end())
	{
		pSSetupSkillOK->ItemUpdateType	= IUT_LOADING;
		pSSetupSkillOK->ItemSkill		= **itr;
		nSendCnt++;
		nTotalSend++;

		if((nSendCnt+1)*MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK) > SIZE_MAX_PACKET)
		{
			this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK));
			nSendCnt		= 0;
			MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK)) ) = T_FC_SKILL_SETUP_SKILL_OK;
			pSSetupSkillOK	= (MSG_FC_SKILL_SETUP_SKILL_OK*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK) + SIZE_FIELD_TYPE_HEADER);
		}
		else
		{
			*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK)) ) = T_FC_SKILL_SETUP_SKILL_OK;
			pSSetupSkillOK	= (MSG_FC_SKILL_SETUP_SKILL_OK*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK) + SIZE_FIELD_TYPE_HEADER);
		}
		itr++;
	}

	if(0 < nSendCnt)
	{
		this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_SKILL_SETUP_SKILL_OK));
		nSendCnt		= 0;
	}
	this->SendAddMessageType(T_FC_SKILL_SETUP_SKILL_OK_DONE);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			 void CFieldIOCPSocket::SendPetItemList()
/// \brief		// 2010-06-15 by shcho&hslee 펫시스템 - 클라이언트 패킷 전송 함수 추가 
/// \author		shcho&hslee
/// \date		2010-07-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendPetItemList()
{
	
	// IOCP소켓에 Itemmanager가 가지고 있는 개인 펫 정보
	mt_auto_lock igLock(&(m_ItemManager.m_vectPetCurrentInfo));
	
	int nTotalSend			= 0;
	int nSendCnt			= 0;
	
	this->SendAddMessageType(T_FC_ITEM_PET_HEADER);

	const tPET_CURRENTINFO *a_pPetCurInfo = NULL;
	
	// 펫 기본 수치 정보 전송.
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_PET_BASEDATA, T_FC_ITEM_PET_BASEDATA_OK, pSSetupPetItemOK, SendBuf_PetBase);

	mtvectPetCurrentInfo::iterator itr = m_ItemManager.m_vectPetCurrentInfo.begin();

	while ( itr != m_ItemManager.m_vectPetCurrentInfo.end() )
	{
		///////////////////////////////////////////////////////////////////////////////////////
		// start 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
		//
		// 기존 
		//

// 		a_pPetCurInfo = (const tPET_CURRENTINFO *)(*itr);
// 
// 		pSSetupPetItemOK->ItemUpdateType = IUT_LOADING;
// 		
// 		pSSetupPetItemOK->CreatedPetUID = a_pPetCurInfo->CreatedPetUID;
// 		
// 		pSSetupPetItemOK->EnableEditPetName = a_pPetCurInfo->EnableEditPetName;
// 		pSSetupPetItemOK->EnableLevelUp = a_pPetCurInfo->EnableLevelUp;
// 		
// 		strcpy ( pSSetupPetItemOK->szPetName, a_pPetCurInfo->szPetName );
// 		
// 		pSSetupPetItemOK->PetIndex = a_pPetCurInfo->PetIndex;
// 		pSSetupPetItemOK->PetLevel = a_pPetCurInfo->PetLevel;
// 		
// 		pSSetupPetItemOK->PetExp = a_pPetCurInfo->PetExp;
// 		
// 		pSSetupPetItemOK->Stamina = a_pPetCurInfo->Stamina;
// 		
// 		pSSetupPetItemOK->SourceIndex_Field = a_pPetCurInfo->SourceIndex_Field;
// 		pSSetupPetItemOK->SourceIndex_City = a_pPetCurInfo->SourceIndex_City;
// 
// 
// 		for ( int i = 0 ; i < SIZE_MAX_PETSKILLITEM ; ++i )
// 		{
// 			if ( a_pPetCurInfo->pItem_PetSkill[i] )
// 				pSSetupPetItemOK->ItemIndex_PetSkill[i] = a_pPetCurInfo->pItem_PetSkill[i]->ItemNum;
// 		}

		/////////
		// 수정

		a_pPetCurInfo = (const tPET_CURRENTINFO *)(*itr);

		pSSetupPetItemOK->ItemUpdateType = IUT_LOADING;
		pSSetupPetItemOK->CreatedPetUID = a_pPetCurInfo->CreatedPetUID;
		strcpy ( pSSetupPetItemOK->PetName, a_pPetCurInfo->PetName );
		pSSetupPetItemOK->PetIndex = a_pPetCurInfo->PetIndex;
		pSSetupPetItemOK->PetLevel = a_pPetCurInfo->PetLevel;
		pSSetupPetItemOK->PetExp = a_pPetCurInfo->PetExp;
		pSSetupPetItemOK->PetExpRatio = a_pPetCurInfo->PetExpRatio;
		pSSetupPetItemOK->PetEnableSocketCount = a_pPetCurInfo->PetEnableSocketCount;

		memcpy(&pSSetupPetItemOK->PetSocketItemUID, &(a_pPetCurInfo->PetSocketItemUID), sizeof(pSSetupPetItemOK->PetSocketItemUID));
		memcpy(&pSSetupPetItemOK->PetKitHP, &(a_pPetCurInfo->PetKitHP), sizeof(pSSetupPetItemOK->PetKitHP));
		memcpy(&pSSetupPetItemOK->PetKitShield, &(a_pPetCurInfo->PetKitShield), sizeof(pSSetupPetItemOK->PetKitShield));
		memcpy(&pSSetupPetItemOK->PetKitSP, &(a_pPetCurInfo->PetKitSP), sizeof(pSSetupPetItemOK->PetKitSP));
		memcpy(&pSSetupPetItemOK->PetAutoSkill, &(a_pPetCurInfo->PetAutoSkill), sizeof(pSSetupPetItemOK->PetAutoSkill));

		// end 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
		///////////////////////////////////////////////////////////////////////////////////////
	
		nSendCnt++;
		nTotalSend++;

		if((nSendCnt+1)*MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA) > SIZE_MAX_PACKET)
		{
			this->SendAddData( SendBuf_PetBase,nSendCnt*MSG_SIZE( MSG_FC_ITEM_PET_BASEDATA ) );
			nSendCnt = 0;
			MEMSET_ZERO(SendBuf_PetBase,SIZE_MAX_PACKET);
			*( ( MessageType_t* ) ( SendBuf_PetBase + nSendCnt*MSG_SIZE( MSG_FC_ITEM_PET_BASEDATA ) ) ) = T_FC_ITEM_PET_BASEDATA_OK;
			pSSetupPetItemOK = (MSG_FC_ITEM_PET_BASEDATA*) ( SendBuf_PetBase + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA) + SIZE_FIELD_TYPE_HEADER );
		}
		else
		{
			*( (MessageType_t*)(SendBuf_PetBase + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA)) ) = T_FC_ITEM_PET_BASEDATA_OK;
			pSSetupPetItemOK = (MSG_FC_ITEM_PET_BASEDATA*) ( SendBuf_PetBase + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA) + SIZE_FIELD_TYPE_HEADER );
		}
		itr++;
	}
	
	if ( 0 < nSendCnt )
	{
		this->SendAddData(SendBuf_PetBase, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA));
		nSendCnt = 0;
	}
	//..

	// 펫 소켓 정보 전송.
// 	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_PET_SOCKETDATA, T_FC_ITEM_PET_SOCKETDATA_OK, pSSetupPetItem_SocketDataOK, SendBuf_Socket);
// 	
// 	itr = m_ItemManager.m_vectPetCurrentInfo.begin();
// 	
// 	while ( itr != m_ItemManager.m_vectPetCurrentInfo.end() )
// 	{
// 		a_pPetCurInfo = (const tPET_CURRENTINFO *)(*itr);
// 		
// 		int i = 0;
// 		
// 		for ( i = 0; i < SIZE_MAX_PETSOCKETITEM; ++i )
// 		{
// 			if ( a_pPetCurInfo->pItem_PetSocketItem[i] )
// 			{
// 				pSSetupPetItem_SocketDataOK->CreatePetUID = a_pPetCurInfo->CreatedPetUID;
// 				pSSetupPetItem_SocketDataOK->iSlotIndex = i;
// 				
// 				memcpy ( &pSSetupPetItem_SocketDataOK->sItem_PetSocket , a_pPetCurInfo->pItem_PetSocketItem[i] , sizeof( ITEM ) );
// 														
// 				
// 				nSendCnt++;
// 				nTotalSend++;
// 				
// 				if((nSendCnt+1)*MSG_SIZE(MSG_FC_ITEM_PET_SOCKETDATA) > SIZE_MAX_PACKET)
// 				{
// 					this->SendAddData( SendBuf_Socket,nSendCnt*MSG_SIZE( MSG_FC_ITEM_PET_SOCKETDATA ) );
// 					nSendCnt = 0;
// 					MEMSET_ZERO(SendBuf_Socket,SIZE_MAX_PACKET);
// 					*( ( MessageType_t* ) ( SendBuf_Socket + nSendCnt*MSG_SIZE( MSG_FC_ITEM_PET_SOCKETDATA ) ) ) = T_FC_ITEM_PET_SOCKETDATA_OK;
// 					pSSetupPetItem_SocketDataOK = (MSG_FC_ITEM_PET_SOCKETDATA*) ( SendBuf_Socket + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_SOCKETDATA) + SIZE_FIELD_TYPE_HEADER );
// 				}
// 				else
// 				{
// 					*( (MessageType_t*)(SendBuf_Socket + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_SOCKETDATA)) ) = T_FC_ITEM_PET_SOCKETDATA_OK;
// 					pSSetupPetItem_SocketDataOK = (MSG_FC_ITEM_PET_SOCKETDATA*) ( SendBuf_Socket + nSendCnt*MSG_SIZE(MSG_FC_ITEM_PET_SOCKETDATA) + SIZE_FIELD_TYPE_HEADER );
// 				}
// 			}
// 		}
// 		
// 		itr++;
// 	}
// 	
// 	if ( 0 < nSendCnt )
// 	{
// 		this->SendAddData(SendBuf_Socket, nSendCnt * MSG_SIZE(MSG_FC_ITEM_PET_SOCKETDATA));
// 		nSendCnt = 0;
// 	}
	//..

	this->SendAddMessageType(T_FC_ITEM_PET_DONE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			 void CFieldIOCPSocket::SendInsertPetItemList()
/// \brief		// 2010-06-15 by shcho&hslee 펫시스템 - Item Insert 시에 클라이언트 패킷 전송 함수 추가 
/// \author		shcho&hslee
/// \date		2010-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendInsertPetItemInfo(BYTE ItemInsertiontype, tPET_CURRENTINFO* pcurrentPetInfo)
{
	const tPET_CURRENTINFO *a_pPetCurInfo = pcurrentPetInfo;
	
	// 펫 기본 수치 정보 전송.
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_PET_BASEDATA, T_FC_ITEM_PET_BASEDATA_OK, pSSetupPetItemOK, SendBuf_PetBase);

	///////////////////////////////////////////////////////////////////////////////////////
	// start 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
	//
	// 기존 
	//

// 	pSSetupPetItemOK->ItemUpdateType = IUT_LOADING;		
// 	pSSetupPetItemOK->CreatedPetUID = a_pPetCurInfo->CreatedPetUID;
// 	pSSetupPetItemOK->EnableEditPetName = a_pPetCurInfo->EnableEditPetName;
// 	pSSetupPetItemOK->EnableLevelUp = a_pPetCurInfo->EnableLevelUp;
// 	strcpy ( pSSetupPetItemOK->szPetName, a_pPetCurInfo->szPetName );
// 	pSSetupPetItemOK->PetIndex = a_pPetCurInfo->PetIndex;
// 	pSSetupPetItemOK->PetLevel = a_pPetCurInfo->PetLevel;
// 	pSSetupPetItemOK->PetExp = a_pPetCurInfo->PetExp;
// 	pSSetupPetItemOK->Stamina = a_pPetCurInfo->Stamina;
// 	pSSetupPetItemOK->SourceIndex_Field = a_pPetCurInfo->SourceIndex_Field;
// 	pSSetupPetItemOK->SourceIndex_City = a_pPetCurInfo->SourceIndex_City;
// 
// 	for ( int i = 0; i < SIZE_MAX_PETSKILLITEM; ++i )
// 	{
// 		if ( a_pPetCurInfo->pItem_PetSkill[i] )
// 			pSSetupPetItemOK->ItemIndex_PetSkill[i] = a_pPetCurInfo->pItem_PetSkill[i]->ItemNum;
// 		// 스킬이 없으면 0처리
// 		pSSetupPetItemOK->ItemIndex_PetSkill[i] = 0;
// 	}

	/////////
	// 수정

	pSSetupPetItemOK->ItemUpdateType = IUT_LOADING;		
	pSSetupPetItemOK->CreatedPetUID = a_pPetCurInfo->CreatedPetUID;
	strcpy(pSSetupPetItemOK->PetName, a_pPetCurInfo->PetName);
	pSSetupPetItemOK->PetIndex = a_pPetCurInfo->PetIndex;
	pSSetupPetItemOK->PetLevel = a_pPetCurInfo->PetLevel;
	pSSetupPetItemOK->PetExp = a_pPetCurInfo->PetExp;
	pSSetupPetItemOK->PetExpRatio = a_pPetCurInfo->PetExpRatio;
	pSSetupPetItemOK->PetEnableSocketCount = a_pPetCurInfo->PetEnableSocketCount;

	memcpy(&pSSetupPetItemOK->PetSocketItemUID, &(a_pPetCurInfo->PetSocketItemUID), sizeof(pSSetupPetItemOK->PetSocketItemUID));
	memcpy(&pSSetupPetItemOK->PetKitHP, &(a_pPetCurInfo->PetKitHP), sizeof(pSSetupPetItemOK->PetKitHP));
	memcpy(&pSSetupPetItemOK->PetKitShield, &(a_pPetCurInfo->PetKitShield), sizeof(pSSetupPetItemOK->PetKitShield));
	memcpy(&pSSetupPetItemOK->PetKitSP, &(a_pPetCurInfo->PetKitSP), sizeof(pSSetupPetItemOK->PetKitSP));
	memcpy(&pSSetupPetItemOK->PetAutoSkill, &(a_pPetCurInfo->PetAutoSkill), sizeof(pSSetupPetItemOK->PetAutoSkill));

	// end 2011-08-17 by hskim, 파트너 시스템 2차 - 자료 구조 결정
	///////////////////////////////////////////////////////////////////////////////////////

	this->SendAddData(SendBuf_PetBase, MSG_SIZE(MSG_FC_ITEM_PET_BASEDATA));
}
///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendQuestList()
/// \brief		게임 시작 루틴 DB값 설정과 Client전송 부분 분리
/// \author		dhjin
/// \date		2007-12-14 ~ 2007-12-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendQuestList()
{
	mt_auto_lock mtA(&m_mapQuest);

	this->SendAddMessageType(T_FC_QUEST_PUT_ALL_QUEST_HEADER);
	///////////////////////////////////////////////////////////////////////////////
	// 2005-10-25 by cmkwon
	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_PUT_ALL_QUEST, T_FC_QUEST_PUT_ALL_QUEST, pPutAllQuest, SendBuf);
	pPutAllQuest->fVCNInflDistributionPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_VCN);	// 2006-02-08 by cmkwon
	pPutAllQuest->fANIInflDistributionPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_ANI);	// 2006-02-08 by cmkwon
	pPutAllQuest->NumOfQuest 					= 0;

	mtmapQuestIndex2FieldCharacterQuest::iterator cqitr(m_mapQuest.begin());
	for(; cqitr != m_mapQuest.end(); cqitr++)
	{
		CFieldCharacterQuest	*pFCharQuest = &cqitr->second;
		CQuest					*pQuestInfo = pFCharQuest->GetQuestInfo();

		if(MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST)+(pPutAllQuest->NumOfQuest+1)*sizeof(MEX_QUEST_INFO) >= SIZE_MAX_PACKET)
		{
			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST) + pPutAllQuest->NumOfQuest*sizeof(MEX_QUEST_INFO));
			pPutAllQuest->NumOfQuest		= 0;
		}

		MEX_QUEST_INFO *pQuest4Exch		= (MEX_QUEST_INFO*)(SendBuf + MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST) + pPutAllQuest->NumOfQuest*sizeof(MEX_QUEST_INFO));
		pQuest4Exch->QuestIndex			= pFCharQuest->QuestIndex;
		pQuest4Exch->QuestState			= pFCharQuest->QuestState;
		pQuest4Exch->QuestPlayTimeStamp	= pFCharQuest->QuestPlayTimeStamp;
		if(pQuestInfo->IsCityWar)
		{
			STRNCPY_MEMSET(pQuest4Exch->szCityWarServerGroupName, g_pFieldGlobal->GetServerGroupNameByMGameServerID(pFCharQuest->QuestParam1), SIZE_MAX_SERVER_NAME);
		}
		
		pPutAllQuest->NumOfQuest++;
	}
	if (pPutAllQuest->NumOfQuest > 0)
	{		
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST) + pPutAllQuest->NumOfQuest*sizeof(MEX_QUEST_INFO));
	}
	this->SendAddMessageType(T_FC_QUEST_PUT_ALL_QUEST_DONE);

	this->SendAddMessageType(T_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT_HEADER);
	///////////////////////////////////////////////////////////////////////////////
	// 2005-10-25 by cmkwon
	// 퀘스트 몬스터 카운트 정보를 전송한다.
	INIT_MSG(MSG_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT, T_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT, pSAllMonCount, SendBuf);
	pSAllMonCount->NumOfMonsterCount	= 0;

	cqitr = m_mapQuest.begin();
	for(; cqitr != m_mapQuest.end(); cqitr++)
	{
		CFieldCharacterQuest	*pFCharQuest = &cqitr->second;
		CQuest					*pQuestInfo = pFCharQuest->GetQuestInfo();
		if(pQuestInfo->TargetMonsterVector.empty()
			|| pFCharQuest->IsEmptyMonsterCount())
		{
			continue;
		}

		vectCharacterQuestMonsterCount::iterator	mcitr(pFCharQuest->m_vectQuestMonsterCount.begin());
		for(; mcitr != pFCharQuest->m_vectQuestMonsterCount.end(); mcitr++)
		{
			if(MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT)+(pSAllMonCount->NumOfMonsterCount+1)*sizeof(MEX_QUEST_MONSTER_COUNT) >= SIZE_MAX_PACKET)
			{
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT) + pSAllMonCount->NumOfMonsterCount*sizeof(MEX_QUEST_MONSTER_COUNT));
				pSAllMonCount->NumOfMonsterCount	= 0;
			}
			MEX_QUEST_MONSTER_COUNT *pMonCount4Exch = (MEX_QUEST_MONSTER_COUNT*)(SendBuf + MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT) + pSAllMonCount->NumOfMonsterCount*sizeof(MEX_QUEST_MONSTER_COUNT));
			pMonCount4Exch->QuestIndex			= pFCharQuest->QuestIndex;
			pMonCount4Exch->MonsterUniqueNumber	= mcitr->MonsterUniqueNumber;
			pMonCount4Exch->Count				= mcitr->Count;

			pSAllMonCount->NumOfMonsterCount++;
		}
	}
	if (pSAllMonCount->NumOfMonsterCount > 0)
	{		
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT) + pSAllMonCount->NumOfMonsterCount*sizeof(MEX_QUEST_MONSTER_COUNT));
	}
	this->SendAddMessageType(T_FC_QUEST_PUT_ALL_QUEST_MONSTER_COUNT_DONE);
	
}


float CFieldIOCPSocket::GetEnchantValue(ITEM *pTargetItem, BYTE desParam)
{
	float fRetValue = 0.0f;

	if(NULL == pTargetItem || 0 == pTargetItem->ItemNum){			return fRetValue;}
	ITEM_GENERAL	*pItemGeneral		= (ITEM_GENERAL*)pTargetItem->ItemNum;
	ITEM			*pItemInfoOriginal	= ms_pFieldIOCP->GetItemInfo(pItemGeneral->ItemNum);	// 원래 아이템 정보

	if (pItemGeneral->Wear == WEAR_NOT_ATTACHED)
	{
		return fRetValue;
	}

	m_mapEnchant.lock();
	{
		mtmapUID2EnchantVector::iterator itrEnchantList	= m_mapEnchant.find(pItemGeneral->UniqueNumber);
		if (m_mapEnchant.end() != itrEnchantList)
		{
			vectENCHANT &vecECH = itrEnchantList->second;

			for (int i = 0; i < vecECH.size(); i++)
			{
				ENCHANT &tmpEnchant = vecECH[i];
				ITEM *pEnchantItemInfo = ms_pFieldIOCP->GetItemInfo(tmpEnchant.EnchantItemNum);
				if (pEnchantItemInfo != NULL)
				{					
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 					if(desParam == pEnchantItemInfo->DestParameter1)
// 						fRetValue += pEnchantItemInfo->ParameterValue1;
// 					if(desParam == pEnchantItemInfo->DestParameter2)
// 						fRetValue += pEnchantItemInfo->ParameterValue2;
// 					if(desParam == pEnchantItemInfo->DestParameter3)
// 						fRetValue += pEnchantItemInfo->ParameterValue3;
// 					if(desParam == pEnchantItemInfo->DestParameter3)
// 						fRetValue += pEnchantItemInfo->ParameterValue3;
					if(pEnchantItemInfo->IsExistDesParam(desParam))
					{
						fRetValue += pEnchantItemInfo->GetParameterValue(desParam);
					}

				}
			}
		}
	}
	m_mapEnchant.unlock();

	return fRetValue;
}

// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
BOOL CFieldIOCPSocket::ApplyEnchant(ITEM_GENERAL *pTargetItemG)
{
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 	if (pTargetItem == NULL || pTargetItem->ItemNum == NULL) {				return FALSE; }
// 
// 	ITEM_GENERAL	*pItemGeneral		= (ITEM_GENERAL*)pTargetItem->ItemNum;
// 	ITEM			*pItemInfoOriginal	= ms_pFieldIOCP->GetItemInfo(pItemGeneral->ItemNum);	// 원래 아이템 정보
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	if(NULL == pTargetItemG){					return FALSE;}
 	ITEM_GENERAL	*pItemGeneral		= pTargetItemG;
 	ITEM			*pItemInfoOriginal	= pTargetItemG->ItemInfo;

	// lock
	m_mapEnchant.lock();
	{
//		pItemGeneral->DesWeight			= 0.0f;		// 2006-01-24 by cmkwon, 중량 인챈트 수치 초기화	// 2012-11-12 by khkim 이곳에 초기화시 무게 메모리핵 발생함 
		mtmapUID2EnchantVector::iterator itrEnchantList	= m_mapEnchant.find(pItemGeneral->UniqueNumber);
		if (m_mapEnchant.end() != itrEnchantList)
		{
			vectENCHANT &vecECH = itrEnchantList->second;

			for (int i = 0; i < vecECH.size(); i++)
			{
				ENCHANT &tmpEnchant = vecECH[i];
				ITEM *pEnchantItemInfo = ms_pFieldIOCP->GetItemInfo(tmpEnchant.EnchantItemNum);
				if (pEnchantItemInfo != NULL)
				{
					///////////////////////////////////////////////////////////////////////////////
					// 2006-01-24 by cmkwon, 아이템의 중량 인챈트 계산
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 					if(DES_WEIGHT_01 == pEnchantItemInfo->DestParameter1 || DES_WEIGHT_02 == pEnchantItemInfo->DestParameter1)
// 					{
// 						pItemGeneral->DesWeight		+= pEnchantItemInfo->ParameterValue1;
// 					}
// 					if(DES_WEIGHT_01 == pEnchantItemInfo->DestParameter2 || DES_WEIGHT_02 == pEnchantItemInfo->DestParameter2)
// 					{
// 						pItemGeneral->DesWeight		+= pEnchantItemInfo->ParameterValue2;
// 					}
// 					if(DES_WEIGHT_01 == pEnchantItemInfo->DestParameter3 || DES_WEIGHT_02 == pEnchantItemInfo->DestParameter3)
// 					{
// 						pItemGeneral->DesWeight		+= pEnchantItemInfo->ParameterValue3;
// 					}
// 					if(DES_WEIGHT_01 == pEnchantItemInfo->DestParameter4 || DES_WEIGHT_02 == pEnchantItemInfo->DestParameter4)
// 					{
// 						pItemGeneral->DesWeight		+= pEnchantItemInfo->ParameterValue4;
// 					}
					if(pEnchantItemInfo->IsExistDesParam(DES_WEIGHT_01))
					{
						pItemGeneral->DesWeight		+= pEnchantItemInfo->GetParameterValue(DES_WEIGHT_01);
					}
					if(pEnchantItemInfo->IsExistDesParam(DES_WEIGHT_02))
					{
						pItemGeneral->DesWeight		+= pEnchantItemInfo->GetParameterValue(DES_WEIGHT_02);
					}
					
					///////////////////////////////////////////////////////////////////////////////
					// 창착 아이템 ParamFactor 적용
					if (pItemGeneral->Wear == WEAR_ATTACHED)
					{

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 						SetParamFactor(pEnchantItemInfo->DestParameter1, pEnchantItemInfo->ParameterValue1);
// 						SetParamFactor(pEnchantItemInfo->DestParameter2, pEnchantItemInfo->ParameterValue2);
// 						SetParamFactor(pEnchantItemInfo->DestParameter3, pEnchantItemInfo->ParameterValue3);
// 						SetParamFactor(pEnchantItemInfo->DestParameter4, pEnchantItemInfo->ParameterValue4);
						for(int j=0; j < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; j++)
						{
							SetParamFactor(pEnchantItemInfo->ArrDestParameter[j], pEnchantItemInfo->ArrParameterValue[j]);
						}
					}

					///////////////////////////////////////////////////////////////////////////////
					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
					if(pEnchantItemInfo->InvokingDestParamID) {
						this->EnchantApplyInvokingItem(pItemGeneral, pEnchantItemInfo);
					}
				}
			}
		}
	}
	m_mapEnchant.unlock();

	return TRUE;
}

BOOL CFieldIOCPSocket::InsertEnchantToItem(ITEM_GENERAL *pTargetItem, ENCHANT &enchant)
{
	// lock
	m_mapEnchant.lock();

	mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(enchant.TargetItemUniqueNumber);
	if (m_mapEnchant.end() == itrEnchantList)
	{
		vectENCHANT v1;
		m_mapEnchant.insertLock(enchant.TargetItemUniqueNumber, v1);
		itrEnchantList = m_mapEnchant.find(enchant.TargetItemUniqueNumber);
	}

	vectENCHANT &tmpVector = itrEnchantList->second;
	if(0 == tmpVector.size())
	{
		tmpVector.reserve(SIZE_MAX_ENCHANT_PER_ITEM);
	}

	// 2009-10-30 by cmkwon, 창고 아이템 가져오기 관련 버그 수정 - CFieldIOCPSocket::InsertEnchantToItem#
	if(SIZE_MAX_ENCHANT_PER_ITEM <= tmpVector.size())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::InsertEnchantToItem enchang count over !! %s %s CurEnchantCount(%d) BuildingKind(%d) EnchangItemNum(%d) \r\n"
			, GetCharacterString(this->GetCharacter(), string()), GetItemGeneralString(pTargetItem, string()), tmpVector.size(), enchant.EnchantItemNum);

		m_mapEnchant.unlock();
		return FALSE;
	}
	
	tmpVector.push_back(enchant);

	// unlock
	m_mapEnchant.unlock();

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertEnchantToItem(ITEM_GENERAL *pTargetItem, vectENCHANT *i_pvectEnchant, BOOL bSendToClient/*=TRUE*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-05-11 ~ 2006-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertEnchantToItem(ITEM_GENERAL *pTargetItem, vectENCHANT *i_pvectEnchant, BOOL bSendToClient/*=TRUE*/)
{
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_PUT_ENCHANT, T_FC_ITEM_PUT_ENCHANT, pPutEnchant, SendBuf);
	mt_auto_lock mtA(&m_mapEnchant);			// 2006-12-18 by cmkwon, 버그 수정(m_mapTradeItem->m_mapEnchant)
	int nVectCnt = i_pvectEnchant->size();
	for(int i=0; i < nVectCnt; i++)
	{
		this->InsertEnchantToItem(pTargetItem, (*i_pvectEnchant)[i]);
		if(bSendToClient)
		{
			pPutEnchant->Enchant = (*i_pvectEnchant)[i];
			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_PUT_ENCHANT));
		}
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::DeleteAllEnchantToItem(UID64_t i_itemUID)
{
	// lock
	m_mapEnchant.lock();
	m_mapEnchant.erase(i_itemUID);
	m_mapEnchant.unlock();

	return TRUE;
}

void CFieldIOCPSocket::PrintEnchant(UID64_t ItemUniqueNumber, BOOL i_bWriteSystemLog)
{
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 사용하지 않음
// 	BitFlag8_t DO2Option = (DO2_DBGOUT | (i_bWriteSystemLog?DO2_SYSLOG:0));
// 
// 	// lock m_mapItemGeneral, @PrintEnchant
// 	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
// 
// 	// lock
// 	m_mapEnchant.lock();
// 
// 	mtmapUID2EnchantVector::iterator itrECH = m_mapEnchant.begin();
// 	while (itrECH != m_mapEnchant.end())
// 	{
// 		if (ItemUniqueNumber == 0 || ItemUniqueNumber == itrECH->first)
// 		{
// 			DBGOUT2(DO2Option, "  ENCHANT %s: ", GetItemString(m_ItemManager.GetItemGeneralByUID(itrECH->first), string()));
// 			vectENCHANT &vecECH = itrECH->second;
// 
// 			for (int ii = 0; ii < vecECH.size(); ii++)
// 			{
// 				ITEM *pEnchantItem = ms_pFieldIOCP->GetItemInfo(vecECH[ii].EnchantItemNum);
// 				if (pEnchantItem != NULL)
// 				{
// 					DBGOUT2(DO2Option, "%s(%d)", pEnchantItem->ItemName, pEnchantItem->ItemNum);
// 					DBGOUT2(DO2Option, "[%d(%3.2f) ", pEnchantItem->DestParameter1, pEnchantItem->ParameterValue1);
// 					DBGOUT2(DO2Option, "%d(%3.2f) ", pEnchantItem->DestParameter2, pEnchantItem->ParameterValue2);
// 					DBGOUT2(DO2Option, "%d(%3.2f) ", pEnchantItem->DestParameter3, pEnchantItem->ParameterValue3);
// 					DBGOUT2(DO2Option, "%d(%3.2f)] ", pEnchantItem->DestParameter4, pEnchantItem->ParameterValue4);
// 				}
// 			}
// 			DBGOUT2(DO2Option, "\r\n");
// 		}
// 
// 		itrECH++;
// 	}
// 
// 	// unlock
// 	m_mapEnchant.unlock();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::PopAllEnchantByItemUID(vectENCHANT *o_pvectEnchat, UID64_t i_itemUID)
/// \brief		
/// \author		cmkwon
/// \date		2006-05-11 ~ 2006-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::PopAllEnchantByItemUID(vectENCHANT *o_pvectEnchat, UID64_t i_itemUID)
{
	mt_auto_lock mtA(&m_mapEnchant);

	mtmapUID2EnchantVector::iterator itr = m_mapEnchant.find(i_itemUID);
	if (itr == m_mapEnchant.end())
	{
		return FALSE;
	}

	*o_pvectEnchat = itr->second;		
	
	m_mapEnchant.erase(i_itemUID);		// 제거한다.

	return TRUE;
}

// 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완
BOOL CFieldIOCPSocket::GetAllEnchantListByItemUID(vectENCHANT *o_pvectEnchat, UID64_t i_itemUID)
{
	//mt_auto_lock mtA(&m_mapEnchant);	// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - 함수 호출전 상위 루틴에서 lock을 걸어야 함.
	
	mtmapUID2EnchantVector::iterator itr = m_mapEnchant.find(i_itemUID);
	if (itr == m_mapEnchant.end())
	{
		return FALSE;
	}
	o_pvectEnchat->assign(itr->second.begin(), itr->second.end());		// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - 리스트를 복사하고
//	*o_pvectEnchat = itr->second;		// 2013-12-10 by jhseol, 베트남 서버다운 대응 lock 처리 - 주석처리
	return TRUE;
}
// End. 2013-07-01 by bckim, 10인챈트 미만 하이퍼카드처리, 로그추가, 운영툴 보완

///////////////////////////////////////////////////////////////////////////////
/// \fn			vectENCHANT *CFieldIOCPSocket::GetVectEnchantListPtr(UID64_t i_itemUID)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-27 ~ 2006-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
vectENCHANT *CFieldIOCPSocket::GetVectEnchantListPtr(UID64_t i_itemUID)
{
	mtmapUID2EnchantVector::iterator itr = m_mapEnchant.find(i_itemUID);
	if (itr == m_mapEnchant.end())
	{
		return NULL;
	}

	return &(itr->second);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
/// \author		cmkwon
/// \date		2010-03-05 ~ 2010-03-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ApplyDestParam8Enchant8RareOfAttachedItems(void)
{
	mt_auto_lock mta(&m_ItemManager.m_mapItemGeneral);

	for (int i = 0; i < SIZE_MAX_POS; i++)
	{
		ITEM_GENERAL *pItemG = GetAttachItemGeneralByPosition(i);
		if(NULL == pItemG)
		{
			continue;
		}

		// 1. 해당 아이템의 기본 DestParam을 적용, cpu는 스탯정보를 가지고 있음.
		if(pItemG->Kind != ITEMKIND_COMPUTER)
		{
			// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 외형 옵션 적용(스텟 제외)
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 외형 옵션 적용(스텟 제외)
			if ( ITEMKIND_DEFENSE == pItemG->Kind)
			{
				ITEM *pOptionItem = ms_pFieldIOCP->GetItemInfo(pItemG->FixedTermShape.nStatShapeItemNum);
				if ( NULL != pOptionItem )
				{
					for ( int i = 0 ; i < pItemG->FixedTermShape.nStatLevel ; i++ )
					{
						ApplyItemDesParam(pOptionItem);
					}
				}
			}
#endif
			// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 외형 옵션 적용(스텟 제외)

			// 2013-04-18 by jhseol,bckim 이달의 아머 - 장착 아이템 옵션 적용
#ifdef S_MONTHL_ARMOR_EVENT_JHSEOL_BCKIM		// 장착 아이템 옵션 적용
			if ( ITEMKIND_DEFENSE == pItemG->Kind)
			{
				// 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경
				ATUM_DATE_TIME CurTime(TRUE);
				if ( CurTime < pItemG->atMonthlyEventEndDate )	// 이달의 아머 이벤트 적용기간이 남아있을때만 옵션 적용
				{
					ITEM *pOptionItem = ms_pFieldIOCP->GetItemInfo(pItemG->nMonthlyOptionItemNum);
					if ( NULL != pOptionItem )
					{
						
#ifdef	SC_PREMIUM_COLLECTION_ARMOR_YMJOO_BCKIM	// 2014-07-17 by bckim, 프리미엄 아머 컬렉션
						if( pOptionItem->IsExistDesParam(DES_PREMIUM_OPTION_ITEM_DEFAULT_DESPARAM))
						{
							ApplyItemDesParamOnlyPremiumAmor(pOptionItem,pItemG->FixedTermShape.nStatLevel);
						}
						else
#endif		// End. 2014-07-17 by bckim, 프리미엄 아머 컬렉션	

#ifdef	SC_OLD_COLLECTION_ARMOR_SHCHOI // 2014-12-29 by shchoi 이달의 구 아머
						if( pOptionItem->IsExistDesParam(DES_OLD_OPTION_ITEM_DEFAULT_DESPARAM))
						{
							ApplyItemDesParamOnlyOldAmor(pOptionItem,pItemG->FixedTermShape.nStatLevel);
						}
							else
#endif // end 2014-12-24 by shchoi 이달의 구 아머
						{
						ApplyItemDesParam(pOptionItem);
						}
					}
				}
				// end 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경
			}
#endif
			// end 2013-04-18 by jhseol,bckim 이달의 아머 - 장착 아이템 옵션 적용
			ApplyItemDesParam(pItemG->ItemInfo);
		}

		// 2. 창착시 발동류 아이템 적용
		ApplyInvokingItem(pItemG);

		// 2.5 적용 (인첸트 / 레어) 옵션 초기화
		ItemOptionInitialization(pItemG);			// 2010-11-12 by khkim 메모리핵:14(무게) 로그 오류 수정

		// 3. 레어 적용
		if(IS_RARE_TARGET_ITEMKIND(pItemG->Kind))
		{
			ApplyRareFix(pItemG);
		}

		// 4. 인챈트 적용
		if(IS_ENCHANT_TARGET_ITEMKIND(pItemG->Kind))
		{
			ApplyEnchant(pItemG);
		}
	}
	return TRUE;
}

void CFieldIOCPSocket::ApplyRareItem(CFieldMonster *i_pMonster, MONSTER2ITEM *i_pMonster2Item
									 , float i_fPlusRateDropRareItem, CFieldIOCP *i_pFieldIOCP, ITEM_GENERAL *io_pItem)
{
	int i = 0;
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 -
	//if (FALSE == IS_WEAPON(io_pItem->Kind)
	if(FALSE == IS_RARE_TARGET_ITEMKIND(io_pItem->Kind)
		|| COMPARE_BIT_FLAG(io_pItem->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM|ITEM_ATTR_LEGEND_ITEM))
	{// 2007-08-22 by cmkwon, 레전드 아이템 - 체크 추가, // 2005-12-02 by cmkwon, 유니크 아이템 체크
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// i_fPlusRateDropRareItem는 Prefix,Suffix처리에 들어갈 확률에만 적용한다

	// Prefix 적용
	int prob = RAND100K();
	if (i_pMonster2Item->PrefixProbability > 0
		&& i_pMonster2Item->PrefixProbability > prob - i_pMonster2Item->PrefixProbability*i_fPlusRateDropRareItem)
	{		
		io_pItem->PrefixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, TRUE, RARE_ITEM_USE_TYPE_NORMAL);
	}

	// Suffix 적용
	prob = RAND100K();
	if (i_pMonster2Item->SuffixProbability > 0
		&& i_pMonster2Item->SuffixProbability > prob - i_pMonster2Item->SuffixProbability*i_fPlusRateDropRareItem)
	{
		io_pItem->SuffixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, FALSE, RARE_ITEM_USE_TYPE_NORMAL);
	}

// 2007-12-07 by cmkwon, 레어 시스템 수정 - 위와 같이 CFieldIOCP::GetRandomRareCode() 함수로 처리
//	// Prefix 적용
//	int prob = RAND100K();
//	if (i_pMonster2Item->PrefixProbability > 0
//		&& i_pMonster2Item->PrefixProbability > prob - i_pMonster2Item->PrefixProbability*i_fPlusRateDropRareItem)
//	{
////		DBGOUT("Monster: %s(%d), Item: %s, Pro(%d) > Rand(%d) \r\n",	i_pMonster->MonsterInfoPtr->MonsterName, i_pMonster->MonsterIndex
////			, io_pItem->ItemInfo->ItemName, (INT)(i_pMonster2Item->PrefixProbability)
////			, (int)(prob - i_pMonster2Item->PrefixProbability*i_fPlusRateDropRareItem));
//		
//		vector<RARE_ITEM_INFO* > *pRareFixVector= i_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItem->ItemInfo->ReqMinLevel));
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (IS_RARE_SUFFIX(pRareItemInfo->CodeNum)
//				|| !COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL))
//			{
//				continue;
//			}
//
//			prob = RAND100K();
//			if (pRareItemInfo->Probability > prob)
//			{// RareItem 성공
//
////				DBGOUT("	Prefix 성공: %d > %d\r\n", (INT)(pRareItemInfo->Probability), prob);				
//				io_pItem->PrefixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
////			else
////			{
////				DBGOUT("	Prefix 실패: %d <= %d\r\n", (INT)(pRareItemInfo->Probability), prob);
////			}
//		}
//	}
//
//	// Suffix 적용
//	prob = RAND100K();
//	if (i_pMonster2Item->SuffixProbability > 0
//		&& i_pMonster2Item->SuffixProbability > prob - i_pMonster2Item->SuffixProbability*i_fPlusRateDropRareItem)
//	{
////		DBGOUT("Monster: %s(%d), Item: %s, Pro(%d) > Rand(%d)\r\n", i_pMonster->MonsterInfoPtr->MonsterName, i_pMonster->MonsterIndex,
////			io_pItem->ItemInfo->ItemName, (INT)(i_pMonster2Item->SuffixProbability)
////			, (int)(prob - i_pMonster2Item->SuffixProbability*i_fPlusRateDropRareItem));
//
//		vector<RARE_ITEM_INFO* > *pRareFixVector
//			= i_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItem->ItemInfo->ReqMinLevel));
//
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (IS_RARE_PREFIX(pRareItemInfo->CodeNum)
//				|| !COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL))
//			{
//				continue;
//			}
//
//			prob = RAND100K();
//			if (pRareItemInfo->Probability > prob)
//			{// RareItem 성공
//
////				DBGOUT("	Suffix 성공: %d > %d\r\n", (INT)(pRareItemInfo->Probability), prob);				
//				io_pItem->SuffixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
////			else
////			{
////				DBGOUT("	Suffix 실패: %d <= %d\r\n", (INT)(pRareItemInfo->Probability), prob);
////			}
//		}
//	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ApplyGambleRareFix(ITEM_GENERAL *io_pItemG, int i_n100KPrefixProbability, int i_n100KSuffixProbability)
/// \brief		
/// \author		cmkwon
/// \date		2006-08-10 ~ 2006-08-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ApplyGambleRareFix(ITEM_GENERAL *io_pItemG, int i_n100KPrefixProbability, int i_n100KSuffixProbability)
{
	int i = 0;
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 -
	//if (FALSE == IS_WEAPON(io_pItemG->Kind)
	if(FALSE == IS_RARE_TARGET_ITEMKIND(io_pItemG->Kind)
		|| COMPARE_BIT_FLAG(io_pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM|ITEM_ATTR_LEGEND_ITEM))
	{// 2007-08-22 by cmkwon, 레전드 아이템 - 체크 추가, // 2006-08-10 by cmkwon, 유니크 아이템 체크
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// Prefix 적용
	int prob = RAND100K();
	if (i_n100KPrefixProbability > 0
		&& i_n100KPrefixProbability > prob)
	{
		io_pItemG->PrefixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItemG->ItemInfo, TRUE, RARE_ITEM_USE_TYPE_NORMAL, this);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
		
		if (io_pItemG->PrefixCodeNum == 0)
		{// Prefix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Prefix error, %s %s\r\n",
				GetCharacterString(&m_character, string()), GetItemString(io_pItemG, string()));
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// Suffix 적용
	prob = RAND100K();
	if (i_n100KSuffixProbability > 0
		&& i_n100KSuffixProbability > prob)
	{
		io_pItemG->SuffixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItemG->ItemInfo, FALSE, RARE_ITEM_USE_TYPE_NORMAL, this);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
		
		if (io_pItemG->SuffixCodeNum == 0)
		{// Suffix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Suffix, %s %s\r\n",
				GetCharacterString(&m_character, string()), GetItemString(io_pItemG, string()));
		}
	}
	return TRUE;

// 2007-12-07 by cmkwon, 레어 시스템 수정 - 위와 같이 CFieldIOCP::GetRandomRareCode() 함수로 처리
//	///////////////////////////////////////////////////////////////////////////////
//	// Prefix 적용
//	int prob = RAND100K();
//	if (i_n100KPrefixProbability > 0
//		&& i_n100KPrefixProbability > prob)
//	{
//		vector<RARE_ITEM_INFO* > *pRareFixVector = ms_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItemG->ItemInfo->ReqMinLevel));
//		
//		Prob100K_t	nSumProb		= 0;
//		///////////////////////////////////////////////////////////////////////////////
//		// 해당되는 RareFix에 대해 확률의 합을 계산
//		for (int i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//			if (IS_RARE_SUFFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItemG->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL)
//				)
//			{
//				continue;
//			}
//
//			nSumProb += pRareItemInfo->Probability;
//		}
//
//		Prob100K_t prob				= RANDI(0, nSumProb-1);
//		Prob100K_t nTempSumProb		= 0;
//		///////////////////////////////////////////////////////////////////////////////		
//		// 확률에 따라 RareFix를 결정
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (IS_RARE_SUFFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItemG->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL)
//				)
//			{
//				continue;
//			}
//
//			if (0 < nTempSumProb+pRareItemInfo->Probability			// 2006-04-20 by cmkwon, 0인 레어가 붙을 수 없도록
//				&& IS_IN_RANGE(nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability))
//			{// RareItem 성공
//
//				io_pItemG->PrefixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
//
//			nTempSumProb += pRareItemInfo->Probability;			// 더함
//		}
//
//		// Prefix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
//		if (io_pItemG->PrefixCodeNum == 0)
//		{
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL Error: No Prefix, %d %d %s %s\r\n",
//				(int)nTempSumProb, (int)prob, GetCharacterString(&m_character, string()), GetItemString(io_pItemG, string()));
//		}
//	}// END - if (i_n100KPrefixProbability > 0 && i_n100KPrefixProbability > prob)
//
//	///////////////////////////////////////////////////////////////////////////////
//	///////////////////////////////////////////////////////////////////////////////
//	// Suffix 적용
//	prob = RAND100K();
//	if (i_n100KSuffixProbability > 0
//		&& i_n100KSuffixProbability > prob)
//	{
//		vector<RARE_ITEM_INFO* > *pRareFixVector = ms_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItemG->ItemInfo->ReqMinLevel));
//
//		Prob100K_t	nSumProb		= 0;
//		///////////////////////////////////////////////////////////////////////////////		
//		// 해당되는 RareFix에 대해 확률의 합을 계산
//		for (int i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (IS_RARE_PREFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItemG->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL)
//				)
//			{
//				continue;
//			}
//
//			nSumProb += pRareItemInfo->Probability;
//		}
//
//		Prob100K_t prob				= RANDI(0, nSumProb-1);
//		Prob100K_t nTempSumProb		= 0;
//		///////////////////////////////////////////////////////////////////////////////
//		// 확률에 따라 RareFix를 결정
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (IS_RARE_PREFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItemG->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, RARE_ITEM_USE_TYPE_NORMAL)
//				)
//			{
//				continue;
//			}
//
//			if (0 < nTempSumProb+pRareItemInfo->Probability			// 2006-04-20 by cmkwon, 0인 레어가 붙을 수 없도록
//				&& IS_IN_RANGE(nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability))
//			{// RareItem 성공
//
//				io_pItemG->SuffixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
//	
//			nTempSumProb += pRareItemInfo->Probability;		// 더함
//		}
//
//		// Suffix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
//		if (io_pItemG->SuffixCodeNum == 0)
//		{
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL Error: No Suffix, %d %d %s %s\r\n",
//				(int)nTempSumProb, (int)prob, GetCharacterString(&m_character, string()), GetItemString(io_pItemG, string()));
//		}
//	}// END - if (i_n100KSuffixProbability > 0 && i_n100KSuffixProbability > prob)
//
//	return TRUE;
}

// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 인자추가(, RARE_ITEM_INFO *i_pLastRareItemInfo/*=NULL*/)
BOOL CFieldIOCPSocket::ApplyGambleRareFix(ITEM *i_pGambleItemInfo, ITEM_GENERAL *io_pItem, RARE_ITEM_INFO *i_pLastRareItemInfo/*=NULL*/)
{
// 2010-04-20 by cmkwon, 신규 러키 머신 구현 -
//	if (FALSE == IS_WEAPON(io_pItem->Kind)){					return FALSE;}
	if(FALSE == IS_RARE_TARGET_ITEMKIND(io_pItem->Kind)){		return FALSE;}

	int			nReqUseType	= 0;
	// 2007-11-07 by cmkwon, 갬블/슈갬 붙는 시스템 수정 - 아래와 같이 ITEM_ATTR_SUPER_GAMBLE_ITEM 를 체크 하여 처리하는 것으로 수정
	//if(FALSE == COMPARE_BIT_FLAG(i_pGambleItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM))

	// 2012-12-27 by hskim, 하이퍼 접두/점미 시스템 구현
	if( TRUE == COMPARE_BIT_FLAG(i_pGambleItemInfo->ItemAttribute, ITEM_ATTR_HYPER_GAMBLE_ITEM) )
	{
		SET_BIT_FLAG(nReqUseType, RARE_ITEM_USE_TYPE_HYPERGAMBLE);
	}
	else
	// end 2012-12-27 by hskim, 하이퍼 접두/점미 시스템 구현
	
	if(FALSE == COMPARE_BIT_FLAG(i_pGambleItemInfo->ItemAttribute, ITEM_ATTR_SUPER_GAMBLE_ITEM))
	{// 2007-11-07 by cmkwon, 갬블/슈갬 붙는 시스템 수정 - 
		SET_BIT_FLAG(nReqUseType, RARE_ITEM_USE_TYPE_GAMBLE);
	}
	else
	{
		SET_BIT_FLAG(nReqUseType, RARE_ITEM_USE_TYPE_SUPERGAMBLE);
	}

	// Prefix 적용
	// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
	//if (i_pGambleItemInfo->DestParameter1 == DES_RARE_FIX_PREFIX)
	if (IS_DES_RARE_FIX_PREFIX(i_pGambleItemInfo))
	{
		/////////////////////////////////////////////////////////////////////////
		// start 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션

		/////////
		// 기존
	
//		// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 인자 추가한것 적용함
//		io_pItem->PrefixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, TRUE, nReqUseType, this, i_pLastRareItemInfo);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
//		if (io_pItem->PrefixCodeNum == 0)
//		{// Prefix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Prefix, %s %s %s\r\n",
//				GetCharacterString(&m_character, string()),	GetItemString(io_pItem, string()), i_pGambleItemInfo->ItemName);
//		}

		/////////
		// 수정

		if( FALSE == i_pGambleItemInfo->IsExistDesParam(DES_GAMBLE_RARE_ITEM_FIX) )
		{
		// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 인자 추가한것 적용함
		io_pItem->PrefixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, TRUE, nReqUseType, this, i_pLastRareItemInfo);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
		if (io_pItem->PrefixCodeNum == 0)
		{// Prefix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Prefix, %s %s %s\r\n",
				GetCharacterString(&m_character, string()),	GetItemString(io_pItem, string()), i_pGambleItemInfo->ItemName);
		}
	}
		else
		{
			// 적용전 CheckFixRareCode() 함수로 미리 검사

			io_pItem->PrefixCodeNum = i_pGambleItemInfo->GetParameterValue(DES_GAMBLE_RARE_ITEM_FIX);
		}

		// end 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션
		/////////////////////////////////////////////////////////////////////////
	}

	// Suffix 적용
	// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
	//if (i_pGambleItemInfo->DestParameter1 == DES_RARE_FIX_SUFFIX)
	if (IS_DES_RARE_FIX_SUFFIX(i_pGambleItemInfo))
	{
		/////////////////////////////////////////////////////////////////////////
		// start 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션

		/////////
		// 기존

		/*
		// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 인자 추가한것 적용함
		io_pItem->SuffixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, FALSE, nReqUseType, this, i_pLastRareItemInfo);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
		if (io_pItem->SuffixCodeNum == 0)
		{// Suffix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Suffix, %s %s %s\r\n",
				GetCharacterString(&m_character, string()),	GetItemString(io_pItem, string()), i_pGambleItemInfo->ItemName);
		*/

		/////////
		// 수정

		if( FALSE == i_pGambleItemInfo->IsExistDesParam(DES_GAMBLE_RARE_ITEM_FIX) )
		{
			// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 인자 추가한것 적용함
			io_pItem->SuffixCodeNum = ms_pFieldIOCP->GetRandomRareCode(io_pItem->ItemInfo, FALSE, nReqUseType, this, i_pLastRareItemInfo);	// 2007-12-07 by cmkwon, 레어 시스템 수정 - 
			if (io_pItem->SuffixCodeNum == 0)
			{// Suffix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyGambleRareFix_ Suffix, %s %s %s\r\n",
					GetCharacterString(&m_character, string()),	GetItemString(io_pItem, string()), i_pGambleItemInfo->ItemName);
			}
		}
		else
		{
			// 적용전 CheckFixRareCode() 함수로 미리 검사

			io_pItem->SuffixCodeNum = i_pGambleItemInfo->GetParameterValue(DES_GAMBLE_RARE_ITEM_FIX);
		}
		// end 2011-10-20 by hskim, EP4 [Free to play] - 접두/접미 고정 옵션
		/////////////////////////////////////////////////////////////////////////
	}

// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 이함수를 호출하는 곳에서 전송하게 수정
// 	// Send MSG
// 	INIT_MSG_OF_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX, T_FC_STORE_UPDATE_RARE_FIX, pUpdateRareFix, pUpdateRareFixBuf);
// 	pUpdateRareFix->ItemUID			= io_pItem->UniqueNumber;
// 	pUpdateRareFix->PrefixCodeNum	= io_pItem->PrefixCodeNum;
// 	pUpdateRareFix->SuffixCodeNum	= io_pItem->SuffixCodeNum;
// 	SendAddData(pUpdateRareFixBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX));
// 
// 	// Update DB
// 	QPARAM_UPDATE_ITEM_RARE_FIX *pQParam = new QPARAM_UPDATE_ITEM_RARE_FIX;
// 	pQParam->ItemUID				= io_pItem->UniqueNumber;
// 	pQParam->PrefixCodeNum			= io_pItem->PrefixCodeNum;
// 	pQParam->SuffixCodeNum			= io_pItem->SuffixCodeNum;
// 	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemRareFix, this, m_character.AccountUniqueNumber, pQParam);
	return TRUE;

// 2007-12-07 by cmkwon, 레어 시스템 수정 - 위와 같이 CFieldIOCP::GetRandomRareCode() 함수로 처리
//	// Prefix 적용
//	if (i_pGambleItemInfo->DestParameter1 == DES_RARE_FIX_PREFIX)
//	{
//		vector<RARE_ITEM_INFO* > *pRareFixVector = ms_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItem->ItemInfo->ReqMinLevel));
//		
//		int			nRareTotalCnts	= 0;		// 2007-12-07 by cmkwon, 디버깅을 위해
//		Prob100K_t	nSumProb = 0;
//		// 해당되는 RareFix에 대해 확률의 합을 계산
//		for (int i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (0 >= pRareItemInfo->Probability			// 2007-12-07 by cmkwon, 0인 레어가 붙을 수 없도록
//				|| IS_RARE_SUFFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, nReqUseType)
//				)
//			{
//				continue;
//			}
//
//			nSumProb += pRareItemInfo->Probability;
//			nRareTotalCnts++;					// 2007-12-07 by cmkwon, 디버깅을 위해
//		}
//
//		int			nRareCurCnts	= 0;		// 2007-12-07 by cmkwon, 디버깅을 위해
//		// 확률에 따라 RareFix를 결정
//		Prob100K_t prob = RANDI(0, nSumProb-1);
//		Prob100K_t nTempSumProb = 0;
//
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (0 >= pRareItemInfo->Probability			// 2007-12-07 by cmkwon, 레어 확률이 0 인 레어는 처리가 안되도록 수정
//				|| IS_RARE_SUFFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, nReqUseType)
//				)
//			{
//				continue;
//			}
//
//			if (0 < nTempSumProb+pRareItemInfo->Probability			// 2007-12-07 by cmkwon, 레어 확률이 0 인 레어는 처리가 안되도록 수정
//				&& IS_IN_RANGE(nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability))
//			{
//				// 2007-12-07 by cmkwon, 디버깅을 위해
//				char szLog[1024];
//				sprintf(szLog, "Prefix \'%15s\' Success: %4d <= %4d <= %4d, TotalPro(%5d) TotalRareCount(%d) CurCount(%d)\r\n",
//					pRareItemInfo->Name, nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability,
//					nSumProb, nRareTotalCnts, nRareCurCnts);
//				g_pFieldGlobal->WriteSystemLogEX(TRUE, szLog);
//				SendString128(STRING_128_ADMIN_CMD, szLog);
//				// RareItem 성공
//				io_pItem->PrefixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
//
//			// 더함
//			nTempSumProb += pRareItemInfo->Probability;
//			nRareCurCnts++;		// 2007-12-07 by cmkwon, 디버깅을 위해
//		}
//
//		// Prefix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
//		if (io_pItem->PrefixCodeNum == 0)
//		{
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL Error: No Prefix, %d %d %s %s %s\r\n",
//				(int)nTempSumProb, (int)prob,
//				GetCharacterString(&m_character, string()),
//				GetItemString(io_pItem, string()),
//				i_pGambleItemInfo->ItemName);
//		}
//	}
//
//	// Suffix 적용
//	if (i_pGambleItemInfo->DestParameter1 == DES_RARE_FIX_SUFFIX)
//	{
//		vector<RARE_ITEM_INFO* > *pRareFixVector = ms_pFieldIOCP->m_mapLevel2RareItemInfo.findEZ_ptr(min(CHARACTER_MAX_LEVEL, io_pItem->ItemInfo->ReqMinLevel));
//
//		int			nRareTotalCnts	= 0;		// 2007-12-07 by cmkwon, 디버깅을 위해
//		Prob100K_t	nSumProb = 0;
//
//		// 해당되는 RareFix에 대해 확률의 합을 계산
//		for (int i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (0 >= pRareItemInfo->Probability			// 2007-12-07 by cmkwon, 레어 확률이 0 인 레어는 처리가 안되도록 수정
//				|| IS_RARE_PREFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, nReqUseType)
//				)
//			{
//				continue;
//			}
//
//			nSumProb += pRareItemInfo->Probability;
//			nRareTotalCnts++;					// 2007-12-07 by cmkwon, 디버깅을 위해
//		}
//
//		int			nRareCurCnts	= 0;		// 2007-12-07 by cmkwon, 디버깅을 위해
//		// 확률에 따라 RareFix를 결정
//		Prob100K_t prob = RANDI(0, nSumProb-1);
//		Prob100K_t nTempSumProb = 0;
//
//		for (i = 0; i < pRareFixVector->size(); i++)
//		{
//			RARE_ITEM_INFO *pRareItemInfo = (*pRareFixVector)[i];
//
//			if (0 >= pRareItemInfo->Probability			// 2007-12-07 by cmkwon, 레어 확률이 0 인 레어는 처리가 안되도록 수정
//				|| IS_RARE_PREFIX(pRareItemInfo->CodeNum)
//				|| FALSE == COMPARE_ITEMKIND(pRareItemInfo->ReqItemKind, io_pItem->Kind)
//				|| FALSE == COMPARE_BIT_FLAG(pRareItemInfo->ReqUseType, nReqUseType)
//				)
//			{
//				continue;
//			}
//
//			if (0 < nTempSumProb+pRareItemInfo->Probability			// 2006-04-20 by cmkwon, 0인 레어가 붙을 수 없도록
//				&& IS_IN_RANGE(nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability))
//			{
//				// 2007-12-07 by cmkwon, 디버깅을 위해
//				char szLog[1024];
//				sprintf(szLog, "Suffix \'%15s\' Success: %4d <= %4d <= %4d, TotalPro(%5d) TotalRareCount(%d) CurCount(%d)\r\n",
//					pRareItemInfo->Name, nTempSumProb, prob, nTempSumProb+pRareItemInfo->Probability,
//					nSumProb, nRareTotalCnts, nRareCurCnts);
//				g_pFieldGlobal->WriteSystemLogEX(TRUE, szLog);
//				SendString128(STRING_128_ADMIN_CMD, szLog);
//
//				// RareItem 성공
//				io_pItem->SuffixCodeNum = pRareItemInfo->CodeNum;
//				break;
//			}
//
//			// 더함
//			nTempSumProb += pRareItemInfo->Probability;
//			nRareCurCnts++;			// 2007-12-07 by cmkwon, 디버깅을 위해
//		}
//
//		// Suffix가 무조건 붙어야 함, 안 붙으면 문제 있음, 만약의 경우를 대비해 로그 남김
//		if (io_pItem->SuffixCodeNum == 0)
//		{
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL Error: No Suffix, %d %d %s %s %s\r\n",
//				(int)nTempSumProb, (int)prob,
//				GetCharacterString(&m_character, string()),
//				GetItemString(io_pItem, string()),
//				i_pGambleItemInfo->ItemName);
//		}
//	}
//
//	// Send MSG
//	INIT_MSG_OF_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX, T_FC_STORE_UPDATE_RARE_FIX, pUpdateRareFix, pUpdateRareFixBuf);
//	pUpdateRareFix->ItemUID			= io_pItem->UniqueNumber;
//	pUpdateRareFix->PrefixCodeNum	= io_pItem->PrefixCodeNum;
//	pUpdateRareFix->SuffixCodeNum	= io_pItem->SuffixCodeNum;
//	SendAddData(pUpdateRareFixBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX));
//
//	// Update DB
//	QPARAM_UPDATE_ITEM_RARE_FIX *pQParam = new QPARAM_UPDATE_ITEM_RARE_FIX;
//	pQParam->ItemUID				= io_pItem->UniqueNumber;
//	pQParam->PrefixCodeNum			= io_pItem->PrefixCodeNum;
//	pQParam->SuffixCodeNum			= io_pItem->SuffixCodeNum;
//	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemRareFix, this, m_character.AccountUniqueNumber, pQParam);
//	return TRUE;
}

BOOL CFieldIOCPSocket::StopItemKindDecoy(ITEM *pItemDecoy)
{
	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DECOY_MASK))
	{
		ClearBodyConditionBit(m_character.BodyCondition, BODYCON_DECOY_MASK);

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 		UnsetParamFactor(m_ItemWingOut.DestParameter1, m_ItemWingOut.ParameterValue1);
// 		UnsetParamFactor(m_ItemWingOut.DestParameter2, m_ItemWingOut.ParameterValue2);
// 		UnsetParamFactor(m_ItemWingOut.DestParameter3, m_ItemWingOut.ParameterValue3);
// 		UnsetParamFactor(m_ItemWingOut.DestParameter4, m_ItemWingOut.ParameterValue4);
		for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
		{
			UnsetParamFactor(m_ItemWingOut.ArrDestParameter[i], m_ItemWingOut.ArrParameterValue[i]);
		}

	}

	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_TOGGLE_DECOY_OK, T_FC_BATTLE_TOGGLE_DECOY_OK, pToggleDecoy, pToggleDecoyBuf);
	pToggleDecoy->AttackIndex = m_character.ClientIndex;
	pToggleDecoy->IsOn = FALSE;
	if (pItemDecoy == NULL)
	{
		pToggleDecoy->ItemNum = 0;
	}
	else
	{
		pToggleDecoy->ItemNum = pItemDecoy->ItemNum;
	}

	SendInRangeMessageAroundMe(pToggleDecoyBuf, MSG_SIZE(MSG_FC_BATTLE_TOGGLE_DECOY_OK), TRUE);
#ifdef _DEBUG
	SendString128Static(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0135, pItemDecoy->ItemName);
#endif

	return TRUE;
}

BOOL CFieldIOCPSocket::StopItemKindShield(ITEM *pItemShield)
{
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_SHIELD_MASK);

	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_TOGGLE_SHIELD_RESULT, T_FC_BATTLE_TOGGLE_SHIELD_RESULT,
						pToggleShield, pToggleShieldBuf);
	pToggleShield->AttackIndex = m_character.ClientIndex;
	pToggleShield->IsOn = FALSE;
	if (pItemShield == NULL)
	{
		pToggleShield->ItemNum = 0;
	}
	else
	{
		pToggleShield->ItemNum = pItemShield->ItemNum;
	}

	SendInRangeMessageAroundMe(pToggleShieldBuf, MSG_SIZE(MSG_FC_BATTLE_TOGGLE_SHIELD_RESULT), TRUE);

	return TRUE;
}

// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - CashItemMoneyPay() 인자 추가, UID32_t i_giveTargetCharUID=0
// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - 인자 추가(, int i_nCurTotalMoney=0)
Err_t CFieldIOCPSocket::CashItemMoneyPay(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/, UID32_t i_giveTargetCharUID/*=0*/, int i_nCurTotalMoney/*=0*/, int i_nAmount/*=1*/)		// 2013-03-13 by hskim, 웹 캐시 상점
{	
	*o_pTotalMoney	= 0;
	*o_pMCash		= 0;
	*o_pGiftCard	= 0;

	if(FALSE == g_pFieldGlobal->m_bCashShopServiceFlag
		&& FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
	{// 2007-01-10 by cmkwon, 유료화 상점 지원 체크 - 관리자/운영자는 상관 없음
		return ERR_CASH_CASH_SHOP_NO_SERVICE;	
	}

	if(g_pFieldGlobal->GetIsJamboreeServer())
	{// 2007-11-05 by cmkwon, 대회 서버는 유료화 상점 모두 접근 불가 - 에러를 리턴 함
		return ERR_CASH_CASH_SHOP_NO_SERVICE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [서비스-필수] 빌링 함수 호출

	// 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템
#ifdef S_BPSOFTBILLING_JHSEOL
	return CashItem_BPSOFT(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nAmount);		// 2013-03-13 by hskim, 웹 캐시 상점	
#endif
	// end 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템

// 2008-07-21 by cmkwon, WinnerOnline_Tha 에 빌링을 마상 빌링 모듈을 적용 - 
#if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)
	return CashItem_S2(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
#endif // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_1

#ifdef SERVICE_TYPE_KOREAN_SERVER_2
	// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - CashItem_Yedang() 인자 추가
	return CashItem_Yedang(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice, i_giveTargetCharUID);
#endif  // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_2

#ifdef SERVICE_TYPE_ENGLISH_SERVER_1
	// 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 -
	//return CashItemGalaNetMoneyPay(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
	return CashItem_Wikigames(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice, i_giveTargetCharUID);	// 2008-08-14 by cmkwon, 캐나다 Wikigames_Eng 선물하기 기능 구현 - // 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 - 
#endif // END - #ifdef SERVICE_TYPE_ENGLISH_SERVER_1

// 2008-07-11 by cmkwon, Gameforge4D_Deu 빌링 모듈 연동하기 - 
// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 아래와 같이 3개 서비스 추가
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1)
// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1)
#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1) || defined(SERVICE_TYPE_POLISH_SERVER_1) || defined(SERVICE_TYPE_SPANISH_SERVER_1)
	// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 
 	return CashItem_ENG_2(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
#endif // END - #ifdef SERVICE_TYPE_ENGLISH_SERVER_2

#ifdef SERVICE_TYPE_VIETNAMESE_SERVER_1
	return CashItemVTCIntecomMoneyPay(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
#endif // END - #ifdef SERVICE_TYPE_VIETNAMESE_SERVER_1

#ifdef SERVICE_TYPE_CHINESE_SERVER_1
	return CashItemMoneyPay_Yetime_Chn(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
#endif // END - #ifdef SERVICE_TYPE_CHINESE_SERVER_1
	
#ifdef SERVICE_TYPE_RUSSIAN_SERVER_1
	// 2008-09-08 by dhjin, 러시아 빌링 관련
	if(TRUE == CashItemMoneyPay_Russia(o_pTotalMoney, o_pMCash, i_pItem, 1))	
	{// 2008-09-09 by dhjin, 러시아 빌링 관련 - 캐쉬 정보 얻어오기
		return ERR_NO_ERROR;
	}
#endif // END -  #ifdef SERVICE_TYPE_RUSSIAN_SERVER_1

#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
	// 2008-09-23 by cmkwon, 지원 서비스 추가(대만 Netpower_Tpe) -
	// 2008-11-13 by cmkwon, 대만 Netpower_Tpe 빌링 시스템 구축 - 수정
	return CashItem_Netpower(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)

#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
	// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - CFieldIOCPSocket::CashItemMoneyPay()에서 CFieldIOCPSocket::CashItem_Arario()을 호출
	return CashItem_Arario(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nCurTotalMoney);
#endif // END - #if defined(SERVICE_TYPE_JAPANESE_SERVER_1)


#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1)
	// 2010-11-29 by shcho, 아르헨티나 외부인증 변경 SOAP 처리
	if(TRUE==CashItemMoneyPay_Lin(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, 1))
	{
		return ERR_NO_ERROR;	
	}
    // END 2010-11-29 by shcho, 아르헨티나 외부인증 변경 SOAP 처리
#endif // #if defined(SERVICE_TYPE_ARGENTINA_SERVER_1)

	return ERR_CASH_mgQueryMall_ERROR;

// 2007-09-13 by cmkwon, 위와 같이 각 서버 define 별로 처리
// 	switch(g_pFieldGlobal->GetLanguageType())
// 	{
//	case LANGUAGE_TYPE_KOREAN:
//		{
//			return CashItem_S2(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
//		}
//		break;
// 	case LANGUAGE_TYPE_ENGLISH:
// 		return CashItemGalaNetMoneyPay(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
//	case LANGUAGE_TYPE_VIETNAMESE:
//		return CashItemVTCIntecomMoneyPay(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-08-22 by cmkwon, 중국 Yetime 빌링 라이브러리 적용	
//	case LANGUAGE_TYPE_CHINESE:
//		return CashItemMoneyPay_Yetime_Chn(o_pTotalMoney, o_pMCash, o_pGiftCard, i_pItem, i_nTotalPrice);
// 	}
//
//	return ERR_CASH_mgQueryMall_ERROR;

// 2005-06-10 by cmkwon
//	_MGAMEDATA	tmMGData;		MEMSET_ZERO(&tmMGData, sizeof(_MGAMEDATA));
//	_MGAMERET	tmMGRet;		MEMSET_ZERO(&tmMGRet, sizeof(_MGAMERET));
//	
//	strcpy(tmMGData.szCPID, MGAME_MALL_SPACECOWBOY_CPID);
//	strncpy(tmMGData.szUserID, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
//	_strupr(tmMGData.szUserID);				// 계정을 대문자로 변경한다
//	strcpy(tmMGData.szGoodsNo, "0000");		// 기본은 항상 "0000"으로 설정한다
//	strncpy(tmMGData.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
//	if(i_pItem)
//	{// 아템 구입시만 처리
//
//		sprintf(tmMGData.szGoodsNo, "%08d", i_pItem->ItemNum);
//		strncpy(tmMGData.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
//		tmMGData.iPrice				= i_nTotalPrice;
//	}
//	if(false == MallAgnetConnect(MGAME_MALL_MONEY_SERVER_IP, MGAME_MALL_MONEY_SERVER_PORT, &tmMGData, &tmMGRet))
//	{
//		if(i_pItem)
//		{
//			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] mgQueryMall Error, AccName(%s) ItemName(%s) TotalPrice(%d)\r\n"
//				, m_character.AccountName, i_pItem->ItemName, i_nTotalPrice); 
//		}
//		return ERR_CASH_mgQueryMall_ERROR;
//	}
//
//	switch(tmMGRet.iReturn)
//	{
//	case 1:	// 1 - 성공
//		{
//			*o_pMCash		= tmMGRet.iMoney;						// MCash
//			*o_pGiftCard	= tmMGRet.iPMoney;						// 상품권
//			*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// 총 MGameMoney
//		}
//		break;
//	case 4:	// 4 - 출금실패
//		{
//			if(i_pItem)
//			{// 아템 구입시에만 에러를 리턴
//				return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;
//			}
//		}
//		break;
//	case 5:	// 5 - 계좌 존재하지 않음
//		{
//			if(i_pItem)
//			{// 아템 구입시에만 에러를 리턴
//				return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT; 
//			}
//		}
//		break;
//	}
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [서비스-필수] 빌링 함수 정의

#ifdef SERVICE_TYPE_ENGLISH_SERVER_1

// 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 - 아래와 같이 Wikigames_Eng 용도로 수정
// ///////////////////////////////////////////////////////////////////////////////
// /// \fn			Err_t CFieldIOCPSocket::CashItemGalaNetMoneyPay(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
// /// \brief		
// /// \author		cmkwon
// /// \date		2006-05-30 ~ 2006-05-30
// /// \warning	
// ///
// /// \param		
// /// \return		
// ///////////////////////////////////////////////////////////////////////////////
// Err_t CFieldIOCPSocket::CashItemGalaNetMoneyPay(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
// {
// 	if(FALSE == g_pFieldGlobal->m_bCashShopServiceFlag)
// 	{// 2008-01-23 by cmkwon, Gameforge4D_Eng 유료화 상점 관리자/운영자 상관없이 사용 안함
// 		return ERR_CASH_CASH_SHOP_NO_SERVICE;	
// 	}
// 
// 	if(0 == m_GalaNetAccountIDNum)
// 	{
// 		return ERR_CASH_INVALID_EXT_ACCOUNTID_NUM;
// 	}
// 
// 	BILLSENDDATA	tmMGData;		MEMSET_ZERO(&tmMGData, sizeof(BILLSENDDATA));
// 	BILLRETDATA		tmMGRet;		MEMSET_ZERO(&tmMGRet, sizeof(BILLRETDATA));
// 
// 	tmMGData.nCommand = 1;			// command(1:the balance of accounts, 2:buy item)
// 	wsprintf(tmMGData.szUserNo, "%d", m_GalaNetAccountIDNum);
// 	STRNCPY_MEMSET(tmMGData.szUserID, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
// 	STRNCPY_MEMSET(tmMGData.szGameCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);		// 기본은 항상 "0000"으로 설정한다
// 	STRNCPY_MEMSET(tmMGData.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
// 	if(i_pItem)
// 	{// if buy item
// 
// 		tmMGData.nCommand = 2;			// command(1:the balance of accounts, 2:buy item)		
// 		wsprintf(tmMGData.szGameItemID, "%d", i_pItem->ItemNum);
// 	}
// 	
// 	if(-1 == BillCmdExecute(BILL_SERVER_INFO, &tmMGData, &tmMGRet))
// 	{
// 		if(i_pItem)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillCmdExecute Error, AccName(%s) ItemName(%s) TotalPrice(%d)\r\n"
// 				, m_character.AccountName, i_pItem->ItemName, i_nTotalPrice); 
// 		}
// 		return ERR_CASH_mgQueryMall_ERROR;
// 	}
// 
// 	switch(tmMGRet.nRetVal)
// 	{
// 	case 0:				break;		// 2006-06-07 by cmkwon, success
// 
// 	case 2264:		// 		2264	[F]insufficient cash.
// 		return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;
// 
// 	case 2274:		// 		2274	[F]user status is invalid.(currently not available), blocked because bad user.
// 		return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;
// 
// 	case 2281:		// 		2281	[F]get item information error.
// 		return ERR_CASH_INVALID_ITEM_INFORMATION;
// 
// 	default:
// 		{
// 			return ERR_CASH_NORMAL_ERROR;
// 		}
// 	}
// 
// 	*o_pMCash		= tmMGRet.nRealCash;					// RealCash
// 	*o_pGiftCard	= tmMGRet.nBonusCash;					// BonusCash
// 	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// Total Cash
// 
// 	return ERR_NO_ERROR;
//}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Wikigames(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/, UID32_t i_giveTargetCharUID/*=0*/)
/// \brief		// 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 - 
/// \author		cmkwon
/// \date		2006-05-30 ~ 2006-05-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Wikigames(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/, UID32_t i_giveTargetCharUID/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 캐나다 Wikigames 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

	SWIKIBILL_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SWIKIBILL_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));

	tmBReq.nCommand			= 1;					// 2007-09-13 by cmkwon, 기본값은 잔액조회 - // 명령종류(1:잔액조회, 2:아이템구매)
	STRNCPY_MEMSET(tmBReq.szAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(tmBReq.szCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= 2;		// 2006-09-13 by cmkwon, 아이템 구매
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		STRNCPY_MEMSET(tmBReq.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격

		///////////////////////////////////////////////////////////////////////////////
		// 2008-08-14 by cmkwon, 캐나다 Wikigames_Eng 선물하기 기능 구현 - 선물받는 사람 설정하기
		if(IS_VALID_UNIQUE_NUMBER(i_giveTargetCharUID))
		{
			tmBReq.nCommand				= 3;	// 2008-08-14 by cmkwon, 캐나다 Wikigames_Eng 선물하기 기능 구현 - 명령종류(1:잔액조회, 2:아이템구매, 3:선물)
			STRNCPY_MEMSET(tmBReq.GiftAccountName, m_giveTargetCharacter.AccountName0, min(SIZE_MAX_ACCOUNT_NAME, WIKIBILL_SIZE_MAX_ACCOUNT_NAME)); 
			tmBReq.GiftAccountUID		= m_giveTargetCharacter.AccountUID0;
			STRNCPY_MEMSET(tmBReq.GiftCharacterName, m_giveTargetCharacter.CharacterName0, min(SIZE_MAX_CHARACTER_NAME, WIKIBILL_SIZE_MAX_CHARACTER_NAME));
		}
	}
	
	int nRetCode = CashItem_Wikigames_DirectConnect(&tmBReq, &tmBRet);

	if(0 != nRetCode)
	{
		if(i_pItem)
		{			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Wikigames CashItem_Wikigames_DirectConnect Error(%d), %s ItemInfo(%d:%s) TotalPrice(%d) RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), i_pItem->ItemNum, i_pItem->ItemName, i_nTotalPrice, nRetCode, tmBRet.nRetErrCode);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Wikigames CashItem_Wikigames_DirectConnect Error(%d), %s RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), nRetCode, tmBRet.nRetErrCode);
		}
		switch(tmBRet.nRetErrCode)
		{
		case WIKIBILL_ERR_DB_NO_ERROR:
			break;
			
		case WIKIBILL_ERR_DB_NOT_ENOUGH_MONEY:
			return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;
			
		case WIKIBILL_ERR_DB_IS_NOT_ACCOUNTNAME:
			return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;
			
		case WIKIBILL_ERR_DB_INVALID_ITEM:
			return ERR_CASH_INVALID_ITEM_INFORMATION;
			
		default:
			{
				return ERR_CASH_NORMAL_ERROR;
			}
		}
	}

	*o_pMCash		= tmBRet.nCashPoint;					// RealCash
	*o_pGiftCard	= tmBRet.nBonusPoint;					// BonusCash
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// Total Cash

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			int CFieldIOCPSocket::CashItem_Wikigames_DirectConnect(SWIKIBILL_REQ_DATA *i_pReqData, SWIKIBILL_RET_DATA *o_pRetData)
/// \brief		// 2008-08-07 by cmkwon, Wikigames_Eng 빌링 수정 - 
/// \author		cmkwon
/// \date		2008-08-07 ~ 2008-08-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int CFieldIOCPSocket::CashItem_Wikigames_DirectConnect(SWIKIBILL_REQ_DATA *i_pReqData, SWIKIBILL_RET_DATA *o_pRetData)
{
	// 2008-07-30 by cmkwon, 초기화
	o_pRetData->nCashPoint	= 0;
	o_pRetData->nBonusPoint	= 0;
	o_pRetData->nRetErrCode	= 0;

	// 2008-07-30 by cmkwon, Command 체크
	switch(i_pReqData->nCommand)
	{
	case 1:
	case 2:
	case 3:
		break;
	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CashItem_Wikigames_DirectConnect command error !! Command(%d)\r\n"
				, i_pReqData->nCommand);
			o_pRetData->nRetErrCode	= WIKIBILL_ERR_DB_INVALID_BILLING_COMMAND;
			return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
		}
	}

	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword(), g_pFieldGlobal->GetMainWndHandle());
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect connect error !! DBServer(%s:%d) DatabaseName(%s) UID(%s) PWD(%s)\r\n"
			, g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword());
		o_pRetData->nRetErrCode	= WIKIBILL_ERR_DB_CONNECT_FAIL;
		return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
	}

	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLINTEGER arrCB[15] = {SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS, SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS
							,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS};
	SQLRETURN ret = 0;
	int nRetVal = 1;	// Error 상태로 초기화 한다.

	// 명령종류(1:잔액조회, 2:아이템구매, 3:선물) // 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - 
	switch (i_pReqData->nCommand)
	{
	case 1:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szAccountName, 0,	&arrCB[1]);
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0196));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB Error] ExecuteQuery(Billing_Get_Point@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect ExecuteQuery(Billing_Get_Point@) error !! User(%s|%s|%s)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP);
				o_pRetData->nRetErrCode		= WIKIBILL_ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}
			arrCB[1] = arrCB[2] = arrCB[3] = SQL_NTS;
			SQLBindCol(hstmt, 1, SQL_C_LONG, &nRetVal, 0,					&arrCB[1]);
			SQLBindCol(hstmt, 2, SQL_C_LONG, &o_pRetData->nCashPoint, 0,	&arrCB[2]);
			SQLBindCol(hstmt, 3, SQL_C_LONG, &o_pRetData->nBonusPoint, 0,	&arrCB[3]);

			SQLSMALLINT    nColCnts          = 0;
			while(TRUE)
			{
				SQLNumResultCols(hstmt, &nColCnts);
				if(nColCnts <= 0)
				{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
					ret = SQLMoreResults(hstmt);
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				ret = SQLFetch(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-25 by cmkwon, Results set 처리
			}
			odbcStmt.FreeStatement();
			
			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상
			// 1 ==> 오류			
			switch(nRetVal)
			{
			case 0:
				{
				}
				break;
			default:
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect Fetch(Billing_Get_Point@) error !! User(%s:%s|%s) RetVal(%d)\r\n"
						, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, nRetVal);
					o_pRetData->nRetErrCode		= WIKIBILL_ERR_DB_QUERY_FETCH_ERROR;
					return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
				}
			}
		}
		break;
	case 2:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szAccountName, 0,		&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szCharacterName, 0,	&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ITEM_NUM, 0, i_pReqData->szItemNum, 0,				&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ITEM_NAME, 0, i_pReqData->szItemName, 0,				&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nBuyItemCount), 0,									&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemUnitPrice), 0,								&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_IPADDRESS, 0, i_pReqData->szUserIP, 0,				&arrCB[7]);
			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0197));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(Billing_Buy_Item@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect ExecuteQuery(Billing_Buy_Item@) error !! User(%s|%s|%s) Item(%s,%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, i_pReqData->szItemNum, i_pReqData->nBuyItemCount);
				o_pRetData->nRetErrCode		= WIKIBILL_ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}
			
			arrCB[1] = arrCB[2] = arrCB[3] = SQL_NTS;
			SQLBindCol(hstmt, 1, SQL_C_LONG, &nRetVal, 0,					&arrCB[1]);
			SQLBindCol(hstmt, 2, SQL_C_LONG, &o_pRetData->nCashPoint, 0,	&arrCB[2]);
			SQLBindCol(hstmt, 3, SQL_C_LONG, &o_pRetData->nBonusPoint, 0,	&arrCB[3]);
			
			SQLSMALLINT    nColCnts          = 0;
			while(TRUE)
			{
				SQLNumResultCols(hstmt, &nColCnts);
				if(nColCnts <= 0)
				{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
					ret = SQLMoreResults(hstmt);
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				ret = SQLFetch(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-25 by cmkwon, Results set 처리
			}
			odbcStmt.FreeStatement();

			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상 과금
			// 1 ==> 캐쉬가 충분하지 않음
			// 2 ==> 구매상품이 일치하지 않음
			if(0 != nRetVal)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect Fetch(Billing_Buy_Item@) error !! User(%s|%s|%s) RetVal(%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, nRetVal);
				o_pRetData->nRetErrCode		= nRetVal;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1				
			}
		}
		break;
	case 3:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szAccountName, 0,			&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szCharacterName, 0,		&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ITEM_NUM, 0, i_pReqData->szItemNum, 0,					&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ITEM_NAME, 0, i_pReqData->szItemName, 0,					&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nBuyItemCount), 0,										&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemUnitPrice), 0,									&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_IPADDRESS, 0, i_pReqData->szUserIP, 0,					&arrCB[7]);
			SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->GiftAccountUID), 0,									&arrCB[8]);
			SQLBindParameter(hstmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->GiftAccountName, 0,			&arrCB[9]);
			SQLBindParameter(hstmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, WIKIBILL_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->GiftCharacterName, 0,	&arrCB[10]);
			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0198));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(Billing_Gift_Item@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect ExecuteQuery(Billing_Gift_Item@) error !! User(%s|%s|%s) Item(%s,%d) GiftUser(%s:%d %s)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, i_pReqData->szItemNum, i_pReqData->nBuyItemCount
					, i_pReqData->GiftAccountName, i_pReqData->GiftAccountUID, i_pReqData->GiftCharacterName);
				o_pRetData->nRetErrCode		= WIKIBILL_ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}
			
			arrCB[1] = arrCB[2] = arrCB[3] = SQL_NTS;
			SQLBindCol(hstmt, 1, SQL_C_LONG, &nRetVal, 0,					&arrCB[1]);
			SQLBindCol(hstmt, 2, SQL_C_LONG, &o_pRetData->nCashPoint, 0,	&arrCB[2]);
			SQLBindCol(hstmt, 3, SQL_C_LONG, &o_pRetData->nBonusPoint, 0,	&arrCB[3]);
			
			SQLSMALLINT    nColCnts          = 0;
			while(TRUE)
			{
				SQLNumResultCols(hstmt, &nColCnts);
				if(nColCnts <= 0)
				{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
					ret = SQLMoreResults(hstmt);
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				ret = SQLFetch(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-25 by cmkwon, Results set 처리
			}
			odbcStmt.FreeStatement();
			
			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상 과금
			// 1 ==> 캐쉬가 충분하지 않음
			// 2 ==> 구매상품이 일치하지 않음
			if(0 != nRetVal)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Wikigames_DirectConnect Fetch(Billing_Gift_Item@) error !! User(%s|%s|%s) GiftUser(%s:%d %s) RetVal(%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP
					, i_pReqData->GiftAccountName, i_pReqData->GiftAccountUID, i_pReqData->GiftCharacterName, nRetVal);
				o_pRetData->nRetErrCode		= nRetVal;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1				
			}
		}
		break;
		
	} // END - switch (i_pReqData->nCommand)

	return FALSE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
}
#endif // END - #ifdef SERVICE_TYPE_ENGLISH_SERVER_1

// 2008-07-11 by cmkwon, Gameforge4D_Deu 빌링 모듈 연동하기 - 
// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 아래와 같이 3개 서비스 추가
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1)
// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1)
#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1) || defined(SERVICE_TYPE_POLISH_SERVER_1) || defined(SERVICE_TYPE_SPANISH_SERVER_1)

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_ENG_2(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
/// \brief		// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 
/// \author		cmkwon
/// \date		2008-03-17 ~ 2008-03-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_ENG_2(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - Gameforge4D 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

	if(NULL == ms_pGFBillingRequest)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_ENG_2_ library error !!, hBillingLibrary(0x%X) ms_pGFBillingRequest(0x%X)\r\n"
			, ms_hBillingLibrary, ms_pGFBillingRequest);
		return ERR_CASH_mgQueryMall_ERROR;
	}
	GFSBILLING_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	GFSBILLING_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));

	tmBReq.nCommand			= GFBILLING_CMD_REQUEST;	// 2008-03-17 by cmkwon, GFBILLING_CMD_REQUEST		302		//just ask how much money/milage user has, dont buy anything (normally returns GFERR_DB_SUCCESS)
	tmBReq.nGameUID			= m_character.AccountUniqueNumber;		// 2008-03-17 by cmkwon, 의미 없지만 Gameforge4D 에서 AccountUID 를 넣어 주기를 요청함
	STRNCPY_MEMSET(tmBReq.szAccountName, m_character.AccountName, min(SIZE_MAX_ACCOUNT_NAME, GFMSBILLING_SIZE_MAX_ACCOUNT_NAME));
	STRNCPY_MEMSET(tmBReq.szCharacterName, m_character.CharacterName, min(SIZE_MAX_CHARACTER_NAME, GFMSBILLING_SIZE_MAX_CHARACTER_NAME));
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= GFBILLING_CMD_EXECUTE;		// 2008-03-17 by cmkwon, GFBILLING_CMD_EXECUTE		301		//buy given item for given user
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		STRNCPY_MEMSET(tmBReq.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격
	}

// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 위에서 처리하게 수정
// #if defined(_DEBUG)		// 2008-04-03 by cmkwon, 디버그 모드에서만 처리
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-04-03 by cmkwon, 마상 내부 서버에서 테스트를 위해
// 	if(g_pFieldGlobal->InMasangServer())
// 	{
// 		tmBRet.nCashPoint	= 50000;
// 		tmBRet.nBonusPoint	= (NULL == i_pItem) ? 50000 : 50000 - i_pItem->CashPrice;
// 
// 		*o_pMCash		= tmBRet.nCashPoint;			// CashPoint
// 		*o_pGiftCard	= tmBRet.nBonusPoint;			// BonusPoint
// 		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;		// Total Cash
// 		return ERR_NO_ERROR;
// 	}
// #endif

	// 2009-05-25 by cmkwon, Gameforge4D 시스템 로그 추가(빌링 관련) - 호출전
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::CashItem_ENG_2 before call ms_pGFBillingRequest# %s Command(%d) \r\n", GetCharacterString(&m_character, string()), tmBReq.nCommand);

	ms_pGFBillingRequest(MSBILLING_DB_SERVER_IP, MSBILLING_DB_SERVER_PORT, &tmBReq, &tmBRet);

	// 2009-05-25 by cmkwon, Gameforge4D 시스템 로그 추가(빌링 관련) - 호출후
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::CashItem_ENG_2 after call ms_pGFBillingRequest# %s RetErrCode(%d) \r\n", GetCharacterString(&m_character, string()), tmBRet.nRetErrCode);

	if(0 != tmBRet.nRetErrCode && GFERR_DB_SUCCESS != tmBRet.nRetErrCode)	// 2008-03-26 by cmkwon, 수정
	{
		if(i_pItem)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_ENG_2_ Error(%d), |%s| ItemInfo(%8d:%s) TotalPrice(%d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(GetCharacter(), string()), i_pItem->ItemNum, i_pItem->ItemName, i_nTotalPrice);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_ENG_2_ Error(%d), |%s|\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(GetCharacter(), string()));
		}
		switch(tmBRet.nRetErrCode)
		{
		case GFERR_DB_NOT_ENOUGH_CASH:				return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;
		case GFERR_DB_ACCT_INFO_CHECK_FAILED:		return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;
		case GFERR_DB_NONEXISTING_ITEM:				return ERR_CASH_INVALID_ITEM_INFORMATION;
		}

		return ERR_CASH_mgQueryMall_ERROR;
	}

	*o_pMCash		= tmBRet.nCashPoint;			// CashPoint
	*o_pGiftCard	= tmBRet.nBonusPoint;			// BonusPoint
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;		// Total Cash
	return ERR_NO_ERROR;
}
#endif // END - SERVICE_TYPE_ENGLISH_SERVER_2


#if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1) 
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItemVTCIntecomMoneyPay(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-07 ~ 2006-06-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItemVTCIntecomMoneyPay(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 베트남 VTC-Intecom 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

	///////////////////////////////////////////////////////////////////////////////
	// 2009-06-25 by cmkwon, 베트남 VTC 빌링 시스템 수정 -
	SVTCBILL_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SVTCBILL_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));

	tmBReq.nCommand		= 1;		// 초기값은 잔액 조회
	STRNCPY_MEMSET(tmBReq.szAccountName, GetCharacter()->AccountName, min(SIZE_MAX_ACCOUNT_NAME, VTCBILL_SIZE_MAX_ACCOUNT_NAME));
	STRNCPY_MEMSET(tmBReq.szCharacterName, GetCharacter()->CharacterName, min(SIZE_MAX_CHARACTER_NAME, VTCBILL_SIZE_MAX_CHARACTER_NAME));
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), min(SIZE_MAX_IPADDRESS, VTCBILL_SIZE_MAX_IPADDRESS));

	if(i_pItem)
	{
		tmBReq.nCommand		= 2;		// 구매로 변경
		tmBReq.nItemNum		= i_pItem->ItemNum;
		// 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
		//tmBReq.nItemPrice	= i_pItem->CashPrice;
		tmBReq.nItemPrice	= i_nTotalPrice;	// 차감할 금액을 최종 가격으로 바꾼다
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "   [Check] CFieldIOCPSocket::Process_FC_SHOP_BUY_CASH_ITEM, CashItemVTCIntecomMoneyPay _ AUID(%d) CUID(%d) ItemNum(%d) [TotalPrice(%d) = ItemPrice(%d) * BuyAmount(%d)]\r\n"
			, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, i_pItem->ItemNum, i_nTotalPrice, i_pItem->CashPrice, i_pItem->CashPrice > 0 ? i_nTotalPrice / i_pItem->CashPrice : -1);
		// end 2013-04-11 by jhseol, 캐쉬아이템 1게 가격으로 n게의 수량을 구매하는 버그수정
	}

	if(FALSE == CashItem_VTC_DirectConnect(&tmBReq, &tmBRet))
	{
		int nErr = ERR_CASH_NORMAL_ERROR;
		switch(tmBRet.nRetErrCode)
		{
		case VTCBILL_ERR_NOT_EXIST_ACCOUNTNAME:			nErr = ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;		break;
		case VTCBILL_ERR_NOT_ENOUGH_MONEY:				nErr = ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;	break;
		case VTCBILL_ERR_INVALID_ITEM_INFORMATION:		nErr = ERR_CASH_INVALID_ITEM_INFORMATION;			break;
		case VTCBILL_ERR_DB_TRANSACTION:				nErr = ERR_CASH_mgQueryMall_ERROR;					break;
		case VTCBILL_ERR_DB_CONNECT_FAIL:				nErr = ERR_CASH_mgQueryMall_ERROR;					break;
		case VTCBILL_ERR_DB_QUERY_ERROR:				nErr = ERR_CASH_mgQueryMall_ERROR;					break;
		case VTCBILL_ERR_DB_QUERY_FETCH_ERROR:			nErr = ERR_CASH_mgQueryMall_ERROR;					break;
		case VTCBILL_ERR_DB_INVALID_BILLING_COMMAND:	nErr = ERR_CASH_mgQueryMall_ERROR;					break;
		}

		return nErr;
	}

	*o_pMCash		= tmBRet.nCashPoint;			// CashPoint
	*o_pGiftCard	= tmBRet.nBonusPoint;			// BonusPoint
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;		// Total Cash
	return ERR_NO_ERROR;

// 2009-06-25 by cmkwon, 베트남 VTC 빌링 시스템 수정 - 기존 소스는 주석 처리함.
// 	VTCGAME_REQ		tmMGData;		MEMSET_ZERO(&tmMGData, sizeof(tmMGData));
// 	VTCGAME_RESP	tmMGRet;		MEMSET_ZERO(&tmMGRet, sizeof(tmMGRet));
// 
// 	STRNCPY_MEMSET(tmMGData.szUserID, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
// 	STRNCPY_MEMSET(tmMGData.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
// 	if(i_pItem)
// 	{// if buy item
// 		
// 		wsprintf(tmMGData.szGoodsNo, "%d", i_pItem->ItemNum);
// 		STRNCPY_MEMSET(tmMGData.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
// 		tmMGData.iPrice			= i_pItem->CashPrice;
// 	}
// 	
// 	int nBillingServerPort = VTC_SC_DEFAULT_SERVER_PORT;
// 	if(g_pFieldGlobal->IsTestServer())
// 	{// 2006-07-06 by cmkwon, 테섭용 빌링 서버 포트가 다르다
// 		nBillingServerPort = VTC_SC_TEST_SERVER_PORT;
// 	}
// 	if(FALSE == VTCDataQuery(VTC_SC_DEFAULT_SERVER_IP, nBillingServerPort, &tmMGData, &tmMGRet, VTC_SC_DEFAULT_TIMEOUT))
// 	{
// 		char szSysLog[1024];
// 		if(NULL == i_pItem)
// 		{
// 			wsprintf(szSysLog, "[ERROR] VTCDataQuery Error, AccInfo(%s:%d) charInfo(%s:%d) iReturn(%d)\r\n"
// 				, m_character.AccountName, m_character.AccountUniqueNumber, m_character.CharacterName, m_character.CharacterUniqueNumber
// 				, tmMGRet.iReturn);
// 		}
// 		else
// 		{
// 			wsprintf(szSysLog, "[ERROR] VTCDataQuery Error, AccInfo(%s:%d) charInfo(%s:%d) iReturn(%d) ItemName(%s) TotalPrice(%d)\r\n"
// 				, m_character.AccountName, m_character.AccountUniqueNumber, m_character.CharacterName, m_character.CharacterUniqueNumber
// 				, tmMGRet.iReturn, i_pItem->ItemName, i_nTotalPrice);
// 		}
// 		g_pFieldGlobal->WriteSystemLog(szSysLog);
// 		DbgOut(szSysLog);
// 
// 		return ERR_CASH_mgQueryMall_ERROR;
// 	}
// 
// 	switch(tmMGRet.iReturn)
// 	{
// 	case VTC_SC_SUCCESS:			break;			// 2006-06-07 by cmkwon, success
// 
// 	case VTC_SC_ERR_INV_CPID:			// #define	VTC_SC_ERR_INV_CPID						11	//Invalid CPID
// 	case VTC_SC_ERR_INV_USERID:			// #define	VTC_SC_ERR_INV_USERID					12	//Invalid UserID
// 		return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;
// 
// 	case VTC_SC_ERR_MONEY_NOT_ENOUGH:	// #define	VTC_SC_ERR_MONEY_NOT_ENOUGH		15	//Not enough money	
// 		return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;
// 
// 	case VTC_SC_ERR_INV_ITEM_NAME:		// #define	VTC_SC_ERR_INV_ITEM_NAME			14	//Invalid ItemName
// 	case VTC_SC_ERR_INV_GOODSNO:		// #define	VTC_SC_ERR_INV_GOODSNO				13	//Invalid GoodsNo
// 		return ERR_CASH_INVALID_ITEM_INFORMATION;
// 
// 	default:
// 		{
// 			return ERR_CASH_NORMAL_ERROR;
// 		}
// 	}
// 
// 	*o_pMCash		= tmMGRet.iMoney;					// RealCash
// 	*o_pGiftCard	= tmMGRet.iPMoney;					// BonusCash
// 	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// Total Cash
//
//	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-06-25 by cmkwon, 베트남 VTC 빌링 시스템 수정 - 
/// \author		cmkwon
/// \date		2009-06-25 ~ 2009-06-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CashItem_VTC_DirectConnect(SVTCBILL_REQ_DATA *i_pReqData, SVTCBILL_RET_DATA *o_pRetData)
{
	o_pRetData->nRetErrCode	= 0;
	o_pRetData->nCashPoint	= 0;
	o_pRetData->nBonusPoint	= 0;

	wchar_t wcAccName[VTCBILL_SIZE_MAX_ACCOUNT_NAME];
	MEMSET_ZERO(wcAccName, sizeof(wcAccName[0])*VTCBILL_SIZE_MAX_ACCOUNT_NAME);
	MultiByteToWideChar(CODE_PAGE, 0, i_pReqData->szAccountName, -1, wcAccName, VTCBILL_SIZE_MAX_ACCOUNT_NAME);

	wchar_t wcUserIP[VTCBILL_SIZE_MAX_IPADDRESS];
	MEMSET_ZERO(wcUserIP, sizeof(wcUserIP[0])*VTCBILL_SIZE_MAX_IPADDRESS);
	MultiByteToWideChar(CODE_PAGE, 0, i_pReqData->szUserIP, -1, wcUserIP, VTCBILL_SIZE_MAX_IPADDRESS);

	switch(i_pReqData->nCommand)
	{
	case 1:
	case 2:
		break;
	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_VTC_DirectConnect# command error !! Command(%d)\r\n", i_pReqData->nCommand);
			o_pRetData->nRetErrCode	= VTCBILL_ERR_DB_CONNECT_FAIL;
			return FALSE;
		}
	}

	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword(), g_pFieldGlobal->GetMainWndHandle());
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::CashItem_VTC_DirectConnect# connect error !! DBServer(%s:%d) DatabaseName(%s) UID(%s) PWD(%s)\r\n"
			, g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword());
		o_pRetData->nRetErrCode	= VTCBILL_ERR_DB_CONNECT_FAIL;
		return FALSE;
	}

	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLINTEGER arrCB[9] = {SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS, SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS};
	// 명령종류(1:잔액조회, 2:아이템구매)
	switch (i_pReqData->nCommand)
	{
	case 1:
		{
			int nReturn			= 0;
			int nResponseStatus = -1;
			SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &nReturn, 0,											&arrCB[1]);	
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, VTCBILL_SIZE_MAX_ACCOUNT_NAME, 0, wcAccName, 0,				&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nResponseStatus), 0,									&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(o_pRetData->nCashPoint), 0,							&arrCB[4]);

			// -- Get account's Vcoin values :
			// PROCEDURE  [dbo].[SP_Account_GetTotalVcoin] 
			//	@_AccountName       NVARCHAR (30),
			//	@_AccountID             INT OUTPUT,
			//	@_TotalVcoin            INT OUTPUT
			//	OUTPUT
			//	@_AccountID  
			//	--   > 0   :  Value of the AccountID (Successful)
			//	--   -1     :  Account not exist			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_090625_0348));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(PROCEDURE_090625_0348@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect ExecuteQuery(PROCEDURE_090625_0348@) error !! %s \r\n"
					, GetCharacterString(GetCharacter(), string()));
				o_pRetData->nRetErrCode		= VTCBILL_ERR_DB_QUERY_ERROR;
				return FALSE;
			}

			while(TRUE)
			{
				SQLRETURN ret = SQLMoreResults(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					break;
				}
			}
			odbcStmt.FreeStatement();
			
			if(0 >= nResponseStatus)
			{
				if(-1 == nResponseStatus)
				{
					o_pRetData->nRetErrCode		= VTCBILL_ERR_NOT_EXIST_ACCOUNTNAME;
				}
				else
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect Fetch(PROCEDURE_090625_0348@) error !! %s ResponseStatus(%d)\r\n"
						, GetCharacterString(GetCharacter(), string()), nResponseStatus);
					o_pRetData->nRetErrCode		= VTCBILL_ERR_DB_QUERY_FETCH_ERROR;
				}
				return FALSE;
			}
		}
		break;
	case 2:
		{
			int nReturn			= 0;
			int nResponseStatus = -1;
			int nDiscountMoney	= 0;	// 빌링 서버에서 처리하는 것임
			SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &nReturn, 0,									&arrCB[1]);	
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, VTCBILL_SIZE_MAX_ACCOUNT_NAME, 0, wcAccName, 0,		&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemNum), 0,						&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemPrice), 0,					&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, VTCBILL_SIZE_MAX_IPADDRESS, 0, wcUserIP, 0,			&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nDiscountMoney), 0,							&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nResponseStatus), 0,							&arrCB[7]);
			SQLBindParameter(hstmt, 8, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(o_pRetData->nCashPoint), 0,					&arrCB[8]);
		
			//--  Perform transactions :				  
			//PROCEDURE    [dbo].[SP_SCO_BuyItem] 
			//	@_AccountName		NVARCHAR(30),
			//	@_ItemID			INT,
			//	@_PriceMoney		INT,
			//	@_AccountIP			NVARCHAR(15),
			//	@_DiscountMoney		INT,
			//	@_ResponseStatus	INT OUTPUT,
			//	@_TotalVcoin		INT OUTPUT
			//	OUTPUT
			//	@_ ResponseStatus  
			//	--       0   : Successful Transaction
			//	--    -50   : Account not exist
			//	--    -51   : Vcoin not enough
			//	--    -52   : Item price invalid (ItemPrice <= 0)
			//	--    -99   : Error system transaction
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_090625_0349));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(PROCEDURE_090625_0349@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect ExecuteQuery(PROCEDURE_090625_0349@) error !! %s IP(%s) Item(%d, %d)\r\n"
					, GetCharacterString(GetCharacter(), string()), i_pReqData->szUserIP, i_pReqData->nItemNum, i_pReqData->nItemPrice);
				o_pRetData->nRetErrCode		= VTCBILL_ERR_DB_QUERY_ERROR;
				return FALSE;
			}
			
			while(TRUE)
			{
				SQLRETURN ret = SQLMoreResults(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					break;
				}
			}
			odbcStmt.FreeStatement();

			if(VTCBILL_ERR_SUCCESS != nResponseStatus)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect Fetch(PROCEDURE_090625_0349@) error !! %s ResponseStatus(%d) \r\n"
					, GetCharacterString(GetCharacter(), string()), nResponseStatus);
				switch(nResponseStatus)
				{
				case VTCBILL_ERR_NOT_EXIST_ACCOUNTNAME:		o_pRetData->nRetErrCode		= VTCBILL_ERR_NOT_EXIST_ACCOUNTNAME;			return FALSE;
				case VTCBILL_ERR_NOT_ENOUGH_MONEY:			o_pRetData->nRetErrCode		= VTCBILL_ERR_NOT_ENOUGH_MONEY;					return FALSE;
				case VTCBILL_ERR_INVALID_ITEM_INFORMATION:	o_pRetData->nRetErrCode		= VTCBILL_ERR_INVALID_ITEM_INFORMATION;			return FALSE;
				case VTCBILL_ERR_DB_TRANSACTION:			o_pRetData->nRetErrCode		= VTCBILL_ERR_DB_TRANSACTION;					return FALSE;
				}
				o_pRetData->nRetErrCode		= VTCBILL_ERR_DB_QUERY_FETCH_ERROR;
				return FALSE;
			}
		}
		break;
	} // END - switch (i_pReqData->nCommand)

	return TRUE;
}
#endif		//#if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1) || defined(SERVICE_TYPE_ARGENTINA_SERVER_1)

struct for_each_uprcase_at_string		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
{
	void operator()(string & i_op)
	{
		transform(i_op.begin(), i_op.end(), i_op.begin(), toupper);
	}
};

			   
#ifdef SERVICE_TYPE_ARGENTINA_SERVER_1
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItemMoneyPay_Lin(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_EA)
/// \brief		// 2011-02-09 by shcho, 아르헨티나 빌링 시스템 구현 -
///	\author		shcho			
/// \date		2011-02-09 ~
/// \warning	
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItemMoneyPay_Lin(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_EA)
{
#if defined(_DEBUG)
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;					// CashPoint
		*o_pTotalMoney	= *o_pMCash;				// Total Cash
		return ERR_NO_ERROR;
	}
#endif

 	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), (LPSTR)g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword(), g_pFieldGlobal->GetMainWndHandle());
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Billcrux connect error !!\r\n");
		return FALSE;
	}
	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLRETURN ret = 0;
	SQLRETURN paramret = 0;
	int	returnCode = 0;

	SQLINTEGER arrCB[8] = {SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS}; 
	CHAR userID[ID_MAX_STR_LEN];
	MEMSET_ZERO(userID,sizeof(ID_MAX_STR_LEN));
	memcpy(userID,this->m_character.AccountName,strlen(this->m_character.AccountName)+1);
	// 캐쉬 체크 프로시저 실행 시작 //
	ret = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, ID_MAX_STR_LEN, 0, userID, 0,	&arrCB[0]);
	ret = SQLBindParameter(hstmt, 2, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &returnCode, 0,	&arrCB[1]);
	ret = SQLBindParameter(hstmt, 3, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, o_pMCash, 0,	&arrCB[2]);
	
	bRet = odbcStmt.ExecuteQuery((char*)"{call dbo.procGetUserInfoByAceOnline(?,?,?)}");
	
	if(FALSE == bRet)
	{
		odbcStmt.ProcessLogMessagesForStmt("[DB Error] ExecuteQuery procGetUserInfoByAceOnline(?,?,?) Error !!\r\n");
		return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
	}

	SQLFreeStmt(hstmt, SQL_CLOSE);
	// 캐쉬 체크 프로시저 실행 종료 //
	
	// 받은 리턴 코드에 관한 관련 에러 체크
	Err_t Errcode = 0;
	switch(returnCode)
	{
		case ARG_RETURN_SUCCESS:
#ifdef _DEBUG	// 디버그 시에만 동작한다
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB EXCUTE] Errcode(%d) Success return!!\r\n", Errcode);
#endif
			break;

		case ERR_ARG_RETURN_INVALED_USER:		// 사용자가 아님
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) INVALID USER!!\r\n", Errcode);
			return FALSE;

		case ERR_ARG_RETURN_NOT_NORMAL_USER:	// 정상 유저가 아님
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) NOT_NOMAL USER!!\r\n", Errcode);
			return FALSE;

		default:								// 알수 없는 에러
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) UNKNOWN ERROR!!\r\n", Errcode);
			return FALSE;

	}	
	*o_pTotalMoney = *o_pMCash;	// 보여줄 남은 캐쉬


	// 아이템을 구매할 경우
 	if(NULL != i_pItem)
 	{
		short GameID = ARG_GAME_SERVICE_ID;
		returnCode = 0;
		int transactionId = 0;
		// 구매 프로시저 실행 루틴 //
		arrCB[0]=arrCB[1]=arrCB[2]=arrCB[3]=arrCB[4]=arrCB[5]=arrCB[6]=arrCB[7]=SQL_NTS;
		ret = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,	SQL_VARCHAR, ID_MAX_STR_LEN, 0, userID, 0,	&arrCB[0]);
		ret = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_SMALLINT, 0, 0, &GameID, 0,	&arrCB[1]);
		ret = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG,	SQL_INTEGER, 0, 0, &i_pItem->ItemNum, 0,	&arrCB[2]);
		ret = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR,	SQL_VARCHAR, ITEMNAME_MAX_STR_LEN, 0, i_pItem->ItemName, 0,	&arrCB[3]);
		ret = SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG,	SQL_INTEGER, 0, 0, &i_pItem->CashPrice, 0,	&arrCB[4]);
		ret = SQLBindParameter(hstmt, 6, SQL_PARAM_OUTPUT, SQL_C_LONG,	SQL_INTEGER, 0, 0, &returnCode, 0,	&arrCB[5]);
		ret = SQLBindParameter(hstmt, 7, SQL_PARAM_OUTPUT, SQL_C_LONG,	SQL_INTEGER, 0, 0, &transactionId, 0,	&arrCB[6]);

		bRet = odbcStmt.ExecuteQuery((char*)"{call dbo.procOrderByAceOnline(?,?,?,?,?,?,?)}");
	
		if(FALSE == bRet)
		{
			odbcStmt.ProcessLogMessagesForStmt("[DB Error] ExecuteQuery dbo.procOrderByAceOnline(?,?,?,?,?,?,?) Error !!\r\n");
			return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
		}

		SQLFreeStmt(hstmt, SQL_CLOSE);
		// 구매 프로시저 실행 종료 //

		// 받은 리턴 코드에 관한 관련 에러 체크
		switch(returnCode)
		{		
			case ARG_RETURN_SUCCESS:			// 접속 성공
#ifdef _DEBUG	// 디버그 시에만 동작한다
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB EXCUTE] Errcode(%d) Success return!!\r\n", Errcode);
#endif
				break;

			return FALSE;
			case ERR_ARG_RETURN_INVALED_USER:	// 사용자가 아님
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) INVALID USER!!\r\n", Errcode);
				return FALSE;
				
			case ERR_ARG_RETURN_NOT_NORMAL_USER:	// 정상 유저가 아님
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) NOT_NOMAL USER!!\r\n", Errcode);
				return FALSE;
				
			case ERR_ARG_RETURN_NOT_ENOUGH_CASH:	// 잔액 부족
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) ENOUGH_CASH!!\r\n", Errcode);
				return FALSE;
			default:								// 알수 없는 에러
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Errcode(%d) UNKNOWN ERROR!!\r\n", Errcode);
		}	

		*o_pMCash = *o_pMCash - (i_pItem->CashPrice * 1);	// 캐쉬 차감
		*o_pTotalMoney = *o_pMCash;	// 보여줄 남은 캐쉬
		
		// 캐쉬 아이템 구매 로그
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[CashItem] User(AccountUID = %d, AccountName = %s, CharacterUID = %d, CharacterName = %s)  Item(ItemNum = %d, CashPrice = %d, ItemCount = %d) \r\n"
			, m_character.AccountUniqueNumber, m_character.AccountName
			, m_character.CharacterUniqueNumber, m_character.CharacterName
			, i_pItem->ItemNum, i_pItem->CashPrice, 1);
		
 	}// if(NULL != i_pItem)
	
	return TRUE;
}
#endif // END - #ifdef SERVICE_TYPE_ARGENTINA_SERVER_1

#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1) || defined(SC_XTRAP_VTC_GAMEGUARD_BHSOHN_JHSEOL)	// 2013-10-09 by jhseol, X-Trap + VTC 게임가드		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경
///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
/// \author		cmkwon
/// \date		2009-10-08 ~ 2009-10-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::XTrapLoadMapFile(const char *i_szDir, char *i_szPrefixFileName)
{
	BYTE			arrXTrapMap[XTRAP_CSFILE_NUM][XTRAP_CS4_BUFSIZE_MAP];
	int				nLoadedCnt = 0;

	vectstring		vectFileNameList;

	MEMSET_ZERO(arrXTrapMap, XTRAP_CSFILE_NUM * XTRAP_CS4_BUFSIZE_MAP);
	
	// 2009-10-08 by cmkwon, 해당 폴더의 모든 파일 리스트를 가져온다
	if(FALSE == CFieldIOCP::GetAllFileNameList(&vectFileNameList, i_szDir, i_szPrefixFileName))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::XTrapLoadMapFile#  call CFieldIOCP::GetAllFileNameList# error !!, Directory(%s) ListCnt(%d) \r\n", i_szDir, vectFileNameList.size());
		return FALSE;
	}
	if(XTRAP_CSFILE_NUM > vectFileNameList.size())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::XTrapLoadMapFile#  mapfile count error !!, ReqCount(%d) fileCount(%d) \r\n", XTRAP_CSFILE_NUM, vectFileNameList.size());
		return FALSE;
	}
	
	// 2009-10-08 by cmkwon, 정렬을 위해 대문자로 모두 변경
	for_each(vectFileNameList.begin(), vectFileNameList.end(), for_each_uprcase_at_string());

	// 2009-10-08 by cmkwon, 정렬
	sort(vectFileNameList.begin(), vectFileNameList.end(), greater<string>());

	vectstring::iterator itr(vectFileNameList.begin());
	for(; itr != vectFileNameList.end(); itr++)
	{
		string *pstrFileName = itr;
		
		char		szFilePathMap[MAX_PATH];
		FILE		*fpMap = NULL;
		sprintf(szFilePathMap, "%s\\%s", i_szDir, pstrFileName->c_str());

		fpMap = fopen(szFilePathMap, "rb");
		if(NULL == fpMap)
		{
			char szCurDir[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, szCurDir);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::XTrapLoadMapFile# fopen error !! Path(%s), CurDir(%s)\r\n", szFilePathMap, szCurDir);
			return FALSE;
		}

		DWORD dwReadCnt = fread(arrXTrapMap[nLoadedCnt], XTRAP_CS4_BUFSIZE_MAP, 1, fpMap);
		fclose(fpMap);
		if(0 == dwReadCnt)
		{
			char szCurDir[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, szCurDir);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::XTrapLoadMapFile# fread error !! Path(%s), CurDir(%s), readCnt(%d) \r\n", szFilePathMap, szCurDir, dwReadCnt);
			return FALSE;
		}
		nLoadedCnt++;

		if(XTRAP_CSFILE_NUM <= nLoadedCnt)
		{
			break;
		}
	}

	if(XTRAP_CSFILE_NUM != nLoadedCnt)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::XTrapLoadMapFile#  loaded mapfile count error !!, ReqCount(%d) fileCount(%d) loadedCount(%d) \r\n", XTRAP_CSFILE_NUM, vectFileNameList.size(), nLoadedCnt);
		return FALSE;
	}

	memcpy(ms_XTrapMap, arrXTrapMap, XTRAP_CSFILE_NUM * XTRAP_CS4_BUFSIZE_MAP);
	return TRUE;
}
#endif //#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1)		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경

#ifdef SERVICE_TYPE_CHINESE_SERVER_1
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItemMoneyPay_Yetime_Chn(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
/// \brief		// 2007-08-22 by cmkwon, 중국 Yetime 빌링 라이브러리 적용 - 함수 추가
/// \author		cmkwon
/// \date		2007-08-22 ~ 2007-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItemMoneyPay_Yetime_Chn(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 중국 Yetime 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif
	
	*o_pTotalMoney		= 0;
	*o_pMCash			= 0;
	*o_pGiftCard		= 0;

	int nCurTotalMoney = 0;	
	Err_t err = 0;
	char szErrString[1024];
	STRNCPY_MEMSET(szErrString, "No Error", 1024);

	if(NULL == i_pItem)
	{
		err = BillingPayW_Yetime_Chn(&nCurTotalMoney, szErrString, g_pFieldGlobal->GetServerGroupName(), m_character.AccountName
										, m_character.CharacterName);
	}
	else
	{
		err = BillingPayW_Yetime_Chn(&nCurTotalMoney, szErrString, g_pFieldGlobal->GetServerGroupName(), m_character.AccountName
										, m_character.CharacterName, i_pItem->ItemNum, 1, i_nTotalPrice);
	}

	if(ERR_NO_ERROR == err)
	{
		*o_pTotalMoney		= nCurTotalMoney;
		*o_pMCash			= nCurTotalMoney;
	}
	else
	{
		if(NULL == i_pItem)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]: BillingPayW_Yetime_Chn error!!, %s, Err(%d:%s) ErrString(%s)\r\n"
				, GetCharacterString(&m_character, string()), err, GetErrorString(err), szErrString);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]: BillingPayW_Yetime_Chn error!!, %s, Err(%d:%s) ErrString(%s), ItemInfo(%d:%s) BuyCount(%d), BuyTotalMoney(%d)\r\n"
				, GetCharacterString(&m_character, string()), err, GetErrorString(err), szErrString, i_pItem->ItemNum, i_pItem->ItemName, 1, i_nTotalPrice);
		}
	}

	return err;
}
#endif // END - #ifdef SERVICE_TYPE_CHINESE_SERVER_1

// 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash, UINT i_pItemCashPrice/*=0*/)
/// \brief		
/// \author		jhseol
/// \date		2012-08-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash, ITEM *i_pItem/*=0*/, int i_nAmount/*=1*/)		// 2013-03-13 by hskim, 웹 캐시 상점
{
	Err_t nRetedErr = GetCashPay_BPSOFT(o_pTotalMoney, o_pMCash, o_pFreeCash);

	if( ERR_NO_ERROR != nRetedErr )
	{
		return nRetedErr;
	}
	if( NULL == i_pItem )
	{
		return nRetedErr;
	}

	nRetedErr = BuyCashItem_BPSOFT(o_pTotalMoney, o_pMCash, o_pFreeCash, i_pItem, i_nAmount);		// 2013-03-13 by hskim, 웹 캐시 상점
	if( ERR_NO_ERROR != nRetedErr )
	{
		return nRetedErr;
	}
	return ERR_NO_ERROR;
}
// end 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템

// 2008-07-21 by cmkwon, WinnerOnline_Tha 에 빌링을 마상 빌링 모듈을 적용 - 
#if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_THAI_SERVER_1)  || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_S2(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-09-13 ~ 2006-09-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_S2(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
{
#if defined(_DEBUG) && !defined(SERVICE_TYPE_KOREAN_SERVER_1)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 태국 WinnerOnline 처리, Masang140은 제외
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 
//	SBILLING_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
//	SBILLING_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));
	SMasangBILL_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SMasangBILL_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));

	tmBReq.nCommand			= 1;					// 2006-09-13 by cmkwon, 잔액 조회
	tmBReq.nGameUID			= MSBILLING_GAMEUID;	// 2006-09-13 by cmkwon, GameUID
	STRNCPY_MEMSET(tmBReq.szAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(tmBReq.szCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= 2;		// 2006-09-13 by cmkwon, 아이템 구매
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		STRNCPY_MEMSET(tmBReq.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격
	}

// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 
// 	if(FALSE == BillingReqExecute(MSBILLING_DB_SERVER_IP, MSBILLING_DB_SERVER_PORT, &tmBReq, &tmBRet))
// 	{
// 		if(i_pItem)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillingReqExecute Error(%d), AccName(%s) ItemName(%s) TotalPrice(%d)\r\n"
// 				, tmBRet.nRetErrCode, m_character.AccountName, i_pItem->ItemName, i_nTotalPrice);
// 		}
// 		else
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillingReqExecute Error(%d), AccName(%s) BillingServer(%s:%d)\r\n"
// 				, tmBRet.nRetErrCode, m_character.AccountName, MSBILLING_DB_SERVER_IP, MSBILLING_DB_SERVER_PORT);
// 		}
// 		return ERR_CASH_mgQueryMall_ERROR;
// 	}

	// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 
	BOOL bRetFlag = CashItem_Masang_DirectConnect(&tmBReq, &tmBRet);

	switch(tmBRet.nRetErrCode)
	{
	case ERR_DB_NO_ERROR:
	case ERR_DB_IS_NOT_ACCOUNTNAME:		// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 빌리 DB에 계정이 없는 것은 에러가 아니다.
		break;		// 2006-06-07 by cmkwon, success

	case ERR_DB_NOT_ENOUGH_MONEY:		// #define ERR_DB_NOT_ENOUGH_MONEY					2			// 소유한 Point(CashPoint+BonusPoint)가 구매하려는 아이템의 가격보다 작다
		return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;

// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 빌리 DB에 계정이 없는 것은 에러가 아니다.
//	case ERR_DB_IS_NOT_ACCOUNTNAME:		// #define ERR_DB_IS_NOT_ACCOUNTNAME				1			// td_cash_bonus_point 테이블에 계정명이 없음
//		return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;

	case ERR_DB_INVALID_ITEM:		// #define ERR_DB_INVALID_ITEM						4			// 구매하려는 아이템이 유효하지 않음 - ti_item_info 테이블에 없거나 IsDisable 필드가 0이 아니다
		return ERR_CASH_INVALID_ITEM_INFORMATION;

	default:
		{
			// 2008-07-18 by cmkwon, 버그 수정
			if(i_pItem)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillingReqExecute Error(%d), AccName(%s) ItemName(%s) TotalPrice(%d)\r\n"
					, tmBRet.nRetErrCode, m_character.AccountName, i_pItem->ItemName, i_nTotalPrice);
			}
			else
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillingReqExecute Error(%d), AccName(%s)\r\n"
					, tmBRet.nRetErrCode, m_character.AccountName);
			}
			return ERR_CASH_NORMAL_ERROR;
		}
	}

	*o_pMCash		= tmBRet.nCashPoint;			// CashPoint
	*o_pGiftCard	= tmBRet.nBonusPoint;			// BonusPoint
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;		// Total Cash
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CashItem_Masang_DirectConnect(SMasangBILL_REQ_DATA *i_pReqData, SMasangBILL_RET_DATA *o_pRetData)
/// \brief		// 2008-09-18 by cmkwon, 태국 WinnerOnline_Tha, 한국 Masang140_Kor 빌링 DBServer 접근을 Direct 로 수정 - 
/// \author		cmkwon
/// \date		2008-09-18 ~ 2008-09-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CashItem_Masang_DirectConnect(SMasangBILL_REQ_DATA *i_pReqData, SMasangBILL_RET_DATA *o_pRetData)
{
	// 2008-09-18 by cmkwon, 초기화
	o_pRetData->nCashPoint	= 0;
	o_pRetData->nBonusPoint	= 0;
	o_pRetData->nRetErrCode	= 0;

	// 2008-09-18 by cmkwon, Command 체크
	switch(i_pReqData->nCommand)
	{
	case 1:
	case 2:
		break;
	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CashItem_Masang_DirectConnect# command error !! Command(%d)\r\n", i_pReqData->nCommand);
			o_pRetData->nRetErrCode	= ERR_DB_INVALID_BILLING_COMMAND;
			return FALSE;
		}
	}

	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword(), g_pFieldGlobal->GetMainWndHandle());
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Masang_DirectConnect# connect error !! DBServer(%s:%d) DatabaseName(%s) UID(%s) PWD(%s)\r\n"
			, g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword());
		o_pRetData->nRetErrCode	= ERR_DB_CONNECT_FAIL;
		return FALSE;
	}

	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLINTEGER arrCB[15] = {SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS, SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS
							,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS};
	SQLRETURN ret = 0;

	o_pRetData->nRetErrCode	= ERR_DB_QUERY_FETCH_ERROR;		// 2008-09-18 by cmkwon, 기본값을 에러 상태로 할당한다.

	// 명령종류(1:잔액조회, 2:아이템구매)
	switch (i_pReqData->nCommand)
	{
	case 1:
		{
			o_pRetData->nRetErrCode	= ERR_DB_IS_NOT_ACCOUNTNAME;		// 2008-09-18 by cmkwon, 기본값을 에러 상태로 할당한다.

			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i_pReqData->nGameUID, 0,									&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szAccountName, 0,	&arrCB[2]);
			bRet = odbcStmt.ExecuteQuery("{call dbo.Billing_Get_Point(?,?)}");
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB Error] ExecuteQuery(Billing_Get_Point@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Masang_DirectConnect# ExecuteQuery(Billing_Get_Point@) error !! User(%s|%s|%s)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP);
				o_pRetData->nRetErrCode		= ERR_DB_QUERY_ERROR;
				return FALSE;
			}
			arrCB[1] = arrCB[2] = arrCB[3] = SQL_NTS;
			SQLBindCol(hstmt, 1, SQL_C_LONG, &o_pRetData->nRetErrCode, 0,		&arrCB[1]);
			SQLBindCol(hstmt, 2, SQL_C_LONG, &o_pRetData->nCashPoint, 0,		&arrCB[2]);
			SQLBindCol(hstmt, 3, SQL_C_LONG, &o_pRetData->nBonusPoint, 0,		&arrCB[3]);

			SQLSMALLINT    nColCnts          = 0;
			while(TRUE)
			{
				SQLNumResultCols(hstmt, &nColCnts);
				if(nColCnts <= 0)
				{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
					ret = SQLMoreResults(hstmt);
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				ret = SQLFetch(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-25 by cmkwon, Results set 처리
			}
			odbcStmt.FreeStatement();
			
			if(0 != o_pRetData->nRetErrCode)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Masang_DirectConnect# Fetch(Billing_Get_Point@) error !! User(%s|%s|%s) RetVal(%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, o_pRetData->nRetErrCode);
				return FALSE;
			}
		}
		break;
	case 2:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i_pReqData->nGameUID, 0,											&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szAccountName, 0,			&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szCharacterName, 0,		&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_ITEM_NUM, 0, i_pReqData->szItemNum, 0,					&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_ITEM_NAME, 0, i_pReqData->szItemName, 0,				&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i_pReqData->nBuyItemCount, 0,										&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i_pReqData->nItemUnitPrice, 0,										&arrCB[7]);
			SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MasangBILL_SIZE_MAX_IPADDRESS, 0, i_pReqData->szUserIP, 0,					&arrCB[8]);
			
			bRet = odbcStmt.ExecuteQuery("{call dbo.Billing_Buy_Item(?,?,?,?,?, ?,?,?)}");
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(Billing_Buy_Item@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Masang_DirectConnect# ExecuteQuery(Billing_Buy_Item@) error !! User(%s|%s|%s) Item(%s,%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, i_pReqData->szItemNum, i_pReqData->nBuyItemCount);
				o_pRetData->nRetErrCode		= ERR_DB_QUERY_ERROR;
				return FALSE;
			}
			arrCB[1] = arrCB[2] = arrCB[3] = SQL_NTS;
			SQLBindCol(hstmt, 1, SQL_C_LONG, &o_pRetData->nRetErrCode, 0,		&arrCB[1]);
			SQLBindCol(hstmt, 2, SQL_C_LONG, &o_pRetData->nCashPoint, 0,			&arrCB[2]);
			SQLBindCol(hstmt, 3, SQL_C_LONG, &o_pRetData->nBonusPoint, 0,		&arrCB[3]);
			
			SQLSMALLINT    nColCnts          = 0;
			while(TRUE)
			{
				SQLNumResultCols(hstmt, &nColCnts);
				if(nColCnts <= 0)
				{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
					ret = SQLMoreResults(hstmt);
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				ret = SQLFetch(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
					if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
					{
						break;
					}
					continue;
				}
				///////////////////////////////////////////////////////////////////////////////
				// 2008-07-25 by cmkwon, Results set 처리
			}
			odbcStmt.FreeStatement();

			if(0 != o_pRetData->nRetErrCode)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItem_Masang_DirectConnect# Fetch(Billing_Buy_Item@) error !! User(%s|%s|%s) RetVal(%d)\r\n"
					, i_pReqData->szAccountName, i_pReqData->szCharacterName, i_pReqData->szUserIP, o_pRetData->nRetErrCode);
				return FALSE;
			}
		}
		break;
		
	} // END - switch (i_pReqData->nCommand)

	return TRUE;
}
#endif // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_1

#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
_FUNC_S_REC	CFieldIOCPSocket::ms_pfRec4Apex		= NULL;		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
/// \author		cmkwon
/// \date		2009-11-04 ~ 2009-11-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
long CFieldIOCPSocket::SecurityApexSendData(int i_nCliIdx, const char *i_pBuff, int i_nBuffLen)
{
	CFieldIOCPSocket *pFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(i_nCliIdx);
	if(NULL == pFISoc
		|| FALSE == pFISoc->IsValidCharacter(FALSE, TRUE))	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::SecurityApexSendData# FSocket invalid !! ClientIdx(%d) \r\n", i_nCliIdx);
		return -1;
	}
	
// 2009-11-04 by cmkwon, 임시용
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityApexSendData# %s BufLen(%d) \r\n", GetCharacterString(pFISoc->GetCharacter(), string()), i_nBuffLen);

	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_APEX_REQ_APEXDATA, T_FC_MOVE_APEX_REQ_APEXDATA, pSMsg, SendBuf);
	pSMsg->cMsgType			= SECURITY_APEX_Cmd_ApexData;
	pSMsg->nApexDataLen		= i_nBuffLen;
	memcpy(pSMsg->szApexData, i_pBuff, min(i_nBuffLen, SECURITY_APEX_MaxPacketLen));	
	if(FALSE == pFISoc->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_APEX_REQ_APEXDATA)))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::SecurityApexSendData# fail to send !! ClientIdx(%d) \r\n", i_nCliIdx);
		return -1;
	}

	return 0;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
/// \author		cmkwon
/// \date		2009-11-04 ~ 2009-11-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
long CFieldIOCPSocket::SecurityApexKillUser(int i_nCliIdx, int i_nActon)
{
	CFieldIOCPSocket *pFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(i_nCliIdx);
	if(NULL == pFISoc
		|| FALSE == pFISoc->IsUsing())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::SecurityApexKillUser# FSocket invalid !! ClientIdx(%d) \r\n", i_nCliIdx);
		return -1;
	}
		
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::SecurityApexKillUser# kill user !! %s Action(%d) \r\n", GetCharacterString(pFISoc->GetCharacter(), string()), i_nActon);
	pFISoc->Close(0x14065);
	return 0;
}
#endif // END - #if defined(SERVICE_TYPE_THAI_SERVER_1) // 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 


#ifdef SERVICE_TYPE_KOREAN_SERVER_2
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Yedang(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/)
/// \brief		
///				// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - CashItem_Yedang() 인자 추가, UID32_t i_giveTargetCharUID=0
/// \author		cmkwon
/// \date		2006-09-13 ~ 2006-09-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Yedang(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, int i_nTotalPrice/*=0*/, UID32_t i_giveTargetCharUID/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 한국 Yedang 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

	SBILLING_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SBILLING_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));

	tmBReq.nCommand			= 1;					// 2007-09-13 by cmkwon, 기본값은 잔액조회 - // 명령종류(1:잔액조회, 2:아이템구매)
	STRNCPY_MEMSET(tmBReq.szServerName, g_pFieldGlobal->GetServerGroupName(), min(SIZE_MAX_SERVER_NAME, MSBILLING_SIZE_MAX_SERVER_NAME));
	STRNCPY_MEMSET(tmBReq.szUserID, m_character.AccountName, min(SIZE_MAX_ACCOUNT_NAME, MSBILLING_SIZE_MAX_ACCOUNT_NAME));
	sprintf(tmBReq.szUserNo, "%u", m_character.AccountUniqueNumber);
	STRNCPY_MEMSET(tmBReq.szCharName, m_character.CharacterName, min(SIZE_MAX_CHARACTER_NAME, MSBILLING_SIZE_MAX_CHARACTER_NAME));
	STRNCPY_MEMSET(tmBReq.szUserIP, this->GetPeerIP(), SIZE_MAX_IPADDRESS);
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= 2;		// 2007-09-13 by cmkwon, 아이템구매 - // 명령종류(1:잔액조회, 2:아이템구매)
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격

		///////////////////////////////////////////////////////////////////////////////
		// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - 선물받는 사람 설정하기
		if(IS_VALID_UNIQUE_NUMBER(i_giveTargetCharUID))
		{
			tmBReq.nCommand				= 3;	// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - // 명령종류(1:잔액조회, 2:아이템구매, 3:선물)
			STRNCPY_MEMSET(tmBReq.szGiftUserID, m_giveTargetCharacter.AccountName0, min(SIZE_MAX_ACCOUNT_NAME, MSBILLING_SIZE_MAX_ACCOUNT_NAME)); 
			_snprintf(tmBReq.szGiftUserNo, MSBILLING_SIZE_MAX_ACCOUNT_NO, "%u", m_giveTargetCharacter.AccountUID0);
			STRNCPY_MEMSET(tmBReq.szGiftCharName, m_giveTargetCharacter.CharacterName0, min(SIZE_MAX_CHARACTER_NAME, MSBILLING_SIZE_MAX_CHARACTER_NAME));

// 2009-08-24 by cmkwon, 이번 업데이트에서는 기능을 사용하지 않도록 처리 - 
// 			///////////////////////////////////////////////////////////////////////////////
// 			// 2009-08-18 by cmkwon, 예당 캐쉬샾 블럭 계정 체크 추가 - 
// 			if(FALSE == CashItem_Yedang_CheckAccount_byHTTP(m_giveTargetCharacter.AccountName0))
// 			{
// 				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang# %s ==> TargetAccount(%s) was blocked!! \r\n", GetCharacterString(this->GetCharacter(), string()), m_giveTargetCharacter.AccountName0);
// 				return ERR_CASH_INVALID_GIVE_TARGET_ACCOUNT;
// 			}
		}
	}

	// 2007-11-30 by cmkwon, 예당 빌리 버그 찾기 위한 시스템 로그 추가 - 함수 호출 전
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::CashItem_Yedang_ before call BillingReqExecute_ %s, ReqSize(%d), RetSize(%d) %s, %s\r\n"
		, GetCharacterString(&m_character, string()), sizeof(tmBReq), sizeof(tmBRet), tmBReq.szUserID, tmBReq.szCharName);

// 2008-07-30 by cmkwon, Yedang_Kor 빌링 DBServer 접근을 임시로 Direct 로 수정 - 아래와 같이 수정 함.
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-07-28 by cmkwon, 예당 빌링 예외(try) 처리, Release 모드 컴파일 옵션 /EHa 추가 해야 함 - 
// 	int nRetCode = 0;
// 	try
// 	{
// 		nRetCode = BillingReqExecute(&tmBReq, &tmBRet);
// 	}
// 	catch (...)
// 	{
// 		if(i_pItem)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_ try...catch Error(%d), %s ItemInfo(%d:%s) TotalPrice(%d) RetCode(%d, %d), GiftTargetCharacterUID(%u)\r\n"
// 				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), i_pItem->ItemNum, i_pItem->ItemName, i_nTotalPrice, nRetCode, tmBRet.nRetErrCode, i_giveTargetCharUID);
// 		}
// 		else
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_ try...catch Error(%d), %s RetCode(%d, %d)\r\n"
// 				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), nRetCode, tmBRet.nRetErrCode);
// 		}
// 	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-07-30 by cmkwon, Yedang_Kor 빌링 DBServer 접근을 임시로 Direct 로 수정 - 
 	int nRetCode = BillingReqExecuteDirectConnect(&tmBReq, &tmBRet);
	
	// 2007-11-30 by cmkwon, 예당 빌리 버그 찾기 위한 시스템 로그 추가 - 함수 호출 후
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::CashItem_Yedang_ after call BillingReqExecute_ %s\r\n", GetCharacterString(&m_character, string()));

	if(0 != nRetCode)
	{// 2007-09-14 by cmkwon, 메신저로 알려주신대로 빌링모듈의 정상처리 0, 에러 1로 변경
		if(i_pItem)
		{
			// 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - 선물받는 유저 정보 출력
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_ BillingReqExecute Error(%d), %s ItemInfo(%d:%s) TotalPrice(%d) RetCode(%d, %d), GiftTargetCharacterUID(%u)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), i_pItem->ItemNum, i_pItem->ItemName, i_nTotalPrice, nRetCode, tmBRet.nRetErrCode, i_giveTargetCharUID);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_ BillingReqExecute Error(%d), %s RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), nRetCode, tmBRet.nRetErrCode);
		}
		switch(tmBRet.nRetErrCode)
		{
		case ERR_DB_NO_ERROR:				// 2009-09-13 by cmkwon, success
			break;

		case ERR_DB_NOT_ENOUGH_MONEY:		// #define ERR_DB_NOT_ENOUGH_MONEY					2			// 소유한 Point(CashPoint+BonusPoint)가 구매하려는 아이템의 가격보다 작다
			return ERR_CASH_mgQueryMall_RESULT_CANNOT_PAYMENT;

		case ERR_DB_IS_NOT_ACCOUNTNAME:		// #define ERR_DB_IS_NOT_ACCOUNTNAME				1			// td_cash_bonus_point 테이블에 계정명이 없음
			return ERR_CASH_mgQueryMall_RESULT_NO_ACCOUNT;

		case ERR_DB_INVALID_ITEM:			// #define ERR_DB_INVALID_ITEM						4			// 구매하려는 아이템이 유효하지 않음 - ti_item_info 테이블에 없거나 IsDisable 필드가 0이 아니다
			return ERR_CASH_INVALID_ITEM_INFORMATION;

		default:
			{
				return ERR_CASH_NORMAL_ERROR;
			}
		}
	}


	*o_pMCash		= tmBRet.nCashPoint;			// CashPoint
	*o_pGiftCard	= tmBRet.nBonusPoint;			// BonusPoint
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;		// Total Cash
	return ERR_NO_ERROR;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			int CFieldIOCPSocket::BillingReqExecuteDirectConnect(SBILLING_REQ_DATA *i_pReqData, SBILLING_RET_DATA *o_pRetData)
/// \brief		// 2008-07-30 by cmkwon, Yedang_Kor 빌링 DBServer 접근을 임시로 Direct 로 수정 - 
/// \author		cmkwon
/// \date		2008-07-30 ~ 2008-07-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int CFieldIOCPSocket::BillingReqExecuteDirectConnect(SBILLING_REQ_DATA *i_pReqData, SBILLING_RET_DATA *o_pRetData)
{
	// 2008-07-30 by cmkwon, 초기화
	o_pRetData->nCashPoint	= 0;
	o_pRetData->nBonusPoint	= 0;
	o_pRetData->nRetErrCode	= 0;

	// 2008-07-30 by cmkwon, Command 체크
	switch(i_pReqData->nCommand)
	{
	case 1:
	case 2:
	case 3:
		break;
	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] BillingReqExecuteDirectConnect command error !! Command(%d)\r\n"
				, i_pReqData->nCommand);
			o_pRetData->nRetErrCode	= ERR_DB_INVALID_BILLING_COMMAND;
			return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
		}
	}

	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword(), g_pFieldGlobal->GetMainWndHandle());
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect connect error !! DBServer(%s:%d) DatabaseName(%s) UID(%s) PWD(%s)\r\n"
			, g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort(), g_pFieldGlobal->GetBillingDBServerDatabaseName(), g_pFieldGlobal->GetBillingDBServerUserID(), g_pFieldGlobal->GetBillingDBServerPassword());
		o_pRetData->nRetErrCode	= ERR_DB_CONNECT_FAIL;
		return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
	}

	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLINTEGER arrCB[15] = {SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS, SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS
							,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS,SQL_NTS};
	int nRetVal = 0;
	int nRetIDX = 0;
	// 명령종류(1:잔액조회, 2:아이템구매, 3:선물) // 2007-12-04 by cmkwon, 예당 선물하기 라이브러리 수정 - 
	switch (i_pReqData->nCommand)
	{
	case 1:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szUserID, 0,	&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NO, 0, i_pReqData->szUserNo, 0,		&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nRetVal), 0,											&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(o_pRetData->nCashPoint), 0,							&arrCB[4]);
			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0199));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(Billing_Get_Point@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect ExecuteQuery(SP_UserCashSearch@) error !! User(%s:%s)\r\n"
					, i_pReqData->szUserID, i_pReqData->szUserNo);
				o_pRetData->nRetErrCode		= ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}

			while(TRUE)
			{
				SQLRETURN ret = SQLMoreResults(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					break;
				}
			}
			odbcStmt.FreeStatement();
			
			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상
			// 1 ==> 오류			
			switch(nRetVal)
			{
			case 0:
				{
				}
				break;
			default:
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect Fetch(SP_UserCashSearch@) error !! User(%s:%s) RetVal(%d)\r\n"
						, i_pReqData->szUserID, i_pReqData->szUserNo, nRetVal);
					o_pRetData->nRetErrCode		= ERR_DB_QUERY_FETCH_ERROR;
					return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
				}
			}
		}
		break;
	case 2:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szUserID, 0,		&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NO, 0, i_pReqData->szUserNo, 0,			&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szCharName, 0,	&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_IPADDRESS, 0, i_pReqData->szUserIP, 0,			&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_SERVER_NAME, 0, i_pReqData->szServerName, 0,	&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ITEM_NUM, 0, i_pReqData->szItemNum, 0,			&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nBuyItemCount), 0,								&arrCB[7]);
			SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemUnitPrice), 0,							&arrCB[8]);
			SQLBindParameter(hstmt, 9, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nRetVal), 0,												&arrCB[9]);
			SQLBindParameter(hstmt, 10, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(o_pRetData->nCashPoint), 0,								&arrCB[10]);
			SQLBindParameter(hstmt, 11, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nRetIDX), 0,												&arrCB[11]);
			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0200));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(SP_GameCashUpdate@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect ExecuteQuery(SP_GameCashUpdate@) error !! User(%s:%s, %s %s %s) Item(%s,%d)\r\n"
					, i_pReqData->szUserID, i_pReqData->szUserNo, i_pReqData->szCharName, i_pReqData->szUserIP, i_pReqData->szServerName, i_pReqData->szItemNum, i_pReqData->nBuyItemCount);
				o_pRetData->nRetErrCode		= ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}
			
			while(TRUE)
			{
				SQLRETURN ret = SQLMoreResults(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					break;
				}
			}
			odbcStmt.FreeStatement();

			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상 과금
			// 1 ==> 캐쉬가 충분하지 않음
			// 2 ==> 구매상품이 일치하지 않음
			if(0 != nRetVal)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect Fetch(SP_GameCashUpdate@) error !! User(%s:%s) RetVal(%d) RetIDX(%d)\r\n"
					, i_pReqData->szUserID, i_pReqData->szUserNo, nRetVal, nRetIDX);
				switch(nRetVal)
				{
				case 1:
					{
						o_pRetData->nRetErrCode		= ERR_DB_INVALID_ITEM;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
					break;
				case 2:
					{
						o_pRetData->nRetErrCode		= ERR_DB_NOT_ENOUGH_MONEY;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
					break;
				default:
					{
						o_pRetData->nRetErrCode		= ERR_DB_QUERY_FETCH_ERROR;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
				}
			}
		}
		break;
	case 3:
		{
			SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szUserID, 0,			&arrCB[1]);
			SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NO, 0, i_pReqData->szUserNo, 0,				&arrCB[2]);
			SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szCharName, 0,		&arrCB[3]);
			SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_IPADDRESS, 0, i_pReqData->szUserIP, 0,				&arrCB[4]);
			SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_SERVER_NAME, 0, i_pReqData->szServerName, 0,		&arrCB[5]);
			SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ITEM_NUM, 0, i_pReqData->szItemNum, 0,				&arrCB[6]);
			SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nBuyItemCount), 0,									&arrCB[7]);
			SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(i_pReqData->nItemUnitPrice), 0,								&arrCB[8]);
			SQLBindParameter(hstmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NAME, 0, i_pReqData->szGiftUserID, 0,		&arrCB[9]);
			SQLBindParameter(hstmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_ACCOUNT_NO, 0, i_pReqData->szGiftUserNo, 0,		&arrCB[10]);
			SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, MSBILLING_SIZE_MAX_CHARACTER_NAME, 0, i_pReqData->szGiftCharName, 0,	&arrCB[11]);
			SQLBindParameter(hstmt, 12, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nRetVal), 0,													&arrCB[12]);
			SQLBindParameter(hstmt, 13, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(o_pRetData->nCashPoint), 0,									&arrCB[13]);
			SQLBindParameter(hstmt, 14, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &(nRetIDX), 0,													&arrCB[14]);
			
			bRet = odbcStmt.ExecuteQuery((char*)(PROCEDURE_080822_0201));
			if(FALSE == bRet)
			{
				odbcStmt.ProcessLogMessagesForStmt("[DB ERROR] ExecuteQuery(SP_GameCashUpdateGift@) Error !!\r\n");
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect ExecuteQuery(SP_GameCashUpdateGift@) error !! User(%s:%s, %s %s %s) Item(%s,%d) GiftTarget(%s:%s, %s)\r\n"
					, i_pReqData->szUserID, i_pReqData->szUserNo, i_pReqData->szCharName, i_pReqData->szUserIP, i_pReqData->szServerName, i_pReqData->szItemNum, i_pReqData->nBuyItemCount
					, i_pReqData->szGiftUserID, i_pReqData->szGiftUserNo, i_pReqData->szGiftCharName);
				o_pRetData->nRetErrCode		= ERR_DB_QUERY_ERROR;
				return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
			}
			
			while(TRUE)
			{
				SQLRETURN ret = SQLMoreResults(hstmt);
				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
				{
					break;
				}
			}
			odbcStmt.FreeStatement();
			
			///////////////////////////////////////////////////////////////////////////////
			// 0 ==> 정상 과금
			// 1 ==> 캐쉬가 충분하지 않음
			// 2 ==> 구매상품이 일치하지 않음
			if(0 != nRetVal)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] BillingReqExecuteDirectConnect Fetch(SP_GameCashUpdateGift@) error !! User(%s:%s) RetVal(%d) RetIDX(%d)\r\n"
					, i_pReqData->szUserID, i_pReqData->szUserNo, nRetVal, nRetIDX);
				switch(nRetVal)
				{
				case 1:
					{
						o_pRetData->nRetErrCode		= ERR_DB_INVALID_ITEM;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
					break;
				case 2:
					{
						o_pRetData->nRetErrCode		= ERR_DB_NOT_ENOUGH_MONEY;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
					break;
				default:
					{
						o_pRetData->nRetErrCode		= ERR_DB_QUERY_FETCH_ERROR;
						return TRUE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
					}
				} // END - switch(nRetVal)
			}
		}
		break;
	} // END - switch (i_pReqData->nCommand)

	return FALSE;	// 2008-07-30 by cmkwon, 정상처리 0, 에러 1
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-18 by cmkwon, 예당 캐쉬샾 블럭 계정 체크 추가 - CFieldIOCPSocket::CashItem_Yedang_CheckAccount_byHTTP
/// \author		cmkwon
/// \date		2009-08-18 ~ 2009-08-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CashItem_Yedang_CheckAccount_byHTTP(char * i_szTargetAccName)
{
	///////////////////////////////////////////////////////////////////////////////
	// 로그인하는 게임코드
	//	PT1= 1, clubAudition= 2, PT2= 3, AceOnline= 4, paeOnline= 7, PT3= 8, BandMaster= 9
	GenericHTTPClient httpCli;	
    httpCli.InitilizePostArguments();
	httpCli.AddPostArguments("userID", i_szTargetAccName);
	httpCli.AddPostArguments("gameID", 4);
	
	static char *szServURL	= "gpUserAuth.ydonline.com";
	static int nServPort	= 8789;
	char szURL[1024];
	sprintf(szURL, "http://%s:%d/gpUserInfo.asmx/GetBlockUserChk_UserID", szServURL, nServPort);
	BOOL bRet = httpCli.Request(szURL, GenericHTTPClient::RequestPostMethod);
	if(FALSE == bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_CheckAccount_byHTTP# call Request fail !!, %s URL(%s) \r\n"
			, GetCharacterString(this->GetCharacter(), string()), szURL);
		return FALSE;
	}
	
    LPCTSTR szResponseMsg = httpCli.QueryHTTPResponse();
	if(0 >= strlen(szResponseMsg))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_CheckAccount_byHTTP# no response message !!, %s URL(%s) \r\n"
			, GetCharacterString(this->GetCharacter(), string()), szURL);
		return FALSE;
	}
	int nErrCode = httpCli.LoadXMLFromQueryHTTPResponse();
	if(0 != nErrCode)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Yedang_CheckAccount_byHTTP# loadXML fail 1 !!, %s URL(%s) ResponseMsg(%s), ErrCode(%d)\r\n"
			, GetCharacterString(this->GetCharacter(), string()), szURL, szResponseMsg, nErrCode);
		return FALSE;
	}
	
	char szSpReturnNo[1024];
	MEMSET_ZERO(szSpReturnNo, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szSpReturnNo, 1024, "//int"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 2!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		return FALSE;
	}

	// -1 이면 정상 계정, 1이면 블럭 계정 ==> 그러므로 -1이 아니면 에러를 리턴하여 선물 불가 처리
	int nSpReturnNo = atoi(szSpReturnNo);
	if(-1 != nSpReturnNo)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 3!!, URL(%s), %s, SpReturnNo(%d)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), nSpReturnNo);
		return FALSE;
	}
	
	return TRUE;
}

#endif // END - #ifdef SERVICE_TYPE_KOREAN_SERVER_2


#ifdef SERVICE_TYPE_RUSSIAN_SERVER_1
///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CashItemMoneyPay_Russia(INT *o_pTotalMoney, INT *o_pMCash, ITEM *i_pItem=NULL, INT i_nItemCount=0)
/// \brief		// 2008-09-09 by dhjin, 러시아 빌링 관련 - 캐쉬 정보 얻어오기 
/// \author		dhjin
/// \date		2008-09-09 ~ 2008-09-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CashItemMoneyPay_Russia(INT *o_pTotalMoney, INT *o_pMCash, ITEM *i_pItem/*=NULL*/, INT i_nItemCount/*=0*/)	
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 러시아 Innova 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;					// CashPoint
		*o_pTotalMoney	= *o_pMCash;				// Total Cash
		return ERR_NO_ERROR;
	}
#endif

// 2010-04-26 by cmkwon, 러시아 Innva 인증/빌링 시스템 변경 - 아래와 같이 New 라이브러리로 변경
// 	CODBCStatement odbcStmt;
// 	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetDBServerIP(), g_pFieldGlobal->GetDBServerPort(), g_pFieldGlobal->GetDBServerDatabaseName(), (LPCSTR)g_pFieldGlobal->GetODBCUID(), (LPCSTR)g_pFieldGlobal->GetODBCPASSWORD(), g_pFieldGlobal->GetMainWndHandle());
// 	if (!bRet)
// 	{
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CashItemCheckBalance connect error !!\r\n");
// 		return FALSE;
// 	}
// 
// 	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
// 	SQLRETURN ret = 0;
// 
// 	SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, SIZE_MAX_ACCOUNT_NAME, 0, this->m_character.AccountName, 0, NULL);
// 	SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, this->GetPeerIP(), 0, NULL);
// 	ret = SQLExecDirect(hstmt, (UCHAR*)"{call dbo.Usp_Check_Balance(?,?)}", SQL_NTS);
// 	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO && ret != SQL_NO_DATA)
// 	{
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Usp_Check_Balance execute error !!\r\n");
// 		SQLFreeStmt(hstmt, SQL_CLOSE);
// 		return FALSE;
// 	}		
// 
// 	int	nResult = 0;
// 	SQLBindCol(hstmt, 1, SQL_C_ULONG, &(nResult), 0, NULL);
// 	SQLBindCol(hstmt, 2, SQL_C_ULONG, o_pMCash, 0, NULL);
// 
// 	SQLSMALLINT    nColCnts          = 0;
// 	while(TRUE)
// 	{
// 		SQLNumResultCols(hstmt, &nColCnts);
// 		if(nColCnts <= 0)
// 		{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
// 			ret = SQLMoreResults(hstmt);
// 			if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 			{
// 				break;
// 			}
// 			continue;
// 		}
// 		ret = SQLFetch(hstmt);
// 		if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 		{
// 			ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
// 			if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 			{
// 				break;
// 			}
// 			continue;
// 		}
// 	}
// 	SQLFreeStmt(hstmt, SQL_CLOSE);
// 
// 	if(0 != nResult)
// 	{
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Usp_Check_Balance Result error !!\r\n");
// 		return FALSE;
// 	}	
// 	*o_pTotalMoney = *o_pMCash;
// 
// 	if(NULL != i_pItem)
// 	{
// 		SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, SIZE_MAX_ACCOUNT_NAME, 0, this->m_character.AccountName, 0, NULL);
// 		SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, this->GetPeerIP(), 0, NULL);
// 		SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, SIZE_MAX_CHARACTER_NAME, 0, this->m_character.CharacterName, 0, NULL);
// 		char szItemNum[20];
// 		MEMSET_ZERO(&szItemNum, 20);
// 		itoa(i_pItem->ItemNum, szItemNum, 10);
// 		SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, szItemNum, 0, NULL);
// 		SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &i_nItemCount, 0, NULL);
// 		SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &i_pItem->CashPrice, 0, NULL);
// 		SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, SIZE_MAX_SERVER_NAME, 0, g_pFieldGlobal->GetServerGroupName(), 0, NULL);
// 		int gameserverID = g_pFieldGlobal->GetMGameServerID();
// 		SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &gameserverID, 0, NULL);
// 
// 		ret = SQLExecDirect(hstmt, (UCHAR*)"{call dbo.Usp_Sell_Item(?,?,?,?,?,?,?,?)}", SQL_NTS);
// 		if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO && ret != SQL_NO_DATA)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Usp_Sell_Item execute error !!\r\n");
// 			SQLFreeStmt(hstmt, SQL_CLOSE);
// 			return FALSE;
// 		}		
// 
// 		int	nResult = 0;
// 		char szBillingLogID[26];
// 		MEMSET_ZERO(&szBillingLogID, 26);
// 		SQLBindCol(hstmt, 1, SQL_C_ULONG, &(nResult), 0, NULL);
// 		SQLBindCol(hstmt, 2, SQL_C_CHAR, &(szBillingLogID), 26, NULL);
// 
// 		SQLSMALLINT    nColCnts          = 0;
// 		while(TRUE)
// 		{
// 			SQLNumResultCols(hstmt, &nColCnts);
// 			if(nColCnts <= 0)
// 			{// 2008-07-25 by cmkwon, ResultCols 0 이면 적용된 RowCount 이다 
// 				ret = SQLMoreResults(hstmt);
// 				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 				{
// 					break;
// 				}
// 				continue;
// 			}
// 			ret = SQLFetch(hstmt);
// 			if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 			{
// 				ret = SQLMoreResults(hstmt);                 // 2008-07-25 by cmkwon, 다음 Results 가 있는지를 한번더 체크한다.
// 				if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
// 				{
// 					break;
// 				}
// 				continue;
// 			}
// 		}
// 		SQLFreeStmt(hstmt, SQL_CLOSE);
// 
// 		if(0 == nResult)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] Usp_Sell_Item Result error !!\r\n");
// 			return FALSE;
// 		}	
// 		*o_pMCash = *o_pMCash - (i_pItem->CashPrice * 1);
// 		*o_pTotalMoney = *o_pMCash;
// 
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[CashItem] BillingLodID = (%s)  User(AccountUID = %d, AccountName = %s, CharacterUID = %d, CharacterName = %s)  Item(ItemNum = %d, CashPrice = %d, ItemCount = %d) \r\n"
// 						, szBillingLogID
// 						, m_character.AccountUniqueNumber, m_character.AccountName
// 						, m_character.CharacterUniqueNumber, m_character.CharacterName
// 						, i_pItem->ItemNum, i_pItem->CashPrice, 1);
// 
// 	}// if(NULL != i_pItem)
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-26 by cmkwon, 러시아 Innva 인증/빌링 시스템 변경 - 
	*o_pTotalMoney		= 0;
	*o_pMCash			= 0;
	if(NULL == i_pItem)
	{
		if(FALSE == ms_pFieldIOCP->INNBILL_GetMoney(m_character.AccountName, o_pTotalMoney))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] innBill CFieldIOCPSocket::CashItemMoneyPay_Russia# GetMoney fail !! %s \r\n", GetCharacterString(GetCharacter(), string()));
			return FALSE;
		}
		*o_pMCash		= *o_pTotalMoney;
		return TRUE;
	}

	UID64_t		nBillTranID = 0;
	if(FALSE == ms_pFieldIOCP->INNBILL_BuyItem(m_character.AccountName, o_pTotalMoney, i_pItem, m_character.CharacterName, &nBillTranID))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] innBill CFieldIOCPSocket::CashItemMoneyPay_Russia# GetMoney fail !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return FALSE;
	}		
	*o_pMCash		= *o_pTotalMoney;
	return TRUE;
}
#endif // END -  #ifdef SERVICE_TYPE_RUSSIAN_SERVER_1

#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Netpower(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, INT i_nItemCount/*=0*/)
/// \brief		// 2008-09-23 by cmkwon, 지원 서비스 추가(대만 Netpower_Tpe) - 
/// \author		cmkwon
/// \date		2008-09-23 ~ 2008-09-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Netpower(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, INT i_nItemCount/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 대만 Netpower 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif

	SNETBILL_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SNETBILL_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));
	
	tmBReq.nCommand			= 1;					// 2008-11-13 by cmkwon, 기본값은 잔액조회 - // 명령종류(1:잔액조회, 2:아이템구매)
	STRNCPY_MEMSET(tmBReq.szAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(tmBReq.szCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), SIZE_MAX_IPADDRESS);
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= 2;			// 2008-11-13 by cmkwon, 아이템 구매
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		STRNCPY_MEMSET(tmBReq.szItemName, i_pItem->ItemName, SIZE_MAX_ITEM_NAME);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격		
	}
	
	Err_t nErrCode = CashItem_Netpower_byHTTP(&tmBReq, &tmBRet);	
	if(0 != nErrCode)
	{
		if(i_pItem)
		{			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Netpower# CashItem_Netpower_byHTTP error(%d), %s ItemInfo(%d:%s) ItemPrice(%d) RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), i_pItem->ItemNum, i_pItem->ItemName, tmBReq.nItemUnitPrice, nErrCode, tmBRet.nRetErrCode);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Netpower# CashItem_Netpower_byHTTP error(%d), %s RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), nErrCode, tmBRet.nRetErrCode);
		}
		return tmBRet.nRetErrCode;
	}
	
	*o_pMCash		= tmBRet.nCashPoint;					// RealCash
	*o_pGiftCard	= tmBRet.nBonusPoint;					// BonusCash
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// Total Cash
	
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
/// \brief		// 2008-11-13 by cmkwon, 대만 Netpower_Tpe 빌링 시스템 구축 - 
/// \author		cmkwon
/// \date		2008-11-13 ~ 2008-11-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
{
	switch(i_pReqData->nCommand)
	{
	case 1:
		{
			return this->CashItem_Netpower_byHTTP_GetCashPoint(i_pReqData, o_pRetData);
		}
		break;
	case 2:
		{
			return this->CashItem_Netpower_byHTTP_BuyCashItem(i_pReqData, o_pRetData);
		}
		break;
	}

	o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
	return o_pRetData->nRetErrCode;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
/// \brief		// 2008-11-13 by cmkwon, 대만 Netpower_Tpe 빌링 시스템 구축 - 
/// \author		cmkwon
/// \date		2008-11-13 ~ 2008-11-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
{
	GenericHTTPClient httpCli;	
    httpCli.InitilizePostArguments();
	httpCli.AddPostArguments("memberNo", this->GetCharacter()->AccountName);
	httpCli.AddPostArguments("serviceCode", NETBILL_SERVICE_CODE_FOR_BILLING);		// 00001->데카론, 00002->서든어택, 00003->ACEonline

	char szURL[1024];
	sprintf(szURL, "http://%s:%d/GameServerInterface.asmx/GetUserCashAmount", g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort());
	BOOL bRet = httpCli.Request(szURL, GenericHTTPClient::RequestPostMethod);
	if(FALSE == bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# call Request fail !!, URL(%s), %s\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()));
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
    LPCTSTR szResponseMsg = httpCli.QueryHTTPResponse();
	if(0 >= strlen(szResponseMsg))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# no response message !!, URL(%s), %s\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()));
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	int nErrCode = httpCli.LoadXMLFromQueryHTTPResponse();
	if(0 != nErrCode)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 1!!, URL(%s), %s, ResponseMsg(%s), ErrCode(%d)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg, nErrCode);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
	char szSpReturnNo[1024];
	MEMSET_ZERO(szSpReturnNo, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szSpReturnNo, 1024, "//SpReturnNo"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 2!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	int nSpReturnNo = atoi(szSpReturnNo);
	if(0 != nSpReturnNo)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 3!!, URL(%s), %s, SpReturnNo(%d)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), nSpReturnNo);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
	char szRemainedBalanceAmount[1024];
	MEMSET_ZERO(szRemainedBalanceAmount, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szRemainedBalanceAmount, 1024, "//RemainedBalanceAmount"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_GetCashPoint# loadXML fail 4!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
	o_pRetData->nCashPoint		= atoi(szRemainedBalanceAmount);
	o_pRetData->nRetErrCode		= ERR_NO_ERROR;
	return o_pRetData->nRetErrCode;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
/// \brief		// 2008-11-13 by cmkwon, 대만 Netpower_Tpe 빌링 시스템 구축 - 
/// \author		cmkwon
/// \date		2008-11-13 ~ 2008-11-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////]
Err_t CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem(SNETBILL_REQ_DATA *i_pReqData, SNETBILL_RET_DATA *o_pRetData)
{
	GenericHTTPClient httpCli;	

	char szReqBuyItemInfo[1024];
	MEMSET_ZERO(szReqBuyItemInfo, 1024);
	sprintf(szReqBuyItemInfo, "<ITEM_LIST><ITEM SERVICE_CODE=\"%s\"  GAME_ITEM_NO=\"ACE-%s\" ITEM_COUNT=\"%d\" ITEM_PRICE=\"%d\"/></ITEM_LIST>"
		, NETBILL_SERVICE_CODE_FOR_BILLING, i_pReqData->szItemNum, i_pReqData->nBuyItemCount, i_pReqData->nItemUnitPrice);

    httpCli.InitilizePostArguments();
	httpCli.AddPostArguments("serviceCode", NETBILL_SERVICE_CODE_FOR_BILLING);			// 00001->데카론, 00002->서든어택, 00003->ACEonline
	httpCli.AddPostArguments("xmlItemList", szReqBuyItemInfo);							// 구매 대상 아이템 정보
	httpCli.AddPostArguments("useSort", "GAM");											// 구매처 코드(WEB:웹, GAM:게임, ETC:기타)
	httpCli.AddPostArguments("targetMemberNo", this->GetCharacter()->AccountName);		// 구매자 회원 번호
	httpCli.AddPostArguments("targetMemberID", "");										// 구매자 회원 ID
	httpCli.AddPostArguments("targetUserIP", this->GetPeerIP());						// 구매자 접속 IP 주소
	httpCli.AddPostArguments("targetCharName", this->GetCharacter()->CharacterName);	// 구매자 케릭터명
	httpCli.AddPostArguments("giftTag", "N");											// 선물 여부 [ Y / N ]
	httpCli.AddPostArguments("giftTargetName", "");										// 선물 받을 사람명(케릭터명)
	httpCli.AddPostArguments("billGoodsCode", "");										// 요금제 코드
	httpCli.AddPostArguments("serverCode", "");											// 서버 코드
	httpCli.AddPostArguments("connectionNo", "");										// 게임 접속 번호
	httpCli.AddPostArguments("pcbangNo", "");											// 피씨방 번호
	httpCli.AddPostArguments("agencyNo", "");											// 총판 번호
	httpCli.AddPostArguments("note", i_pReqData->szItemName);							// 비고 (보통은 아이템명)
	httpCli.AddPostArguments("payPassword", "");										// 구매 비밀 번호[MD5 Hashed String], 사용하지 않는 서비스라면 Empty String
	httpCli.AddPostArguments("period", "0");											// 기간제 아이템 유효기간(초) [데카론 전용. 여타게임은 0]
	httpCli.AddPostArguments("itemIndex", "0");											// 구매대상 아이템 인덱스 [데카론 전용. 여타게임은 0]
	httpCli.AddPostArguments("itemName", "");											// 구매대상 아이템 명 [데카론 전용. 여타게임은 Empty String]
	httpCli.AddPostArguments("itemSerialNo", "");										// 구매대상 아이템 시리얼 [데카론 전용. 여타게임은 Empty String]

	
	char szURL[1024];
	sprintf(szURL, "http://%s:%d/GameServerInterface.asmx/PaymentForGame", g_pFieldGlobal->GetBillingDBServerIP(), g_pFieldGlobal->GetBillingDBServerPort());
	BOOL bRet = httpCli.Request(szURL, GenericHTTPClient::RequestPostMethod);
	if(FALSE == bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# call Request fail !!, URL(%s), %s\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()));
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
    LPCTSTR szResponseMsg = httpCli.QueryHTTPResponse();
	if(0 >= strlen(szResponseMsg))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# no response message !!, URL(%s), %s\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()));
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	int nErrCode = httpCli.LoadXMLFromQueryHTTPResponse();
	if(0 != nErrCode)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 1!!, URL(%s), %s, ResponseMsg(%s), ErrCode(%d)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg, nErrCode);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
	char szSpReturnNo[1024];
	MEMSET_ZERO(szSpReturnNo, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szSpReturnNo, 1024, "//SpReturnNo"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 2!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	int nSpReturnNo = atoi(szSpReturnNo);
	if(0 != nSpReturnNo)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 3!!, URL(%s), %s, SpReturnNo(%d)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), nSpReturnNo);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	
	char szRemainedBalanceAmount[1024];
	MEMSET_ZERO(szRemainedBalanceAmount, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szRemainedBalanceAmount, 1024, "//RemainedBalanceAmount"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 4!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}
	o_pRetData->nCashPoint		= atoi(szRemainedBalanceAmount);

	char szTransactionID[1024];
	MEMSET_ZERO(szTransactionID, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szTransactionID, 1024, "//TransactionID"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 5!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}

	char szApprovalNo[1024];
	MEMSET_ZERO(szApprovalNo, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szApprovalNo, 1024, "//ApprovalNo"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 6!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}

	char szEtcInfo[1024];
	MEMSET_ZERO(szEtcInfo, 1024);
	if(FALSE == httpCli.GetTextFromXMLLoaderByNodeName(szEtcInfo, 1024, "//EtcInfo"))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR]CFieldIOCPSocket::CashItem_Netpower_byHTTP_BuyCashItem# loadXML fail 6!!, URL(%s), %s, ResponseMsg(%s)\r\n"
			, szURL, GetCharacterString(this->GetCharacter(), string()), szResponseMsg);
		o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
		return o_pRetData->nRetErrCode;
	}

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Buy Item success !!, %s, ItemNum(%s), RemainedCashPoint(%d)\r\n"
		, GetCharacterString(this->GetCharacter(), string()), i_pReqData->szItemNum, o_pRetData->nCashPoint);
	
	o_pRetData->nRetErrCode		= ERR_NO_ERROR;
	return o_pRetData->nRetErrCode;
}

#endif // END -  #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)


///////////////////////////////////////////////////////////////////////////////
#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Arario(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, INT i_nCurTotalMoney/*=0*/)
/// \brief		// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - 
/// \author		cmkwon
/// \date		2008-12-18 ~ 2008-12-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Arario(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pGiftCard, ITEM *i_pItem/*=NULL*/, INT i_nCurTotalMoney/*=0*/)
{
#if defined(_DEBUG)
	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-02 by cmkwon, 내부 테섭에서 캐쉬 포인트 관련 수정(디버그 모드시만 동작) - 일본 Arario 처리
	if(g_pFieldGlobal->InMasangServer())
	{
		*o_pMCash		= 50000;																// CashPoint
		*o_pGiftCard	= (NULL == i_pItem) ? *o_pMCash : *o_pMCash - i_pItem->CashPrice;		// BonusPoint
		*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;												// Total Cash
		return ERR_NO_ERROR;
	}
#endif
	
	SARABILL_REQ_DATA	tmBReq;		MEMSET_ZERO(&tmBReq, sizeof(tmBReq));
	SARABILL_RET_DATA	tmBRet;		MEMSET_ZERO(&tmBRet, sizeof(tmBRet));
	
	tmBReq.nCommand			= 1;									// 2008-12-18 by cmkwon, 기본값은 잔액조회 - // 명령종류(1:잔액조회, 2:아이템구매)
	STRNCPY_MEMSET(tmBReq.szAccountName, m_character.AccountName, ARABILL_SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(tmBReq.szCharacterName, m_character.CharacterName, ARABILL_SIZE_MAX_CHARACTER_NAME);
	tmBReq.uiCharacterUID	= m_character.CharacterUniqueNumber;	// 2008-12-18 by cmkwon, 캐릭터 고유번호 설정
	STRNCPY_MEMSET(tmBReq.szUserIP, GetPeerIP(), ARABILL_SIZE_MAX_IPADDRESS);
	tmBReq.nCurTotalMoney	= i_nCurTotalMoney;						// 2008-12-18 by cmkwon, 현재의 캐쉬 포인트 설정
	if(i_pItem)
	{// if buy item
		
		tmBReq.nCommand				= 2;			// 2008-12-18 by cmkwon, 아이템 구매
		sprintf(tmBReq.szItemNum, "%d", i_pItem->ItemNum);
		STRNCPY_MEMSET(tmBReq.szItemName, i_pItem->ItemName, ARABILL_SIZE_MAX_ITEM_NAME);
		tmBReq.nBuyItemCount		= 1;					// 구매 카운트
		tmBReq.nItemUnitPrice		= i_pItem->CashPrice;	// 1개당 가격		
	}
	
	Err_t nErrCode = CashItem_Arario_ByLibary(&tmBReq, &tmBRet);	
	if(0 != nErrCode)
	{
		if(i_pItem)
		{			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Arario# call CashItem_Arario_ByLibary() error(%d), %s ItemInfo(%d:%s) ItemPrice(%d) RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), i_pItem->ItemNum, i_pItem->ItemName, tmBReq.nItemUnitPrice, nErrCode, tmBRet.nRetErrCode);
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Arario# call CashItem_Arario_ByLibary() error(%d), %s RetCode(%d, %d)\r\n"
				, tmBRet.nRetErrCode, GetCharacterString(&m_character, string()), nErrCode, tmBRet.nRetErrCode);
		}
		return tmBRet.nRetErrCode;
	}
	
	*o_pMCash		= tmBRet.nCashPoint;					// RealCash
	*o_pGiftCard	= tmBRet.nBonusPoint;					// BonusCash
	*o_pTotalMoney	= *o_pMCash + *o_pGiftCard;				// Total Cash
	
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CashItem_Arario_ByLibary(SARABILL_REQ_DATA *i_pReqData, SARABILL_RET_DATA *o_pRetData)
/// \brief		// 2008-12-18 by cmkwon, 일본 Arario 외부인증, 빌링 모듈 적용하기 - 
/// \author		cmkwon
/// \date		2008-12-18 ~ 2008-12-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CashItem_Arario_ByLibary(SARABILL_REQ_DATA *i_pReqData, SARABILL_RET_DATA *o_pRetData)
{	
	// 2008-12-22 by cmkwon, 일본 Arario 외부인증,빌링 모듈 설정 파일(*.ini) 경로 설저하기 - 
	static BOOL bSetedIniFilePathFlag = FALSE;
	if(FALSE == bSetedIniFilePathFlag)
	{
		WCHAR wszConfigRoot[MAX_PATH];
		MEMSET_ZERO(wszConfigRoot, sizeof(WCHAR) * MAX_PATH);
		
		MultiByteToWideChar(CP_ACP, 0, CONFIG_ROOT, strlen(CONFIG_ROOT), wszConfigRoot, sizeof(WCHAR) * MAX_PATH);
		SetBillingInfoPath(wszConfigRoot);
		bSetedIniFilePathFlag		= TRUE;		// 2008-12-22 by cmkwon, 설정 한번만 처리되도록
	}

	switch(i_pReqData->nCommand)
	{
	case 1:	// 잔액 조회
		{
			ARTP_RCS_GETRIOCASH		in;		MEMSET_ZERO(&in, sizeof(in));
			ARTP_RET_RCS_GETRIOCASH	out;	MEMSET_ZERO(&out, sizeof(out));
			
			// 2008-12-19 by cmkwon, 입력 형식
			// in.m_usn				<= -1(고정된 값)
			// in.m_memberID		<= 유니코드 계정 설정
			in.m_usn				= -1;	// 2008-12-19 by cmkwon, -1로 설정해야지만 멤버 아이디를 인식
			MultiByteToWideChar(CP_ACP, 0, i_pReqData->szAccountName, strlen(i_pReqData->szAccountName), in.m_memberID, ARTP_RCS_ROOT::member_len);

			int result = GetRioCash( in, out );	
			if(0 != result)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Arario_ByLibary# call GetRioCash() error !! %s result(%d) out.result(%d, %d) \r\n"
					, GetCharacterString(&m_character, string()), result, out.m_result, out.m_subResult);

				o_pRetData->nRetErrCode		= ERR_CASH_mgQueryMall_ERROR;
				return o_pRetData->nRetErrCode;
			}

			o_pRetData->nCashPoint	= out.m_cash;
		}
		break;
	case 2:	// 아이템 구매
		{
			ARTP_RCS_USERIOCASH		in;		MEMSET_ZERO(&in, sizeof(in));
			ARTP_RET_RCS_USERIOCASH	out;	MEMSET_ZERO(&out, sizeof(out));

			// 2008-12-19 by cmkwon, 입력 형식
			// in.m_usn				<= -1(고정된 값)
			// in.m_memberID		<= (유니코드) 계정 설정
			// in.m_clientRemainder	<= 현재 잔액 -- 빌링DB상의 잔액과 비교목적으로 사용;
			// in.m_itemID			<= (유니코드)아이템 아이디 -- 빌링DB에 미리 등록되어 있어야함;
			// in.m_gameCode		<= 게임코드 -- 에이스온라인 CM001003;
			// in.m_serverID		<= (유니코드) 서버군 이름
			// in.m_characterID		<= 캐릭터 고유 넘버;
			in.m_usn				= -1;	// 2008-12-19 by cmkwon, -1로 설정해야지만 멤버 아이디를 인식
			MultiByteToWideChar(CP_ACP, 0, i_pReqData->szAccountName, strlen(i_pReqData->szAccountName), in.m_memberID, ARTP_RCS_ROOT::member_len);
			in.m_clientRemainder	= i_pReqData->nCurTotalMoney;
			MultiByteToWideChar(CP_ACP, 0, i_pReqData->szItemNum, strlen(i_pReqData->szItemNum), in.m_itemID, ARTP_RCS_ROOT::item_len);			
			MultiByteToWideChar(CP_ACP, 0, ARABILL_ACEONLINE_GAME_CODE, strlen(ARABILL_ACEONLINE_GAME_CODE), in.m_gameCode, ARTP_RCS_ROOT::gamecode_len);			
			MultiByteToWideChar(CP_ACP, 0, g_pFieldGlobal->GetServerGroupName(), strlen(g_pFieldGlobal->GetServerGroupName()), in.m_serverID, ARTP_RCS_ROOT::servercode_len);			
			in.m_characterID		= i_pReqData->uiCharacterUID;

			int result = UseRioCash(in, out);	
			if(0 != result)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CashItem_Arario_ByLibary# call UseRioCash() error !! %s result(%d) out.result(%d, %d) ItemInfo(%s:%s) CurTotalMoney(%d)\r\n"
					, GetCharacterString(&m_character, string()), result, out.m_result, out.m_subResult, i_pReqData->szItemNum, i_pReqData->szItemName, i_pReqData->nCurTotalMoney);
				
				o_pRetData->nRetErrCode		= ERR_CASH_mgQueryMall_ERROR;
				return o_pRetData->nRetErrCode;
			}
			
			o_pRetData->nCashPoint	= out.m_remainder;
		}
		break;
	default:
		{
			o_pRetData->nRetErrCode	= ERR_CASH_NORMAL_ERROR;
			return o_pRetData->nRetErrCode;
		}
	}

	o_pRetData->nRetErrCode	= ERR_NO_ERROR;
	return o_pRetData->nRetErrCode;
}

#endif // END -  #if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
///////////////////////////////////////////////////////////////////////////////

BOOL CFieldIOCPSocket::ms_bUsingNProtect		= FALSE;		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 정의

#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - ERROR 레벨의 로그와 DEBUG 레벨의 로그 정보를 받는 콜백
/// \author		cmkwon
/// \date		2009-03-09 ~ 2009-03-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
GGAUTHS_API void NpLog(int mode, char *msg)
{
	// 2009-04-17 by cmkwon, 일본 nProtect 시스템 로그에 NPLOG_DEBUG를 제외한다.
	//if(mode & (NPLOG_DEBUG|NPLOG_ERROR))
	if(mode & (NPLOG_ERROR))
	{
		g_pFieldGlobal->WriteSystemLogEX(FALSE, "[Notify] nProtect NpLog#, Msg(%s) \r\n", msg);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - CS인증 버전 및 프로토콜이 업데이트 된 정보를 받는 콜백
/// \author		cmkwon
/// \date		2009-03-09 ~ 2009-03-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
GGAUTHS_API void GGAuthUpdateCallback(PGG_UPREPORT report)
{
	g_pFieldGlobal->WriteSystemLogEX(FALSE, "[Notify] nProtect GGAuth version update [%s]:[%ld] -> [%ld] \r\n"
		, (report->nType==1)?"GameGuard Ver" : "Protocol Num", report->dwBefore, report->dwNext);
}
#endif // END - #if defined(SERVICE_TYPE_JAPANESE_SERVER_1)


///////////////////////////////////////////////////////////////////////////////
/// \fn			INT CFieldIOCPSocket::GetMaxBuyableDayOfMembership(void)
/// \brief		// 2007-10-01 by cmkwon, 멤버쉬 구입 가능 최대 일수 - 나라별로 다르다
/// \author		cmkwon
/// \date		2007-10-01 ~ 2007-10-01
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
INT CFieldIOCPSocket::GetMaxBuyableDayOfMembership(void)
{
	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-필수] 추가 언어시에 멤버쉽 구입 가능 최대 일수

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_VIETNAMESE:	return TERM_MONTHLYPAY_MAX_BUY_ENABLE_DAY;	// 2007-10-01 by cmkwon, 180일
	case LANGUAGE_TYPE_KOREAN:		return 60;									// 2007-10-08 by cmkwon, 60일
	case LANGUAGE_TYPE_CHINESE:		return 3650;								// 2007-10-01 by cmkwon, 3650일(10년)
	case LANGUAGE_TYPE_ENGLISH:
		{
#if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
			return 60;		// 2008-08-14 by cmkwon, 캐나다 Wikigames_Eng 멤버쉽 구매 최대 2개월로 설정
#endif
			return 730;									// 2008-04-03 by cmkwon, Gameforge4D 멤버쉽 최대 일수(730일=24개월)
		}
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:		// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 
	case LANGUAGE_TYPE_FRENCH:		// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 
	case LANGUAGE_TYPE_ITALIAN:		// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 
	case LANGUAGE_TYPE_POLISH:		// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:		// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_ARGENTINA:	// 2010-11-01 by shcho, Lin 아르헨티나 서비스 시작 준비 - 언어타입 추가
		return 730;									// 2008-04-25 by cmkwon, 지원 언어에 독일어 추가 - Gameforge4D 멤버쉽 최대 일수(730일=24개월)
	case LANGUAGE_TYPE_TAIWANESE:	return 30;		// 2008-10-10 by cmkwon, 30일로 수정, // 2008-09-23 by cmkwon, 지원 서비스 추가(대만 Netpower_Tpe) - 기본 180일

	}
	return TERM_MONTHLYPAY_MAX_BUY_ENABLE_DAY;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsChargeUser(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-01 ~ 2006-06-01
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsChargeUser(void)
{
	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_VIETNAMESE:
		{
			if(m_ItemManager.IsExistPremiumCard())
			{// 2006-06-01 by cmkwon, 베트남은 프리미엄으로 정액제를 체크한다.
				return TRUE;
			}
		}
		break;
	default:
		{
			return TRUE;
		}
	}
	return FALSE;
}

BOOL CFieldIOCPSocket::IsValidGameUser(Experience_t *o_pExptMaxEXP/*=NULL*/
									   , Experience_t i_CurEXP/*=0.0f*/)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-21 by cmkwon, 베트남도 한국버젼과 동일하게 서비스 진행
	return TRUE;


	if(IsChargeUser())
	{
		return TRUE;
	}

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_VIETNAMESE:
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2006-06-14 by cmkwon, 계정 등록일 체크
			ATUM_DATE_TIME tmaExpre = m_AccountRegisteredDate;
			tmaExpre.AddDateTime(0, 0, 7, 0, 0, 0);
			ATUM_DATE_TIME tmaCur(TRUE);
			if(tmaExpre < tmaCur)
			{
				return FALSE;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2006-06-14 by cmkwon, 경험치 체크
			if(0.0f >= i_CurEXP)
			{
				i_CurEXP = m_character.Experience;
			}
			Experience_t tmExp = CAtumSJ::GetExperienceFromPercentage(99, 24);
			if(i_CurEXP >= tmExp)
			{
				if(o_pExptMaxEXP)
				{
					*o_pExptMaxEXP = tmExp;
				}
				return FALSE;
			}
		}
		break;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::LoadCashLibrary(void)
/// \brief		// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 
/// \author		cmkwon
/// \date		2008-03-17 ~ 2008-03-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::LoadCashLibrary(void)
{
	
// 2008-07-11 by cmkwon, Gameforge4D_Deu 빌링 모듈 연동하기 - 
// 2008-12-22 by cmkwon, 지원 서비스 추가(Gameforge4D 터키아, 불어, 이탈리아어) - 아래와 같이 3개 서비스 추가
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1)
// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
//#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1)
#if defined(SERVICE_TYPE_ENGLISH_SERVER_2) || defined(SERVICE_TYPE_GERMAN_SERVER_1) || defined(SERVICE_TYPE_TURKISH_SERVER_1) || defined(SERVICE_TYPE_FRENCH_SERVER_1) || defined(SERVICE_TYPE_ITALIAN_SERVER_1) || defined(SERVICE_TYPE_POLISH_SERVER_1) || defined(SERVICE_TYPE_SPANISH_SERVER_1)

	// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 라이브러리 초기화
	if(NULL != ms_hBillingLibrary)
	{
		return TRUE;
	}
	
	ms_hBillingLibrary = LoadLibrary("flysisdll.dll");
	if ((UINT)ms_hBillingLibrary < HINSTANCE_ERROR)
	{
		ms_hBillingLibrary = NULL;
		return FALSE;
	}
	
	ms_pGFBillingRequest = (PGFBILLINGREQUEST) GetProcAddress((HMODULE)ms_hBillingLibrary, "GFBillingReqExecute");
	return TRUE;
#endif // END - SERVICE_TYPE_ENGLISH_SERVER_2
	
	return TRUE;
}


// 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GetWebAccountNum(char* i_szAccountName, UID32_t* o_WebAccountNumber, int* o_nErrNum)
/// \brief		BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
/// \author		jhseol
/// \date		2012-10-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GetWebAccountNum(char* i_szAccountName, UID32_t* o_WebAccountNumber, int* o_nErrNum)
{
#ifdef S_BPSOFTBILLING_JHSEOL
	// 2014-02-10 by jhseol&bckim, 체널링 - 한국 유저 정보 추가저장
	#ifdef SC_CHANNELING_JHSEOL_BCKIM_SSJUNG	// - web UID가 이미 저장돼 있으면 기존 루틴 스킵

	if ( 0 != m_nExtUserSerial )
	{
		*o_WebAccountNumber = m_nExtUserSerial;
		*o_nErrNum = ERR_NO_ERROR;
		return;
	}
	CODBCStatement odbcStmt;
	BOOL bRet = odbcStmt.Init(g_pFieldGlobal->GetExtUserInfoDBServerIP(), g_pFieldGlobal->GetExtAuthDBServerPort(), g_pFieldGlobal->GetExtUserInfoDBServerDatabaseName()
					, (CHAR*)g_pFieldGlobal->GetExtUserInfoODBCUID(), (CHAR*)g_pFieldGlobal->GetExtUserInfoODBCPASSWORD(), g_pFieldGlobal->GetMainWndHandle());

	#else

	CODBCStatement odbcStmt;
	char DBIP[SIZE_MAX_IPADDRESS];
	int DBPort = 9979;
	char DBName[20];
	char DBUserName[20];
	char DBPWD[20];
	// 2013-12-26 by jhseol, 한국 테섭 빌링연동 추가
	if ( TRUE == g_pFieldGlobal->IsTestServer() )
	{
		STRNCPY_MEMSET(DBIP,		"115.144.35.82",	sizeof(DBIP));
		STRNCPY_MEMSET(DBName,		"masangsoftweb",	sizeof(DBName));
		STRNCPY_MEMSET(DBUserName,	"web_master",		sizeof(DBUserName));
		STRNCPY_MEMSET(DBPWD,		"dnpq34tjqltm()",	sizeof(DBPWD));
	}
	else
	{
		STRNCPY_MEMSET(DBIP,		"192.168.4.14",		sizeof(DBIP));
		STRNCPY_MEMSET(DBName,		"masangsoftweb",	sizeof(DBName));
		STRNCPY_MEMSET(DBUserName,	"web_master",		sizeof(DBUserName));
		STRNCPY_MEMSET(DBPWD,		"dnpq34tjqltm()",	sizeof(DBPWD));
	}
	// end 2013-12-26 by jhseol, 한국 테섭 빌링연동 추가
	BOOL bRet = odbcStmt.Init(DBIP, DBPort, DBName, DBUserName, DBPWD, g_pFieldGlobal->GetMainWndHandle());

	#endif
	// end 2014-02-10 by jhseol&bckim, 체널링 - 한국 유저 정보 추가저장
	if (!bRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::GetWebAccountNum, WEB DB DirectConnect# connect error !! DBServer(%s:%d)\r\n", g_pFieldGlobal->GetExtUserInfoDBServerIP(), g_pFieldGlobal->GetExtAuthDBServerPort());
		*o_nErrNum = ERR_DB_CONNECT_FAIL;
		return;
	}
	
	SQLHSTMT hstmt = odbcStmt.GetSTMTHandle();
	SQLINTEGER arrCB[3] = {SQL_NTS,SQL_NTS,SQL_NTS};
	SQLRETURN ret = 0;
	
	SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, SIZE_MAX_ACCOUNT_NAME, 0, i_szAccountName, 0,	&arrCB[1]);
	bRet = odbcStmt.ExecuteQuery("{call dbo.usp_SELECT_HOMEPAGE_MEMBER_SERIAL(?)}");
	if(FALSE == bRet)
	{
		odbcStmt.ProcessLogMessagesForStmt("[DB Error] CFieldIOCPSocket::GetWebAccountNum ExecuteQuery(dbo.usp_SELECT_HOMEPAGE_MEMBER_SERIAL) Error !!\r\n");
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::GetWebAccountNum, ExecuteQuery(dbo.usp_SELECT_HOMEPAGE_MEMBER_SERIAL) error !! User(%s)\r\n", i_szAccountName);
		*o_nErrNum = ERR_DB_QUERY_ERROR;
		return;
	}
	SQLBindCol(hstmt, 1, SQL_C_ULONG, o_WebAccountNumber, 0,		&arrCB[2]);
	
	ret = SQLFetch(hstmt);
	if(ret!=SQL_SUCCESS && ret!=SQL_SUCCESS_WITH_INFO)
	{
		odbcStmt.ProcessLogMessagesForStmt("[DB Error] CFieldIOCPSocket::GetWebAccountNum, SQLBindCol(Billing_Get_Point@) Error !!\r\n");
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::GetWebAccountNum, SQLBindCol(Billing_Get_Point@) error !! User(%s)\r\n", i_szAccountName);
		*o_nErrNum = ERR_DB_QUERY_ERROR;
		return;
	}
	*o_nErrNum = ERR_NO_ERROR;
#endif
}
// end 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기

// 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템
///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::GetCashPay_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash)
/// \brief		
/// \author		jhseol
/// \date		2012-08-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::GetCashPay_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash)
{
#ifdef S_BPSOFTBILLING_JHSEOL
	char UserNum[BUFFSIZE] = {NULL,};
	char UserID[BUFFSIZE] = {NULL,};
	// 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
	UID32_t tmWebAccountNumber = 0;
	int ErrCode = ERR_NO_ERROR;
	GetWebAccountNum(m_character.AccountName, &tmWebAccountNumber, &ErrCode);
	if( ErrCode != ERR_NO_ERROR)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::GetCashPay_BPSOFT, GetWebAccountNum() error !! User(%s) RetVal(%d)\r\n", m_character.AccountName, ErrCode);
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
		return ERR_CASH_BPSOFT_METHOD_CALL;
	}
	itoa(tmWebAccountNumber, UserNum, 10);
	// end 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
	memcpy(UserID, m_character.AccountName, BUFFSIZE);

// #if defined(TEST140)		// 2013-05-06 by jhseol, 238 서버 빌링 테섭 연동 - 주석처리
// 	memcpy(UserNum, BPSOFT_TEST_USER_NO, BUFFSIZE);
// 	memcpy(UserID, BPSOFT_TEST_USER_ID, BUFFSIZE);
// #endif
	
	
	/********************************************************************************************/
	/*	잔액장 조회								   */
	/*	Method :CashBalanceInfo() 호출 방법.					   */
	/********************************************************************************************/
	
	//변수 선언
	_variant_t	vsMembership_Cd, vsUser_no, vsUser_id, vsUser_name,vlCharge_cash, vlPay_cash, vlGift_cash, vlEvent_cash, vlYD_cash, vlTest_cash, vlTotal_cash,vsRetCode,vlRetValCom;
	
	char	szTemp[BUFFSIZE] = {0};
	WCHAR	*wTemp = (WCHAR *)szTemp;
	char	Buf[BUFFSIZE] = {0};
	//[IN]변수 세팅
	//멤버쉽 코드 - (M:Mandatory)- 유관부서에서 부여 받은 값
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(BPSOFT_MEMBERSHIP_CODE, wTemp, strlen(BPSOFT_MEMBERSHIP_CODE) );
	vsMembership_Cd.vt = VT_BSTR; vsMembership_Cd.bstrVal= ::SysAllocString(wTemp);

	//사용자 번호 - (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(UserNum, wTemp, strlen(UserNum) );
	vsUser_no.vt = VT_BSTR; vsUser_no.bstrVal= ::SysAllocString(wTemp);

	//사용자 아이디- (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(UserID, wTemp, strlen(UserID) );
	vsUser_id.vt = VT_BSTR; vsUser_id.bstrVal= ::SysAllocString(wTemp);
	
	
	//COM 라이브러리 초기화
	if  ( !(CoInitializeEx(NULL, COINIT_MULTITHREADED) == S_OK))
	{
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::GetCashPay_BPSOFT (Load COM Library CoInitializeEx() FAILED)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
		return ERR_CASH_BPSOFT_COM_LIBRARY_INIT;
	}
	
	try
	{
		//COM 객체 생성
		CComPtr<ICartPurchaseCli>pICartPurchaseCli;
		HRESULT hr = pICartPurchaseCli.CoCreateInstance(OLESTR("BCARTPURCHASE_COM.CartPurchaseCli.1"));
		if  (FAILED(hr))
		{
			//에러처리
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::GetCashPay_BPSOFT (Creation ICartPurchaseCli Object FAILED)\r\n");
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
			return ERR_CASH_BPSOFT_CREATION_OBJECK;
		}
		
		//함수 호출
		vlRetValCom = pICartPurchaseCli->CashBalanceInfo (&vsMembership_Cd, &vsUser_no, &vsUser_id, &vsUser_name,&vlCharge_cash, &vlPay_cash, &vlGift_cash, &vlEvent_cash, &vlYD_cash,&vlTest_cash, &vlTotal_cash);

		_variant_t callresult;
		memset(wTemp, 0x00, BUFFSIZE);	MTOW(BPSOFT_METHOD_CALL_NO_ERRER, wTemp, strlen(BPSOFT_METHOD_CALL_NO_ERRER) );
		callresult.vt = VT_BSTR; callresult.bstrVal = ::SysAllocString(wTemp);
		
		if( callresult != vlRetValCom )
		{
			::CoUninitialize();
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (CashBalanceInfo Method Call FAILED)\r\n");
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
			return ERR_CASH_BPSOFT_METHOD_CALL;
		}

		memset(szTemp, 0x00, BUFFSIZE); WTOM(vlRetValCom.lVal, szTemp);
		//
		if (atoi(szTemp) == 0)
		{
			//나머지 [OUT]변수를 결과에 따라 처리한다.
			*o_pMCash		= vlCharge_cash.lVal + vlYD_cash.lVal;
			*o_pFreeCash	= vlEvent_cash.lVal + vlTest_cash.lVal;
			*o_pTotalMoney	= *o_pMCash + *o_pFreeCash;
		}
		else
		{
			// 에러 처리
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::GetCashPay_BPSOFT (CashBalanceInfo Method Call FAILED : szTemp[%s])\r\n", szTemp);
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
			return ERR_CASH_BPSOFT_METHOD_CALL;
		}
	}
	catch (const _com_error& e)
	{
		::CoUninitialize();
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::GetCashPay_BPSOFT (Exception ERROR Type.1)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
		return ERR_CASH_BPSOFT_EXCEPTION;
	}
	catch (...)
	{
		CoUninitialize();
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::GetCashPay_BPSOFT (Exception ERROR Type.2)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
		return ERR_CASH_BPSOFT_EXCEPTION;
	}
	CoUninitialize();
#endif
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::BuyCashItem_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash, UINT i_pItemCashPrice);
/// \brief		
/// \author		jhseol
/// \date		2012-08-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::BuyCashItem_BPSOFT(INT *o_pTotalMoney, INT *o_pMCash, INT *o_pFreeCash, ITEM *i_pItem, int i_nAmount/*=1*/)		// 2013-03-13 by hskim, 웹 캐시 상점
{
#ifdef S_BPSOFTBILLING_JHSEOL
	char UserNum[BUFFSIZE] = {NULL,};
	char UserID[BUFFSIZE] = {NULL,};
	char ItemNum[BUFFSIZE] = {NULL,};
	// 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
	UID32_t tmWebAccountNumber = 0;
	int ErrCode = ERR_NO_ERROR;
	GetWebAccountNum(m_character.AccountName, &tmWebAccountNumber, &ErrCode);
	if( ErrCode != ERR_NO_ERROR)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[DB Error] CFieldIOCPSocket::BuyCashItem_BPSOFT, GetWebAccountNum() error !! User(%s) RetVal(%d)\r\n", m_character.AccountName, ErrCode);
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0046);
		return ERR_CASH_BPSOFT_METHOD_CALL;
	}
	itoa(tmWebAccountNumber, UserNum, 10);
	// end 2012-10-18 by jhseol, BPSoft 빌링 모듈 - 빌링(=WEB)DB 유저 씨리얼 넘버 가져오기
	memcpy(UserID, m_character.AccountName, BUFFSIZE);
	itoa(i_pItem->ItemNum, ItemNum, 10);

	
// #if defined(TEST140)		// 2013-05-06 by jhseol, 238 서버 빌링 테섭 연동 - 주석처리
// 	memcpy(UserNum, BPSOFT_TEST_USER_NO, BUFFSIZE);
// 	memcpy(UserID, BPSOFT_TEST_USER_ID, BUFFSIZE);
// #endif

	/********************************************************************************************/
	/*	구매 상품 구매								   */
	/*	Method :PurchaseComplete() 호출 방법.					   */
	/********************************************************************************************/
	
	//변수 선언
	_variant_t	vsMembership_Cd, vsUser_no, vsUser_id,vlContentsNo,vlSiteNo,vsGoodsNo, vlGoodsCnt, vlPayAmt, vsUserIp, vsServerIp, vsFreeVar1, vsFreeVar2, vsFreeVar3, vsFreeVar4,
		vsBxaid,vlLimitAge,vlLimitAmt,vlLimitBuyAmt,vsRetCode,vlRetValCom;

	char	szTemp[BUFFSIZE] = {0};
	WCHAR	*wTemp = (WCHAR *)szTemp;
	char	Buf[BUFFSIZE] = {0};
	
	//[IN]변수 세팅
	//멤버쉽 코드 - (M:Mandatory)- 유관부서에서 부여 받은 값
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(BPSOFT_MEMBERSHIP_CODE, wTemp, strlen(BPSOFT_MEMBERSHIP_CODE) );
	vsMembership_Cd.vt = VT_BSTR; vsMembership_Cd.bstrVal= ::SysAllocString(wTemp);
	
	//사용자 번호 - (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(UserNum, wTemp, strlen(UserNum) );
	vsUser_no.vt = VT_BSTR; vsUser_no.bstrVal= ::SysAllocString(wTemp);
	
	//사용자 아이디- (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(UserID, wTemp, strlen(UserID) );
	vsUser_id.vt = VT_BSTR; vsUser_id.bstrVal= ::SysAllocString(wTemp);
	
	//컨텐츠 번호-(M:Mandatory) - 유관부서에서 부여 받은 값
	vlContentsNo.vt = VT_I4;
	vlContentsNo.lVal = (LONG)BPSOFT_CINTENS_NO;
	
	//사이트 번호-(M:Mandatory)- 유관부서에서 부여 받은 값
	vlSiteNo.vt = VT_I4;
	// 2014-02-10 by jhseol&bckim, 체널링 - 빌링 연동
#ifdef SC_CHANNELING_JHSEOL_BCKIM_SSJUNG	// - 빌링 연동
	switch(m_nChannelingNum)
	{	// 추후 채널링 추가시 채널링 번호에 따른 BP에서 부여받은 사이트 번호를 입력하는 코드 추가해야함.
	case 0:			vlSiteNo.lVal = (LONG)BPSOFT_SITE_NO;				break;
	case 101:		vlSiteNo.lVal = (LONG)BPSOFT_SITE_NO_MUNPIA;		break;
	}
#else
	vlSiteNo.lVal = (LONG)BPSOFT_SITE_NO;
#endif
	// end 2014-02-10 by jhseol&bckim, 체널링 - 빌링 연동
	
	//상품 번호 - (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(ItemNum, wTemp, strlen(ItemNum) );
	vsGoodsNo.vt = VT_BSTR; vsGoodsNo.bstrVal= ::SysAllocString(wTemp);
	
	//상품 수량-(M:Mandatory)
	vlGoodsCnt.vt = VT_I4;
	vlGoodsCnt.lVal = i_nAmount;		// 2013-03-13 by hskim, 웹 캐시 상점
	
	//상품 가격-(M:Mandatory) 한 개 상품의 가격을 입력한다.
	vlPayAmt.vt = VT_I4;
	vlPayAmt.lVal = (LONG)i_pItem->CashPrice;
	
	//사용자 IP - (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(m_szPeerIP, wTemp, strlen(m_szPeerIP) );
	vsUserIp.vt = VT_BSTR; vsUserIp.bstrVal= ::SysAllocString(wTemp);
	
	char tmServerIP[SIZE_MAX_IPADDRESS];
	if( 10062 == g_pFieldGlobal->GetMGameServerID() )
	{
		STRNCPY_MEMSET(tmServerIP, "182.162.137.3", SIZE_MAX_IPADDRESS)
	}
	else if( 10067 == g_pFieldGlobal->GetMGameServerID() )
	{
		STRNCPY_MEMSET(tmServerIP, "182.162.137.4", SIZE_MAX_IPADDRESS)
	}
	else if( 10066 == g_pFieldGlobal->GetMGameServerID() )
	{
		STRNCPY_MEMSET(tmServerIP, "182.162.137.6", SIZE_MAX_IPADDRESS)
	}

	// 2013-12-26 by jhseol, 한국 테섭 빌링연동 추가
	if ( TRUE == g_pFieldGlobal->IsTestServer() )
	{
		STRNCPY_MEMSET(tmServerIP, "182.162.137.7", SIZE_MAX_IPADDRESS)
	}
	// end 2013-12-26 by jhseol, 한국 테섭 빌링연동 추가
#if defined(TEST140)		// 2013-05-06 by jhseol, 238 서버 빌링 테섭 연동 - 서버 IP 입력
	STRNCPY_MEMSET(tmServerIP, "115.144.35.238", SIZE_MAX_IPADDRESS)
#endif
	//서버 IP - (M:Mandatory)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW(tmServerIP, wTemp, strlen(tmServerIP) );
	vsServerIp.vt = VT_BSTR; vsServerIp.bstrVal= ::SysAllocString(wTemp);
	
	//ETC Param 1 - (O:Option)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW("ETC Param 1", wTemp, strlen("ETC Param 1") );
	vsFreeVar1.vt = VT_BSTR; vsFreeVar1.bstrVal = ::SysAllocString(wTemp);
	
	//ETC Param 2 - (O:Option)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW("ETC Param 2", wTemp, strlen("ETC Param 2") );
	vsFreeVar2.vt = VT_BSTR; vsFreeVar2.bstrVal = ::SysAllocString(wTemp);
	
	//ETC Param 3 - (O:Option)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW("ETC Param 3", wTemp, strlen("ETC Param 3") );
	vsFreeVar3.vt = VT_BSTR; vsFreeVar3.bstrVal = ::SysAllocString(wTemp);
	
	//ETC Param 4 - (O:Option)
	memset(wTemp, 0x00, BUFFSIZE);	MTOW("ETC Param 4", wTemp, strlen("ETC Param 4") );
	vsFreeVar4.vt = VT_BSTR; vsFreeVar4.bstrVal = ::SysAllocString(wTemp);
	
	//COM 라이브러리 초기화
	if  ( !(CoInitializeEx(NULL, COINIT_MULTITHREADED) == S_OK)) {
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (Load COM Library CoInitializeEx() FAILED)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
		return ERR_CASH_BPSOFT_COM_LIBRARY_INIT;
	}
	
	try
	{
		//COM 객체 생성
		CComPtr<ICartPurchaseCli>pICartPurchaseCli;
		HRESULT hr = pICartPurchaseCli.CoCreateInstance(OLESTR("BCARTPURCHASE_COM.CartPurchaseCli.1"));
		if  (FAILED(hr))
		{
			//에러처리
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (Creation ICartPurchaseCli Object FAILED)\r\n");
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
			return ERR_CASH_BPSOFT_CREATION_OBJECK;
		}
		
		//함수 호출
		vlRetValCom = pICartPurchaseCli ->PurchaseComplete (&vsMembership_Cd, &vsUser_no, &vsUser_id, &vlContentsNo, &vlSiteNo, &vsGoodsNo, &vlGoodsCnt, &vlPayAmt, &vsUserIp , &vsServerIp,  &vsFreeVar1, &vsFreeVar2, &vsFreeVar3, &vsFreeVar4, &vsBxaid, &vlLimitAge, &vlLimitAmt, &vlLimitBuyAmt);
		
		_variant_t callresult;
		memset(wTemp, 0x00, BUFFSIZE);	MTOW(BPSOFT_METHOD_CALL_NO_ERRER, wTemp, strlen(BPSOFT_METHOD_CALL_NO_ERRER) );
		callresult.vt = VT_BSTR; callresult.bstrVal = ::SysAllocString(wTemp);

		if( callresult != vlRetValCom )
		{
			::CoUninitialize();
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (PurchaseComplete Method Call FAILED)\r\n");
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
			return ERR_CASH_BPSOFT_METHOD_CALL;
		}
		
		//결과 처리
		memset(szTemp, 0x00, BUFFSIZE); WTOM(vlRetValCom.bstrVal, szTemp);
		//
		if (atoi(szTemp) == 0)
		{
			//나머지 [OUT]변수를 결과에 따라 처리한다.
			//빌링 주문 번호
			memset(szTemp, 0x00, BUFFSIZE); 
			WTOM(vsBxaid.bstrVal, szTemp);
			//제한 나이
			//"제한 나이= vlLimitAge.lVal;
			//한도 금액
			//"한도 금액 = vlLimitAmt.lVal;
			//구매 한도 금액 
			//"구매 한도 금액 = vlLimitBuyAmt.lVal;
				
		}
		else
		{
			// 에러 처리
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (PurchaseComplete Method Call FAILED : szTemp[%s])\r\n", szTemp);
			SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
			return ERR_CASH_BPSOFT_METHOD_CALL;
		}
	}
	catch (const _com_error& e)
	{
		::CoUninitialize();
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (Exception ERROR Type.1)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
		return ERR_CASH_BPSOFT_EXCEPTION;
	}
	catch (...)
	{
		CoUninitialize();
		//에러처리
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [ERROR] CFieldIOCPSocket::BuyCashItem_BPSOFT (Exception ERROR Type.2)\r\n");
		SendString128(STRING_128_USER_ERR, STRERR_ERROR_0045);
		return ERR_CASH_BPSOFT_EXCEPTION;
	}
	
	::CoUninitialize();
	
	// 구매 완료 후 잔액 조회를 다시한다.
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::BuyCashItem_BPSOFT Success, Before the GetCashPay_BPSOFT Method Call (CUID:%d) (ItemNum:%d) (CashPrice:%d) (Amount:%d)\r\n"
		,m_character.CharacterUniqueNumber, i_pItem->ItemNum, i_pItem->CashPrice, BPSOFT_ITEM_AMOUNT);
	return GetCashPay_BPSOFT(o_pTotalMoney, o_pMCash, o_pFreeCash);
#endif
	return ERR_NO_ERROR;
}
// end 2012-08-17 by jhseol, 마상 BPSoft 빌링시스템

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::UnloadCashLibrary(void)
/// \brief		// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 
/// \author		cmkwon
/// \date		2008-03-17 ~ 2008-03-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::UnloadCashLibrary(void)
{
	if(ms_hBillingLibrary)
	{
		FreeLibrary((HMODULE)ms_hBillingLibrary);
		ms_hBillingLibrary	= NULL;
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ITEM *CFieldIOCPSocket::GetGiveKillMarkItemPtr2Killer(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-02-09 ~ 2006-02-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM *CFieldIOCPSocket::GetGiveKillMarkItemPtr2Killer(void)
{
	return m_pGiveKillMarkItemPtr2Killer;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetGiveKillMarkItemPtr2Killer(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-02-09 ~ 2006-02-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetGiveKillMarkItemPtr2Killer(void)
{
	m_pGiveKillMarkItemPtr2Killer = ms_pFieldIOCP->GetKillMarkItemPtr(m_character.InfluenceType, m_character.Level);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GMQuestCompletion(int i_questIdx/*=-1*/)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-07 ~ 2005-12-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GMQuestCompletion(int i_questIdx/*=-1*/)
{
	mt_auto_lock mtA(&this->m_mapQuest);

	if(-1 == i_questIdx)
	{// 2006-08-07 by cmkwon, 현재 진행중인 퀘스트를 완료한다.

		CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();
		if(NULL == pFCharQuest)
		{// 2005-12-07 by cmkwon, 진행중 퀘스트가 없다
			return FALSE;
		}

		return this->GMQuestCompletion(pFCharQuest->GetQuestInfo());
	}

	CQuest *pQuestInfo = ms_pFieldIOCP->GetQuestInfo(i_questIdx);
	if(NULL == pQuestInfo
		|| FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, pQuestInfo->ReqInfluenceType))
	{// 2006-08-08 by cmkwon, 미션의 세력과 캐릭터의 세력을 체크한다.
		return FALSE;
	}

	if(QUEST_KIND_SCENARIO != pQuestInfo->QuestKind)
	{// 2006-08-08 by cmkwon, 시나리오 미션이 아니면 찾은 미션만 완료 처리함
		return this->GMQuestCompletion(pQuestInfo);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-08 by cmkwon, 시나리오 미션일 경우 해당 세력의 시나리오 미션을 찾은 미션까지 모두 완료 처리한다.
	CQuest *pCurQuestInfo = ms_pFieldIOCP->GetFirstScenarioQuestInfoByInfluenceType(m_character.InfluenceType);
	if(NULL == pCurQuestInfo)
	{
		return FALSE;
	}

	for(; NULL != pCurQuestInfo && pCurQuestInfo->QuestIndex != pQuestInfo->NextQuestIndex; pCurQuestInfo = ms_pFieldIOCP->GetQuestInfo(pCurQuestInfo->NextQuestIndex))
	{
		if(FALSE == this->GMQuestCompletion(pCurQuestInfo))
		{
			break;
		}
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GMQuestCompletion(CQuest *i_pQuestInfo)
/// \brief		
/// \author		cmkwon
/// \date		2006-08-07 ~ 2006-08-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GMQuestCompletion(CQuest *i_pQuestInfo)
{
	// 2007-10-11 by cmkwon, 체크 추가
	if(FALSE == IsValidCharacter())
	{
		return FALSE;
	}

	if(QUEST_END_TYPE_SELECT_INFLUENCE == i_pQuestInfo->QuestEndType)
	{// 2005-12-07 by cmkwon, 세력선택미션은 자동으로 완료 불가
		return FALSE;
	}

	CFieldCharacterQuest *pFCharQuest = this->GetFieldCharacterQuestPtrByQuestIndex(i_pQuestInfo->QuestIndex);
	if(QUEST_TYPE_REPEATABLE == i_pQuestInfo->QuestType)
	{
		if(pFCharQuest)
		{
			// 퀘스트를 삭제한다
			QPARAM_DELETE_QUEST *pQDeleteQuest		= new QPARAM_DELETE_QUEST;
			pQDeleteQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQDeleteQuest->QuestIndex				= i_pQuestInfo->QuestIndex;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);

			m_mapQuest.deleteLock(i_pQuestInfo->QuestIndex);
		}
	}
	else
	{
		if(NULL == pFCharQuest)
		{
			CharacterQuest *pQInsertQuest = new CharacterQuest;
			pQInsertQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQInsertQuest->QuestIndex				= i_pQuestInfo->QuestIndex;
			pQInsertQuest->QuestState				= QUEST_STATE_COMPLETED;
			pQInsertQuest->QuestParam1				= 0;
			pQInsertQuest->QuestTimeStamp.SetCurrentDateTime();
			pQInsertQuest->QuestPlayTimeStamp		= GetTotalPlayTimeInSeconds();

			m_mapQuest.insertNoLock(i_pQuestInfo->QuestIndex, CFieldCharacterQuest(pQInsertQuest, i_pQuestInfo));

			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertQuest, this, m_character.AccountUniqueNumber, pQInsertQuest);
		}
		else
		{
			if(QUEST_STATE_COMPLETED == pFCharQuest->QuestState)
			{
				return TRUE;
			}

			pFCharQuest->QuestState					= QUEST_STATE_COMPLETED;

			QPARAM_UPDATE_QUEST *pQUpdateQuest		= new QPARAM_UPDATE_QUEST;
			pQUpdateQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQUpdateQuest->QuestIndex				= pFCharQuest->QuestIndex;
			pQUpdateQuest->QuestState				= pFCharQuest->QuestState;
			pQUpdateQuest->QuestProgressTimeInSecond	= this->GetTotalPlayTimeInSeconds() - pFCharQuest->QuestPlayTimeStamp;	// 2006-08-31 by cmkwon, 퀘스트 진행 시간 저장
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateQuestState, this, m_character.AccountUniqueNumber, pQUpdateQuest);
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 완료한 퀘스트 로그에 남기기
	CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, i_pQuestInfo->QuestIndex);		// send log

	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT, T_FC_QUEST_REQUEST_SUCCESS_RESULT, pSuccessResult, pSuccessResultBuf);
	pSuccessResult->QuestIndex		= i_pQuestInfo->QuestIndex;
	pSuccessResult->IsSuccessful	= TRUE;
	SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT));
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GMQuestAdjustByInfluenceType(BYTE i_byInflTy)
/// \brief		
/// \author		cmkwon
/// \date		2006-08-08 ~ 2006-08-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GMQuestAdjustByInfluenceType(BYTE i_byInflTy)
{
	mt_auto_lock mtA(&this->m_mapQuest);

	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest = m_mapQuest.begin();
	while (itrQuest != m_mapQuest.end())
	{
		CFieldCharacterQuest *pFCharacterQuest = &itrQuest->second;
		CQuest *pQuestInfo = pFCharacterQuest->GetQuestInfo();
		if (INFLUENCE_TYPE_NORMAL == i_byInflTy					// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 명령어로 일반세력으로 변경하면 모든 퀘스트 삭제
			|| FALSE == COMPARE_INFLUENCE(i_byInflTy, pQuestInfo->ReqInfluenceType))
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_DISCARD_QUEST_OK, T_FC_QUEST_DISCARD_QUEST_OK, pMsgDiscard, pMsgDiscardBuf);
			pMsgDiscard->QuestIndex		= pFCharacterQuest->QuestIndex;
			pMsgDiscard->IsDiscarded	= TRUE;
			SendAddData(pMsgDiscardBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));

			// 퀘스트 지우기 - DB
			QPARAM_DELETE_QUEST *pQDeleteQuest		= new QPARAM_DELETE_QUEST;
			pQDeleteQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQDeleteQuest->QuestIndex				= pFCharacterQuest->QuestIndex;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);

			m_mapQuest.erase(itrQuest++);
			continue;
		}
		itrQuest++;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			CFieldCharacterQuest * CFieldIOCPSocket::GetFieldCharacterQuestPtrByQuestIndex(INT i_questIdx)
/// \brief		
/// \author		cmkwon
/// \date		2005-10-19 ~ 2005-10-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CFieldCharacterQuest * CFieldIOCPSocket::GetFieldCharacterQuestPtrByQuestIndex(INT i_questIdx)
{
	return this->m_mapQuest.findNoLock_Ptr(i_questIdx);
}

Err_t CFieldIOCPSocket::CheckQuestStartRequirements(CQuest *pQuestInfo, MSG_FC_QUEST_REQUEST_START *i_pQuestStart, BOOL i_bProcessPartyMembers/*=TRUE*/)
{
	if (FALSE == (m_character.UnitKind & pQuestInfo->ReqUnitKind))
	{// 가능 세력 체크
		return ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED;
	}

	if(FALSE == COMPARE_INFLUENCE(pQuestInfo->ReqInfluenceType, m_character.InfluenceType))
	{
		return ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqAttackPart.Min, m_character.TotalGearStat.AttackPart, pQuestInfo->ReqAttackPart.Max))
	{
		return ERR_PROTOCOL_REQ_ATTACK_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqDefensePart.Min, m_character.TotalGearStat.DefensePart, pQuestInfo->ReqDefensePart.Max))
	{
		return ERR_PROTOCOL_REQ_DEFENSE_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqFuelPart.Min, m_character.TotalGearStat.FuelPart, pQuestInfo->ReqFuelPart.Max))
	{
		return ERR_PROTOCOL_REQ_FUEL_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqSoulPart.Min, m_character.TotalGearStat.SoulPart, pQuestInfo->ReqSoulPart.Max))
	{
		return ERR_PROTOCOL_REQ_SOUL_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqShieldPart.Min, m_character.TotalGearStat.ShieldPart, pQuestInfo->ReqShieldPart.Max))
	{
		return ERR_PROTOCOL_REQ_SHIELD_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqDodgePart.Min, m_character.TotalGearStat.DodgePart, pQuestInfo->ReqDodgePart.Max))
	{
		return ERR_PROTOCOL_REQ_DODGE_PART_NOT_MATCHED;
	}

	if (!IS_IN_RANGE(pQuestInfo->ReqLevel.Min, m_character.Level, pQuestInfo->ReqLevel.Max))	// 필요레벨
	{
		return ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED;
	}

	if (pQuestInfo->ReqExperience > m_character.Experience)	// 필요 경험치
	{
		return ERR_PROTOCOL_REQ_EXPERIENCE_NOT_MATCHED;
	}

	int i = 0;

	// 필요 아이템 확인
	if(false == pQuestInfo->ReqItemVector.empty())
	{
		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
		for (i = 0; i < pQuestInfo->ReqItemVector.size(); i++)
		{
			ITEM_W_COUNT tmpItemWCount = pQuestInfo->ReqItemVector[i];

			// lock m_mapItemGeneral, @CheckQuestStartRequirements

			ITEM_BASE *pItem = m_ItemManager.GetFirstItemGeneralByItemNum(tmpItemWCount.ItemNum);
			if (pItem == NULL || (IS_GENERAL_ITEM(pItem->ItemInfo->Kind) && ((ITEM_GENERAL*)pItem)->CurrentCount < tmpItemWCount.Count))
			{
				return ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED;
			}
		}
	}

	// 필요 quest 확인
	if(false == pQuestInfo->ReqQuestIndexVector.empty())
	{
		mt_auto_lock qLock(&m_mapQuest);
		for (i = 0; i < pQuestInfo->ReqQuestIndexVector.size(); i++)
		{
			CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(pQuestInfo->ReqQuestIndexVector[i]);
			if (NULL == pFCharQuest || pFCharQuest->QuestState != QUEST_STATE_COMPLETED)
			{
				return ERR_PROTOCOL_REQ_QUEST_NOT_MATCHED;
			}
		}
	}

	// 필요 받은 quest 확인
	if(false == pQuestInfo->ReqRecvQuestIndexVector.empty())
	{
		mt_auto_lock qLock(&m_mapQuest);
		for (i = 0; i < pQuestInfo->ReqRecvQuestIndexVector.size(); i++)
		{
			CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(pQuestInfo->ReqRecvQuestIndexVector[i]);
			if (NULL == pFCharQuest || pFCharQuest->QuestState != QUEST_STATE_IN_PROGRESS)
			{
				return ERR_PROTOCOL_REQ_QUEST_NOT_MATCHED;
			}
		}
	}

// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
//	// 필요 무게 확인
//	if (GetCurrentLoadagePercentage(pQuestInfo->StartPayItemWeight) > 1.0f)
//	{
//		return ERR_PROTOCOL_ITEM_OVER_WEIGHT;
//	}

	if(FALSE == pQuestInfo->ReqStartArea.IsPositionInArea(m_character.MapChannelIndex.MapIndex, i_pQuestStart->AVec3QuestPosition.z, i_pQuestStart->AVec3QuestPosition.z))
	{
		return ERR_PROTOCOL_REQ_MAP_AREA_NOT_MATCHED;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-03-21 by cmkwon, 파티미션 체크
	if(i_bProcessPartyMembers
		&& pQuestInfo->IsPartyQuest())
	{
		CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if(NULL == pFParty)
		{// 2006-03-21 by cmkwon, 파티가 없다
			return ERR_PROTOCOL_NO_SUCH_PARTY;
		}

// 2007-02-12 by cmkwon, 아래와 같이 수정함
//		mt_auto_lock pmlock(&pFParty->m_ListPartyMember);
//		if(pQuestInfo->QuestPartyMembers > pFParty->m_FieldPartyInfo.nTotalPartyMember)
//		{// 2006-03-21 by cmkwon, 파티원수가 부족하다
//			return ERR_PROTOCOL_REQ_PARTYMEMBERS_NOT_MATCHED;
//		}
//// 2007-01-08 by cmkwon, dhkwon, 필요 없어서 삭제 처리함
////		if(10 <= pFParty->GetMaxMemberLevel() - pFParty->GetLowestMemberLevel())
////		{// 2006-03-21 by cmkwon, 최고레벨과 최저레벨의 차가 10이상이다
////			return ERR_PROTOCOL_REQ_PARTYMEMBERS_LEVEL_NOT_MATCHED;
////		}
//
//		if(pFParty->m_FieldPartyInfo.nTotalPartyMember != pFParty->GetMembersInSameMap(NULL, m_pCurrentFieldMapChannel))
//		{// 2006-03-21 by cmkwon, 파티원이 모두 같은맵이 있지 않다
//			return ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED;
//		}
//
//		if(0 != pQuestInfo->StartMapIndex)
//		{
//			CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pQuestInfo->StartMapIndex);
//			if (NULL == pFMPro)
//			{
//				return ERR_PROTOCOL_NO_SUCH_MAP_SERVED;
//			}
//
//			pmlock.auto_unlock_cancel();
//
//			if(FALSE == pFParty->CheckAllMemberEnableWarp(m_pCurrentFieldMapChannel, pFMPro->GetMapInfluenceType(), pFMPro->IsConflictAreaMap(), pFMPro->m_nQuestIndexForWarp))
//			{
//				return ERR_PROTOCOL_REQ_PARTYMEMBERS_SOMEONE_CANNOT_WARP;
//			}
//		}

		vectCFieldIOCPSocket tmFISockList;
		pFParty->GetAllMembers(&tmFISockList);

		if(pQuestInfo->QuestPartyMembers > tmFISockList.size())
		{// 2006-03-21 by cmkwon, 파티원수가 부족하다
			return ERR_PROTOCOL_REQ_PARTYMEMBERS_NOT_MATCHED;
		}

		if(FALSE == CFieldIOCPSocket::IsAllSameMap(this->GetCurrentFieldMapChannel(), &tmFISockList))
		{// 2007-02-12 by cmkwon, 파티원이 모두 같은맵이 있지 않다
			return ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED;
		}

		if(0 != pQuestInfo->StartMapIndex)
		{
			CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pQuestInfo->StartMapIndex);
			if (NULL == pFMPro)
			{
				return ERR_PROTOCOL_NO_SUCH_MAP_SERVED;
			}

			if(FALSE == CFieldParty::CheckAllMemberEnableWarp(&tmFISockList, m_pCurrentFieldMapChannel, pFMPro->GetMapInfluenceType(), pFMPro->IsConflictAreaMap(), pFMPro->m_nQuestIndexForWarp))
			{
				return ERR_PROTOCOL_REQ_PARTYMEMBERS_SOMEONE_CANNOT_WARP;
			}
		}
	}

	if(pQuestInfo->IsCityWar)
	{// 도시점령전 퀘스트 이다

		CCityWar *pCityWar = ms_pFieldIOCP->m_cityWarManager.GetCityWarPtrByQuestIndex(pQuestInfo->QuestIndex);
		if(NULL == pCityWar)
		{
			return ERR_PROTOCOL_QUEST_INVALID_CITYWAR_QUEST_INDEX;
		}
		
		if(CITYWAR_STATE_STARTED == pCityWar->GetCityWarState())
		{			
			return ERR_PROTOCOL_QUEST_CANNOT_CITYWAR_QUEST;
		}
		
// 2008-07-24 by cmkwon, MySQL 포팅 관련(OUTPUT 제거) - 사용하지 않는 함수, 주석 처리 함.
//		if(FALSE == pCityWar->QP_CheckGuildAndGuildMaster(m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber))
//		{// 여단장이 아니다
//			return ERR_PROTOCOL_REQ_NOT_GUILD_MASTER;
//		}
		
		if(IsExistQuestCityWar())
		{// 다른 도시점령전 퀘스트가 존재한다
			return ERR_PROTOCOL_QUEST_ALREADY_EXIST_CITYWAR;
		}
	}
		
	return ERR_NO_ERROR;
}

Err_t CFieldIOCPSocket::CheckQuestCompetionRequirements(CFieldCharacterQuest *i_pFCharQuest
														, MSG_FC_QUEST_REQUEST_SUCCESS *i_pQuestSuccess
														, MapIndex_t i_nMapIndex
														, INT i_nWarpTargetIndex
														, INT i_nAttMonster/*=0*/
														, BOOL i_bByUser/*=TRUE*/
														, ItemNum_t i_nUseItem/* = 0*/)	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
{
	CQuest *pQuestInfo = i_pFCharQuest->GetQuestInfo();
	if(NULL == pQuestInfo)
	{
		return ERR_PROTOCOL_NO_SUCH_QUEST_INFO;
	}

	if(QUEST_END_TYPE_SELECT_INFLUENCE == pQuestInfo->QuestEndType)
	{// 세력 선택 미션시 체크
		if(this->m_pFieldParty)
		{// 2005-12-06 by cmkwon, 파티상태에서는 불가
			return ERR_PROTOCOL_DOING_PARTY_BATTLE;
		}

		if(FALSE == COMPARE_INFLUENCE(i_pQuestSuccess->QuestResult, this->GetSelectableInfluenceMask()))
		{// 2005-12-07 by cmkwon, 하나의 계정에 하나의 세력만 선택 가능하다
			if(FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
			{// 2005-12-08 by cmkwon, 관리자 혹은 운영자가 아니면 에러를 리턴한다.
				return ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED;
			}
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - CFieldIOCPSocket::CheckQuestCompetionRequirements(), 두세력의 퀘스트를 모두 가지고 있는지 체크 한다.
		if(FALSE == ms_pFieldIOCP->m_QuestMatching.IsEnableSelectInfluence(this))
		{
			return ERR_PROTOCOL_QUEST_NEVER_COMPLITION_BY_USER;
		}

		// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 세력을 처음 선택하는 계정 일경우 세력 비율 체크
		if(m_character.SelectableInfluenceMask != i_pQuestSuccess->QuestResult
// 2009-09-16 by cmkwon, 세력 초기화시 어뷰징 방지 구현 - 아래와 같이 함수명 변경, Level 인자 추가
//			&& FALSE == ms_pFieldIOCP->IsEnableSelectInfluence(i_pQuestSuccess->QuestResult))
			&& FALSE == ms_pFieldIOCP->IsSelectableInfluence(i_pQuestSuccess->QuestResult, m_character.Level))
		{
			return ERR_CANNOT_CHOOSE_INFLUENCE_TYPE;
		}
	}


	if(pQuestInfo->IsNeverCompletionByUser
		&& i_bByUser)
	{// 유저에 의해서 완료불가능하다

		return ERR_PROTOCOL_QUEST_NEVER_COMPLITION_BY_USER;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-07-13 by cmkwon
	// 미션 완료 조건을 체크하기 전에 먼저 미션 종료 타입에 따른 체크를 먼저한다.
	switch(pQuestInfo->QuestEndType)
	{
	case QUEST_END_TYPE_LEVEL_UP:
		{
			if(m_character.Level <= i_pFCharQuest->QuestParam1)
			{
				return ERR_PROTOCOL_QUEST_NO_LEVEL_UP;
			}
		}
		return ERR_NO_ERROR;
	case QUEST_END_TYPE_TIME_OVER:
		{
			if(i_pQuestSuccess->SpentTimeInSeconds < pQuestInfo->TimeLimitInMinutes * 60)
			{
				return ERR_PROTOCOL_TIME_LIMIT_ERROR;
			}
		}
		return ERR_NO_ERROR;
	}

	// 2005-07-15 by cmkwon, 필요 없음, NPC를 만나지 않고 해결 가능하게 기획함
	// 2005-08-22 by cmkwon, 다시 추가함
	if (pQuestInfo->TargetMeetNPCInfo.NPCIndex != 0)
	{
		if (m_pCurrentBuildingNPC == NULL)
		{
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_QUEST_GENERAL_ERROR);
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0136);
			return ERR_PROTOCOL_QUEST_GENERAL_ERROR;
		}

		if (pQuestInfo->TargetMeetNPCInfo.NPCIndex != m_pCurrentBuildingNPC->NPCIndex)
		{
			return ERR_PROTOCOL_QUEST_GENERAL_ERROR;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-04-02 by cmkwon, 조합 완료 결과물 체크 미션 추가로 아래와 같이 수정함
	// TargetMixItemTarget이 0이 아니면  TargetMixItemTarget아이템이 있다면 필요아이템은 체크 필요없이 완료가능
	// TargetMixItemTarget이 0이면 기존과 같이 필요아이템을 모두 체크한다.
	if(0 != pQuestInfo->TargetMixItemTarget.ItemNum)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-02 by cmkwon, 조합 결과물 필요 아이템은 카운터블 아이템이 아닐수도 있다. 하지만 넌카운터블 아이템은 1개만 가능하다.
		ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pQuestInfo->TargetMixItemTarget.ItemNum);
		if (NULL == pItemG)
		{
			return ERR_PROTOCOL_REQ_MIX_ITEM_NOT_MATCHED;
		}

		if(IS_COUNTABLE_ITEM(pItemG->ItemInfo->Kind)
			&& pItemG->CurrentCount < pQuestInfo->TargetMixItemTarget.Count)
		{// 2007-04-02 by cmkwon, 카운터블 아이템은 개수를 체크
			return ERR_PROTOCOL_REQ_MIX_ITEM_NOT_MATCHED;
		}
	}
	else
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-02 by cmkwon, 미션 완료에 필요한 모든 아이템은 카운터블 아이템이다
		
		// 필요 몬스터 아이템 확인
		for (int j = 0; j < pQuestInfo->TargetMonsterItemVector.size(); j++)
		{
			if (0 >= pQuestInfo->TargetMonsterItemVector[j].ItemWithCount.ItemNum)
			{// 2007-03-16 by cmkwon, ItemNum이 유효하지 않으면
				continue;
			}
		
			ITEM_GENERAL *pTargetMonsterItem = m_ItemManager.GetFirstItemGeneralByItemNum(pQuestInfo->TargetMonsterItemVector[j].ItemWithCount.ItemNum);

			// Count가 0이면 꼭 있지 않아도 되는 아이템임
			if (0 >= pQuestInfo->TargetMonsterItemVector[j].ItemWithCount.Count)
			{// 2007-03-16 by cmkwon, Count가 0이하이면 체크하지 않아도 됨
				continue;
			}

			// 해당 아이템을 가지지 않은 경우
			if (pTargetMonsterItem == NULL)
			{
				return ERR_PROTOCOL_QUEST_GENERAL_ERROR;
			}

			// 해당 아이템의 개수가 부족한 경우
			if (IS_COUNTABLE_ITEM(pTargetMonsterItem->ItemInfo->Kind)
				&& pTargetMonsterItem->CurrentCount < pQuestInfo->TargetMonsterItemVector[j].ItemWithCount.Count)
			{
				return ERR_PROTOCOL_QUEST_GENERAL_ERROR;
			}
		}

		// 필요 아이템 확인
		for (int i = 0; i < pQuestInfo->TargetItemVector.size(); i++)
		{
			ITEM_W_COUNT tmpItemWCount = pQuestInfo->TargetItemVector[i];

			ITEM_BASE *pItem = m_ItemManager.GetFirstItemGeneralByItemNum(tmpItemWCount.ItemNum);
			if (pItem == NULL || (IS_GENERAL_ITEM(pItem->ItemInfo->Kind) && ((ITEM_GENERAL*)pItem)->CurrentCount < tmpItemWCount.Count))
			{
				return ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED;
			}
		}

		// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
		if ( 0 < pQuestInfo->TargetUseItemVector.size() )
		{
			BOOL bUseItemCheck = FALSE;
			vector<ITEM_W_COUNT>::iterator itrUseItem = pQuestInfo->TargetUseItemVector.begin();
			for ( ; itrUseItem != pQuestInfo->TargetUseItemVector.end() ; itrUseItem++ )
			{
				if ( i_nUseItem == itrUseItem->ItemNum )
				{
					itrUseItem->Count = max(0, itrUseItem->Count-1);
				}
				if ( 0 == itrUseItem->Count )
				{
					bUseItemCheck = TRUE;	// 조건중에 하나라도 완료하면 퀘스트 클리어
				}
			}
			if ( FALSE == bUseItemCheck )
			{
				return ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED;
			}
		}
		// end 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
	}

	// 2005-10-19 by cmkwon, 필요 몬스터 카운트 확인
	for (int i = 0; i < pQuestInfo->TargetMonsterVector.size(); i++)
	{
		MONSTER_W_COUNT tmpMonWCount = pQuestInfo->TargetMonsterVector[i];

		if(0 >= tmpMonWCount.Count)
		{// 2007-03-14 by cmkwon, 몬스터 카운트가 0 이하이면 체크가 필요 없음
			continue;
		}

		CharacterQuestMonsterCount *pMonCount = i_pFCharQuest->FindMonsterCountByMonsterUniqueNumber(tmpMonWCount.MonsterUniqueNumber);

		if(NULL == pMonCount
			|| pMonCount->Count < tmpMonWCount.Count)
		{
			return ERR_PROTOCOL_REQ_MONSTER_NOT_MATCHED;
		}
	}

// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
//	// 필요 무게 확인
//	if (GetCurrentLoadagePercentage(pQuestInfo->EndPayItemWeight) > 1.0f)
//	{
//		return ERR_PROTOCOL_ITEM_OVER_WEIGHT;
//	}

	// 시간 제한 확인
	if (pQuestInfo->TimeLimitInMinutes != 0
//		&& pCharacterQuest->QuestTimeStamp.GetTimeDiffToCurrentTimeInSeconds() > pQuestInfo->TimeLimitInMinutes*60
//		&& GetTotalPlayTimeInSeconds() - pCharacterQuest->QuestPlayTimeStamp > pQuestInfo->TimeLimitInMinutes*60
		&& i_pQuestSuccess->SpentTimeInSeconds > pQuestInfo->TimeLimitInMinutes * 60
	)
	{
		return ERR_PROTOCOL_TIME_LIMIT_ERROR;
	}

	if(0 != pQuestInfo->TargetMeetObjectMapArea.MapIndex)
	{
		if(pQuestInfo->TargetMeetObjectMapArea.MapIndex != i_nMapIndex
			|| pQuestInfo->TargetMeetObjectIndex != i_nWarpTargetIndex)
		{
			return ERR_PROTOCOL_REQ_MAP_OBJECT_NOT_MATCHED;
		}
	}

	if(0 != pQuestInfo->TargetDeadByMonsterUniquenumber)
	{
		if(pQuestInfo->TargetDeadByMonsterUniquenumber != i_nAttMonster)
		{
			return ERR_PROTOCOL_QUEST_GENERAL_ERROR;
		}
	}

	if(FALSE == pQuestInfo->TargetMeetMapArea.IsPositionInArea(m_character.MapChannelIndex.MapIndex, i_pQuestSuccess->AVec3QuestPosition.x, i_pQuestSuccess->AVec3QuestPosition.z))
	{
		return ERR_PROTOCOL_REQ_MAP_AREA_NOT_MATCHED;
	}

	if(pQuestInfo->IsPartyQuest()
		&& NULL == m_pFieldParty)
	{// 2006-03-24 by cmkwon, 파티퀘스트 완료시 파티 상태여야 함
		return ERR_PROTOCOL_NO_SUCH_PARTY;
	}

	return ERR_NO_ERROR;
}

ProcessResult CFieldIOCPSocket::CheckQuestRequestSuccessAndSendResult(CFieldCharacterQuest *i_pFCharQuest
																	  , MSG_FC_QUEST_REQUEST_SUCCESS *i_pQuestSuccess
																	  , BOOL i_bSendErrorMessage/*=TRUE*/
																	  , MapIndex_t i_nMapIndex/*=0*/
																	  , INT i_nWarpTargetIndex/*=0*/
																	  , INT i_nAttMonster/*=0*/
																	  , BOOL i_bOnlyCompletionCheck/*=FALSE*/
																	  , BOOL i_bFreepass/*=FALSE*/		// 2013-08-07 by bckim, 미션프리패스 아이템
																	  , ItemNum_t i_nUseItem/* = 0*/)		// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
{
	CQuest *pQuestInfo = i_pFCharQuest->GetQuestInfo();		// 퀘스트가 삭제되어도 유지되어야 한다.
	if(NULL == pQuestInfo)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_NO_SUCH_QUEST_INFO, i_pFCharQuest->QuestIndex);
		return RES_BREAK;
	}

	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
//	Err_t errQuestCompletion = CheckQuestCompetionRequirements(i_pFCharQuest, i_pQuestSuccess, i_nMapIndex, i_nWarpTargetIndex, i_nAttMonster);
	Err_t errQuestCompletion = CheckQuestCompetionRequirements(i_pFCharQuest, i_pQuestSuccess, i_nMapIndex, i_nWarpTargetIndex, i_nAttMonster, TRUE, i_nUseItem);
	// end 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 사용한 아이템 확인
	
	// 2013-08-07 by bckim, 미션프리패스 아이템
	if( i_bFreepass )
	{
		errQuestCompletion = ERR_NO_ERROR;	
	}
	// End. 2013-08-07 by bckim, 미션프리패스 아이템
	
	if (errQuestCompletion != ERR_NO_ERROR)
	{// 퀘스트 완료 조건 불만족 시

		if(i_bSendErrorMessage
			&& FALSE == i_bOnlyCompletionCheck)
		{
			// client는 해당 퀘스트의 NPC_QUEST_TALK_IN_PROGRESS 을 보여주면 된다. NPC_QUEST_TALK_IN_PROGRESS가 없는 경우는 아무것도 보여줄 필요 없다.
			INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT, T_FC_QUEST_REQUEST_SUCCESS_RESULT, pSuccessResult, pSuccessResultBuf);
			pSuccessResult->QuestIndex		= i_pFCharQuest->QuestIndex;
			pSuccessResult->IsSuccessful	= FALSE;
			SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT));

			// check: 필요 없을 듯. 삭제 가능. 20040220, kelovon
			SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, errQuestCompletion, i_pFCharQuest->QuestIndex, this->GetSelectableInfluenceMask());
		}
		return RES_BREAK;
	}

	if(i_bOnlyCompletionCheck)
	{// 2006-03-24 by cmkwon, 파티퀘스트 완료 체크시 사용됨
		return RES_RETURN_TRUE;
	}
	
	// 퀘스트 완료 조건 만족 체크
	int nExpOfCompensation = 0;		// 2007-03-06 by cmkwon, 추가함

	// 2007-07-09 by dhjin, 퀘스트 완료시 보상 정보 추가하여 전송.
	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT, T_FC_QUEST_REQUEST_SUCCESS_RESULT, pSuccessResult, pSuccessResultBuf);
	if (FALSE == ProcessQuestResult(&nExpOfCompensation, i_pFCharQuest->GetQuestInfo(), i_pQuestSuccess->QuestResult, pSuccessResult
									, (QUEST_PAY_ITEM_INFO*)(pSuccessResultBuf+MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT))))
	{
		if(i_bSendErrorMessage)
		{
			SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_QUEST_RESULT_PROCESS_FAILED);
		}
		return RES_BREAK;
	}

	if (pQuestInfo->QuestType == QUEST_TYPE_REPEATABLE)
	{
		// 퀘스트를 삭제한다
		QPARAM_DELETE_QUEST *pQDeleteQuest		= new QPARAM_DELETE_QUEST;
		pQDeleteQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQDeleteQuest->QuestIndex				= i_pFCharQuest->QuestIndex;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);

		m_mapQuest.deleteLock(i_pFCharQuest->QuestIndex);
	}
	else
	{
		// Update Field
		i_pFCharQuest->QuestState				= QUEST_STATE_COMPLETED;

		// Update DB
		QPARAM_UPDATE_QUEST *pQUpdateQuest		= new QPARAM_UPDATE_QUEST;
		pQUpdateQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQUpdateQuest->QuestIndex				= i_pFCharQuest->QuestIndex;
		pQUpdateQuest->QuestState				= i_pFCharQuest->QuestState;
		pQUpdateQuest->QuestProgressTimeInSecond	= this->GetTotalPlayTimeInSeconds() - i_pFCharQuest->QuestPlayTimeStamp;	// 2006-08-31 by cmkwon, 퀘스트 진행 시간 저장
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateQuestState, this, m_character.AccountUniqueNumber, pQUpdateQuest);
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 완료한 퀘스트 로그에 남기기
	CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, pQuestInfo->QuestIndex, i_bFreepass);		// send log		// 2013-08-07 by bckim, 미션프리패스 아이템 //미션프리패스 아이템 사용유무 인자추가 

	pSuccessResult->QuestIndex				= pQuestInfo->QuestIndex;
	pSuccessResult->IsSuccessful			= TRUE;
	pSuccessResult->ExpOfCompensation		= nExpOfCompensation;		// 2007-03-06 by cmkwon
	SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT)+pSuccessResult->QuestPayInfoListCount*sizeof(QUEST_PAY_ITEM_INFO));

// 2007-01-24 by cmkwon, 이벤트 기간 종료
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-12-22 by cmkwon, 정규군,반란군 선택 이벤트
//	if(QUEST_END_TYPE_SELECT_INFLUENCE == pQuestInfo->QuestEndType
//		&& LANGUAGE_TYPE_KOREAN == g_pFieldGlobal->GetLanguageType())
//	{
//		ATUM_DATE_TIME atStart, atEnd;
//		ATUM_DATE_TIME atCur(TRUE);
//
//		atStart.SetDateTime(2006, 12, 26, 10, 0, 0);		// 2006-12-26 10:00:00
//		atEnd.SetDateTime(2007, 1, 23, 11, 0, 0);			// 2007-01-23 11:00:00
//		if(atCur > atStart
//			&& atCur < atEnd)
//		{
//			this->SendString128(STRING_128_USER_NOTICE, "축하합니다. [너의 소속을 밝혀라] 이벤트에 응모 되셨습니다.");
//
//			char szSysLog[1024];
//			sprintf(szSysLog, "[너의 소속을 밝혀라]|%s|%d|%s|%d|%s\r\n"
//				, m_character.AccountName, m_character.AccountUniqueNumber, m_character.CharacterName, m_character.CharacterUniqueNumber
//				, CAtumSJ::GetInfluenceTypeString(m_character.InfluenceType));
//			g_pFieldGlobal->WriteSystemLog(szSysLog);
//		}
//	}
	
	return RES_RETURN_TRUE;
}

void CFieldIOCPSocket::CheckSuccessAllQuestByWarpTargetIndex(MapIndex_t i_nMapIndex, INT i_nWarpTargetIndex)
{
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// lock m_ItemManager.m_mapItemGeneral - @CheckQuestCompetionRequirements, @ProcessQuestResult
	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest
	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest= m_mapQuest.begin();
	for(; itrQuest != m_mapQuest.end(); itrQuest++)
	{
		CFieldCharacterQuest *pFCharQuest = &itrQuest->second;
		if (pFCharQuest->QuestState == QUEST_STATE_IN_PROGRESS)
		{
			CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
			if(pQuestInfo
				&& i_nMapIndex == pQuestInfo->TargetMeetObjectMapArea.MapIndex
				&& i_nWarpTargetIndex == pQuestInfo->TargetMeetObjectIndex)
			{
				MSG_FC_QUEST_REQUEST_SUCCESS tmQuest;
				tmQuest.QuestIndex			= pQuestInfo->QuestIndex;
				tmQuest.SpentTimeInSeconds	= 0;
				tmQuest.QuestResult			= 0;
				this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, &tmQuest, FALSE, i_nMapIndex, i_nWarpTargetIndex);
				break;	// 2005-08-17 by cmkwon, 퀘스트를 하나만 체크하고 빠져 나간다
			}
		}
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckSuccessAllQuestByAttackMonsterNum(INT i_nAttackMonsterNum)
/// \brief		
/// \author		cmkwon
/// \date		2005-08-22 ~ 2005-08-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckSuccessAllQuestByAttackMonsterNum(INT i_nAttackMonsterNum)
{
	if(0 == i_nAttackMonsterNum){					return;}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// lock m_ItemManager.m_mapItemGeneral - @CheckQuestCompetionRequirements, @ProcessQuestResult
	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest
	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest= m_mapQuest.begin();
	for(; itrQuest != m_mapQuest.end(); itrQuest++)
	{
		CFieldCharacterQuest *pFCharQuest = &itrQuest->second;
		if (pFCharQuest->QuestState == QUEST_STATE_IN_PROGRESS)
		{
			CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
			if(pQuestInfo
				&& i_nAttackMonsterNum == pQuestInfo->TargetDeadByMonsterUniquenumber)
			{
				MSG_FC_QUEST_REQUEST_SUCCESS tmQuest;
				tmQuest.QuestIndex			= pQuestInfo->QuestIndex;
				tmQuest.SpentTimeInSeconds	= 0;
				tmQuest.QuestResult			= 0;
				this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, &tmQuest, FALSE, 0, 0, i_nAttackMonsterNum);
			}
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckSuccessProgressQuestByTimeLimited(void)
/// \brief		// 2007-12-06 by cmkwon, 시간제한 퀘스트 서버에서 시간 체크하게 수정 - CheckSuccessProgressQuestByTimeLimited() 추가
/// \author		cmkwon
/// \date		2007-12-06 ~ 2007-12-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckSuccessProgressQuestByTimeLimited(void)
{
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// lock m_ItemManager.m_mapItemGeneral - @CheckQuestCompetionRequirements, @ProcessQuestResult
	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest

	
	CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();	// 2007-12-06 by cmkwon, 현재 진행중인 퀘스트를 가져온다
	if(NULL == pFCharQuest
		|| FALSE == pFCharQuest->m_pQuestInfo->IsEndTypeTimeOver())	// 2007-12-06 by cmkwon, 시간제한형 퀘스트가 아니면 리턴
	{
		return;
	}

	LONGLONG	llTPlayTime		= this->GetTotalPlayTimeInSeconds();
	int			nSpentTimeSec	= llTPlayTime - pFCharQuest->QuestPlayTimeStamp;

	// 2007-12-06 by cmkwon, 서버에서 체크는 최소 30초 경과 후 완료되도록
	if(FALSE == pFCharQuest->m_pQuestInfo->IsCompleteEndTypeTimeOver(max(0, nSpentTimeSec-30)))
	{
		return;
	}

	// 2007-12-06 by cmkwon, 테스트만을 위한 임시용 - 본섭에 올려서 이상 없으면 나중에 제거 해야함
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] CFieldIOCPSocket::CheckSuccessProgressQuestByTimeLimited_ %s, QuestIndex(%d), TotalPlayTime(%I64d), PlayTimeAtQuestStart(%I64d), TimeGap(%dsec)\r\n"
		, GetCharacterString(&m_character, string()), pFCharQuest->QuestIndex, llTPlayTime, pFCharQuest->QuestPlayTimeStamp, nSpentTimeSec);

	MSG_FC_QUEST_REQUEST_SUCCESS tmQuestReqSuccess;
	tmQuestReqSuccess.QuestIndex			= pFCharQuest->m_pQuestInfo->QuestIndex;
	tmQuestReqSuccess.SpentTimeInSeconds	= nSpentTimeSec;
	tmQuestReqSuccess.QuestResult			= 0;
	this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, &tmQuestReqSuccess, FALSE);	
}
	

// error 메세지를 전송
void CFieldIOCPSocket::SendErrorMessage(MessageType_t msgType, Err_t err, int errParam1, int errParam2
										, char* errMsg/*=NULL*/
										, BOOL bCloseConnection/*=FALSE*/
										, BOOL i_bWriteSystemLog/*=TRUE*/)
{
	MSG_ERROR	*pMsgError;
	BYTE		SendBuf[SIZE_MAX_PACKET];

	if(i_bWriteSystemLog)
	{
		char szSystemLog[2048];		// 2009-12-15 by cmkwon, 서버 죽는 버그 수정(2048로변경) - 
		sprintf(szSystemLog, "  SendErrorMsg to %s %s ==> %s(%#04x) AT %s Param1(%d) Param2(%d) Msg(%s)\r\n",
			GetCharacterString(&m_character, string()), m_szPeerIP,
			GetErrorString(err), err, GetProtocolTypeString(msgType), errParam1, errParam2, errMsg);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
#ifdef _DEBUG
	//	if (err != ERR_PROTOCOL_INVALID_MAP_EVENT_INFO)
		{
			DBGOUT(szSystemLog);
		}
#endif
	}

	*(MessageType_t*)SendBuf = T_ERROR;
	pMsgError = (MSG_ERROR*)(SendBuf+SIZE_FIELD_TYPE_HEADER);
	pMsgError->CloseConnection = bCloseConnection;
	pMsgError->ErrorCode = err;
	pMsgError->MsgType = msgType;
	pMsgError->ErrParam1 = errParam1;
	pMsgError->ErrParam2 = errParam2;
	if (errMsg == NULL)
	{
		pMsgError->StringLength = 0;
	}
	else
	{
		pMsgError->StringLength = (USHORT)(strlen(errMsg) + 1);
		STRNCPY_MEMSET((char*)SendBuf + MSG_SIZE(MSG_ERROR), errMsg, SIZE_MAX_ERROR_STRING);
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_ERROR) + pMsgError->StringLength);
}

void CFieldIOCPSocket::SendNetworkErrorMessage(int i_nWriteBufCounts, int i_nBadNetworkContinueTime)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2008-03-13 by cmkwon, 아래와 같이 정리함
	switch(m_PeerSocketType)
	{
	case ST_CLIENT_TYPE:
		{
			BOOL bCloseFlag = i_nWriteBufCounts > 200 ? TRUE:FALSE;			
			this->SendErrorMessage(T_FC_CONNECT_ALIVE, ERR_COMMON_BAD_NETWORK, i_nWriteBufCounts, i_nBadNetworkContinueTime, NULL, bCloseFlag);
						
			if(bCloseFlag
				&& i_nBadNetworkContinueTime > 60000)
			{
				m_bMustClose					= TRUE;		// 2007-03-12 by cmkwon
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify]: Closed by Bad network !!, %s IP|%s| SockIdx|%4d| WriteBufCount|%8d| ContinueTime|%8d|\r\n"
					, GetCharacterString(GetCharacter(), string()), GetPeerIP(), this->GetClientArrayIndex(), i_nWriteBufCounts, i_nBadNetworkContinueTime);

				// 2008-03-19 by cmkwon, 대규모 전쟁시 클라이언트 랙(lack) 현상 수정 - 네트워크 상태가 좋지 안아 종료되는 유저의 데이터를 파일로 저장한다.
				this->SaveDataOfWriteBufList();
			}
		}
		break;
	default:
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] SendNetworkError !! IP|%s| SockIdx|%4d| WriteBufCount|%8d| ContinueTime|%8d|\r\n"
				, GetPeerIP(), this->GetClientArrayIndex(), i_nWriteBufCounts, i_nBadNetworkContinueTime);
		}
	}

// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 위와 같이 수정함
// 	if(ST_CLIENT_TYPE == m_PeerSocketType)
// 	{
// 		// 2008-03-10 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 400 으로 수정(<==200)
// 		BOOL bCloseFlag = i_nWriteBufCounts > 400 ? TRUE:FALSE;
// 		//	this->SendErrorMessage(T_FC_CONNECT_ALIVE, ERR_COMMON_BAD_NETWORK
// 		//		, i_nWriteBufCounts, i_nBadNetworkContinueTime, NULL
// 		//		, (i_nWriteBufCounts > 50 ? TRUE:FALSE));
// 		
// 		// 2004-11-15 by cmkwon, WriteBufCounts가 100보다 크면 소켓을 Cloese한다
// 		this->SendErrorMessage(T_FC_CONNECT_ALIVE, ERR_COMMON_BAD_NETWORK
// 			, i_nWriteBufCounts, i_nBadNetworkContinueTime, NULL
// 			, bCloseFlag);
// 		
// 		// 2008-03-10 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 60000 으로 수정(<==30000)
// 		if(bCloseFlag
// 			&& i_nBadNetworkContinueTime > 60000)
// 		{
// 			m_bMustClose					= TRUE;		// 2007-03-12 by cmkwon
// // 2007-03-12 by cmkwon, 종료를 Alive 체크 쪽에서 처리, 데드락 관련 처리
// //			Sleep(100);
// //			this->Close(0, FALSE);
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify]: Closed by Bad network !!, %s WriteBufCount(%d) BadnetworkContinueTime(%d)\r\n"
// 				, GetCharacterString(GetCharacter(), string()), i_nWriteBufCounts, i_nBadNetworkContinueTime);
// 		}
// 	}
// #ifdef _DEBUG
// 	else
// 	{
// 		char szSystemLog[256];
// 		sprintf(szSystemLog, "[ERROR] SendNetworkError to %s %s ==> WriteBufCounts(%4d) ContinueTime(%5d)\r\n"
// 			, GetCharacterString(&m_character, string()), m_szPeerIP
// 			, i_nWriteBufCounts, i_nBadNetworkContinueTime);
// 		g_pFieldGlobal->WriteSystemLog(szSystemLog);	
// 	}
// #endif// _DEBUG_endif
}

// error 메세지를 전송
void CFieldIOCPSocket::SendErrorMessageFromFieldDB(EnumQueryType qType, Err_t err, int errParam1, int errParam2, char* errMsg, BOOL bCloseConnection)
{
	if(FALSE == IsUsing()){						return;	}

	MSG_ERROR	*pMsgError;
	BYTE		SendBuf[SIZE_MAX_PACKET];

	char szSystemLog[256];
	sprintf(szSystemLog, "  SendErrorMessageFromFieldDB to %s %s ==> %s(%#04x) AT %s Param1(%d) Param2(%d) Msg(%s)\r\n",
		GetCharacterString(&m_character, string()), m_szPeerIP,
		GetErrorString(err), err, GetDBQueryTypeString(qType), errParam1, errParam2, errMsg);
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
#ifdef _DEBUG
//	if (err != ERR_PROTOCOL_INVALID_MAP_EVENT_INFO)
	{
		DBGOUT(szSystemLog);
	}
#endif

	*(MessageType_t*)SendBuf = T_ERROR;
	pMsgError = (MSG_ERROR*)(SendBuf+SIZE_FIELD_TYPE_HEADER);
	pMsgError->CloseConnection = bCloseConnection;
	pMsgError->ErrorCode = err;
	pMsgError->MsgType = T_FIELD_DB;
	pMsgError->ErrParam1 = errParam1;
	pMsgError->ErrParam2 = errParam2;
	if (errMsg == NULL)
	{
		pMsgError->StringLength = 0;
	}
	else
	{
		pMsgError->StringLength = (USHORT)(strlen(errMsg) + 1);
		STRNCPY_MEMSET((char*)SendBuf + MSG_SIZE(MSG_ERROR), errMsg, SIZE_MAX_ERROR_STRING);
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_ERROR) + pMsgError->StringLength);
}

BOOL CFieldIOCPSocket::IsSamePartyByClientIndex(ClientIndex_t clientIndex)
{
	CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pMeFParty == NULL)
	{
		return FALSE;
	}

	CFieldIOCPSocket *pSocket = ms_pFieldIOCP->GetFieldIOCPSocket(clientIndex);
	if (!pSocket->IsUsing())
	{
		return FALSE;
	}

	CFieldParty *pPeerFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pPeerFParty == NULL)
	{
		return FALSE;
	}

	return (pPeerFParty->m_PartyID == pMeFParty->m_PartyID);
}

BOOL CFieldIOCPSocket::IsSamePartyByCharacterUniqueNumber(UID32_t characterUniqueNumber)
{
	CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pMeFParty == NULL)
	{
		return FALSE;
	}

	CFieldIOCPSocket *pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(characterUniqueNumber);
	if (NULL == pSocket
		|| FALSE == pSocket->IsValidCharacter(FALSE))
	{
		return FALSE;
	}

	CFieldParty *pPeerFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pPeerFParty == NULL)
	{
		return FALSE;
	}

	return (pPeerFParty->m_PartyID == pMeFParty->m_PartyID);
}


void CFieldIOCPSocket::PartyGetMemberClientIdxListExcludeMe(vectorClientIndex *o_pVectClientIndex
															, ClientIndex_t i_excludeCltIdx/*=0*/
															, BOOL i_bOnlySameMapChannel/*=FALSE*/
															, BOOL i_bOnlyNoBodyConEventHandle/*=FALSE*/)
{
	CFieldParty *pParty = this->m_pFieldParty;
	if (NULL == pParty)
	{
		return;
	}

	pParty->m_ListPartyMember.lock();
	int nSize = pParty->m_ListPartyMember.size();
	
	for(int i=0; i < nSize; i++)
	{
		CFieldIOCPSocket *pSocket = pParty->m_ListPartyMember[i].PM_CharacterSocket;
		if (pSocket
			&& pSocket != this
			&& pSocket->IsUsing()
			&& pSocket->m_character.ClientIndex != i_excludeCltIdx)
		{
			if(FALSE == i_bOnlySameMapChannel
				|| pSocket->m_pCurrentFieldMapChannel == this->m_pCurrentFieldMapChannel)
			{
				if(FALSE == i_bOnlyNoBodyConEventHandle
					|| FALSE == COMPARE_BODYCON_BIT(pSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
				{
					o_pVectClientIndex->push_back(pSocket->m_character.ClientIndex);
				}
			}					
		}
	}
	pParty->m_ListPartyMember.unlock();
}

UID32_t CFieldIOCPSocket::GetPartyMasterUniqueNumber()
{
	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pFParty == NULL)
	{
		return INVALID_UNIQUE_NUMBER;
	}

	return pFParty->GetMasterCharacterUniqueNumber();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsPartyMaster(void)
/// \brief		
/// \author		cmkwon
/// \date		2007-02-12 ~ 2007-02-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsPartyMaster(void)
{
	CFieldParty *pFParty = m_pFieldParty;
	if(NULL == pFParty)
	{
		return FALSE;
	}

	mt_auto_lock mtFP(&pFParty->m_ListPartyMember);
	return m_character.CharacterUniqueNumber == pFParty->GetMasterCharacterUniqueNumber();
}

BOOL CFieldIOCPSocket::IsSameParty(CFieldIOCPSocket *pSocket)
{
	CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pMeFParty == NULL)
	{
		return FALSE;
	}
	
	if (pSocket == NULL || FALSE == pSocket->IsUsing())
	{
		return FALSE;
	}
	
	CFieldParty *pPeerFParty = pSocket->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(NULL == pPeerFParty)
	{
		return FALSE;
	}	

	return (pPeerFParty->m_PartyID == pMeFParty->m_PartyID);
}

void CFieldIOCPSocket::OnPartyBattleMemberDead(BOOL bImediateLoss)
{
	CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (NULL == pMeFParty
		|| FALSE == this->IsPartyBattleState())
	{
		return;
	}

	pMeFParty->m_ListPartyMember.lock();

	// live member lock
	pMeFParty->m_PartyBattle.m_setLiveMember.lock();

	pMeFParty->m_PartyBattle.m_setLiveMember.deleteLock(m_character.CharacterUniqueNumber);

	if (bImediateLoss)
	{
// 2005-12-27 by cmkwon, 1:1 PK로 명성치를 올리지 않는다 - 명성치는 타세력을 죽였을 때만 증가된다.
//		// 즉시 패배를 처리
//		m_character.PKLossPoint += 1;
//		m_character.Propensity
//			-= (5 + max(m_pFieldParty->m_PartyBattle.m_nAverageLevel - m_pFieldParty->m_PartyBattle.m_nPeerAverageLevel, 0));
//		CheckAndUpdateStatus();
//		SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
//		// DB에 저장
//		QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointLoser = new QPARAM_CHARACTER_CHANGE_PKPOINT;
//		pQChangePKPointLoser->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
//		pQChangePKPointLoser->Propensity = m_character.Propensity;
//		pQChangePKPointLoser->PKWinPoint = m_character.PKWinPoint;
//		pQChangePKPointLoser->PKLossPoint = m_character.PKLossPoint;
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, this, m_character.AccountUniqueNumber, pQChangePKPointLoser);
	}
	else
	{
		pMeFParty->m_PartyBattle.m_setLossWaiters.insertLock(m_character.CharacterUniqueNumber);
	}

	if (pMeFParty->m_PartyBattle.m_setLiveMember.empty())
	{
		// live member unlock
		pMeFParty->m_PartyBattle.m_setLiveMember.unlock();

		// 모두 죽음, 파티전 패배
		PartyID_t tmpPeerPartyID = pMeFParty->m_PeerBattlePartyID;
		pMeFParty->m_PeerBattlePartyID = 0;	// 더 이상의 파티전 관련 루틴을 막기 위해 초기화, ex) 죽은 후에 미사일 맞기 등

		CFieldParty *pPeerWinnerParty = ms_pFieldIOCP->m_MapParties.findLock(tmpPeerPartyID);
		if (pPeerWinnerParty != NULL)
		{
			pPeerWinnerParty->m_PeerBattlePartyID = 0;	// 더 이상의 파티전 관련 루틴을 막기 위해 초기화, ex) 죽은 후에 미사일 맞기 등

			// 파티전 결과 처리
			OnPartyBattleEnd(pPeerWinnerParty, pMeFParty);
		}
	}
	else
	{
		// just live member unlock
		pMeFParty->m_PartyBattle.m_setLiveMember.unlock();
	}

	// party unlock
	pMeFParty->m_ListPartyMember.unlock();
}

BOOL CFieldIOCPSocket::IsPartyBattleState(void)
{
	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(NULL == pFParty
		|| 0 == pFParty->m_PeerBattlePartyID)
	{
		return FALSE;
	}

	return TRUE;
}

void CFieldIOCPSocket::OnPartyBattleEnd(CFieldParty *pWinnerParty, CFieldParty *pLoserParty)
{
	///////////////////////////////////////////////////////////////////////////
	// Winner Party 처리
	///////////////////////////////////////////////////////////////////////////
	if (pWinnerParty != NULL)
	{
		mt_auto_lock pmlock(&pWinnerParty->m_ListPartyMember);

		// 파티전 결과 통보
		INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_BATTLE_END, T_FC_PARTY_BATTLE_END, pPartyBattleEnd, pPartyBattleEndBuf);
		// To Winner
		pPartyBattleEnd->EndType = BATTLE_END_WIN;
		pPartyBattleEnd->PeerPartyID = pWinnerParty->m_PeerBattlePartyID;
		pWinnerParty->SendMsgToMembersMap(pPartyBattleEndBuf, MSG_SIZE(MSG_FC_PARTY_BATTLE_END), pWinnerParty->m_PartyBattle.m_pBattleMapChannel);

// 2005-12-27 by cmkwon, 1:1 PK로 명성치를 올리지 않는다 - 명성치는 타세력을 죽였을 때만 증가된다.
//		// PK 수치 조정
//		mtlistFieldPartyMember::iterator itrWinner = pWinnerParty->m_ListPartyMember.begin();
//		while (itrWinner != pWinnerParty->m_ListPartyMember.end())
//		{
//			CFieldIOCPSocket *pWinnerSocket = (*itrWinner).PM_CharacterSocket;
//
//			if (pWinnerSocket->IsUsing())
//			{
//				pWinnerSocket->m_character.PKWinPoint += 1;
//				pWinnerSocket->m_character.Propensity += max(0, (10 + pWinnerParty->m_PartyBattle.m_nPeerAverageLevel - pWinnerParty->m_PartyBattle.m_nAverageLevel));
//				pWinnerSocket->CheckAndUpdateStatus();
//				pWinnerSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
//				// DB에 저장
//				QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointWinner = new QPARAM_CHARACTER_CHANGE_PKPOINT;
//				pQChangePKPointWinner->CharacterUniqueNumber = pWinnerSocket->m_character.CharacterUniqueNumber;
//				pQChangePKPointWinner->Propensity = pWinnerSocket->m_character.Propensity;
//				pQChangePKPointWinner->PKWinPoint = pWinnerSocket->m_character.PKWinPoint;
//				pQChangePKPointWinner->PKLossPoint = pWinnerSocket->m_character.PKLossPoint;
//				pWinnerSocket->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, pWinnerSocket, pWinnerSocket->m_character.AccountUniqueNumber, pQChangePKPointWinner);
//			}
//
//			itrWinner++;
//		}

		// Reset
		pWinnerParty->m_PeerBattleRequesterPartyID = 0;
		pWinnerParty->m_PeerBattlePartyID = 0;
		pWinnerParty->m_PartyBattle.CleanFieldPartyBattle();
	}

	///////////////////////////////////////////////////////////////////////////
	// Loser Party 처리
	///////////////////////////////////////////////////////////////////////////
	if (pLoserParty != NULL)
	{
		// lock m_ListPartyMember
		mt_auto_lock pmlock(&pLoserParty->m_ListPartyMember);

		// 파티전 결과 통보
		INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_BATTLE_END, T_FC_PARTY_BATTLE_END, pPartyBattleEnd, pPartyBattleEndBuf);
		pPartyBattleEnd->EndType = BATTLE_END_DEFEAT;
		pPartyBattleEnd->PeerPartyID = pLoserParty->m_PeerBattlePartyID;
		pLoserParty->SendMsgToMembersMap(pPartyBattleEndBuf, MSG_SIZE(MSG_FC_PARTY_BATTLE_END), pLoserParty->m_PartyBattle.m_pBattleMapChannel);

		pLoserParty->m_PartyBattle.m_setLossWaiters.lock();
// 2005-12-27 by cmkwon, 1:1 PK로 명성치를 올리지 않는다 - 명성치는 타세력을 죽였을 때만 증가된다.
//		// PK 수치 조정
//		mtsetUID32::iterator itrLoserCharacter = pLoserParty->m_PartyBattle.m_setLossWaiters.begin();
//		while (itrLoserCharacter != pLoserParty->m_PartyBattle.m_setLossWaiters.end())
//		{
//			UID32_t loserCharacterUniqueNumber = (*itrLoserCharacter);
//			CFieldIOCPSocket *pLoserSocket = pLoserParty->m_pFieldIOCP7->m_mapCharacterUniqueNumber.findLock(loserCharacterUniqueNumber);
//			if (pLoserSocket == NULL)
//			{
//				// check: fatal error
//				g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL ERROR@OnPartyBattleEnd: loser socket is null(%d)\r\n", loserCharacterUniqueNumber);
//			}
//			else
//			{
//				pLoserSocket->m_character.PKLossPoint += 1;
//				pLoserSocket->m_character.Propensity -= (5 + max(pLoserParty->m_PartyBattle.m_nAverageLevel - pLoserParty->m_PartyBattle.m_nPeerAverageLevel, 0));
//				pLoserSocket->CheckAndUpdateStatus();
//				pLoserSocket->SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
//				// DB에 저장
//				QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointLoser = new QPARAM_CHARACTER_CHANGE_PKPOINT;
//				pQChangePKPointLoser->CharacterUniqueNumber = pLoserSocket->m_character.CharacterUniqueNumber;
//				pQChangePKPointLoser->Propensity = pLoserSocket->m_character.Propensity;
//				pQChangePKPointLoser->PKWinPoint = pLoserSocket->m_character.PKWinPoint;
//				pQChangePKPointLoser->PKLossPoint = pLoserSocket->m_character.PKLossPoint;
//				pLoserSocket->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, pLoserSocket, pLoserSocket->m_character.AccountUniqueNumber, pQChangePKPointLoser);
//			}
//
//			itrLoserCharacter++;
//		}
		pLoserParty->m_PartyBattle.m_setLossWaiters.clearLock();
		pLoserParty->m_PartyBattle.m_setLossWaiters.unlock();

		// Reset
		pLoserParty->m_PeerBattleRequesterPartyID = 0;
		pLoserParty->m_PeerBattlePartyID = 0;
		pLoserParty->m_PartyBattle.CleanFieldPartyBattle();
	}
}


void CFieldIOCPSocket::DBGOUT2(BitFlag8_t bType, char* pFormat, ...)
{
	if (bType == DO2_NONE)
	{
		return;
	}

	char szLogMsg[1024];
	va_list args;
	va_start(args, pFormat);
	vsprintf(szLogMsg, pFormat, args);

	if (COMPARE_BIT_FLAG(bType, DO2_DBGOUT)) DBGOUT(szLogMsg);
	if (COMPARE_BIT_FLAG(bType, DO2_SYSLOG)) g_pFieldGlobal->WriteSystemLog(szLogMsg, TRUE);
	if (COMPARE_BIT_FLAG(bType, DO2_STR128)) SendString128(STRING_128_ADMIN_CMD, szLogMsg);
}

void CFieldIOCPSocket::StartTestDBG(int nParam1, int nParam2, int nParam3, const char *szParam1, const char *szParam2, const char *szParam3)
{
	// 경매 테스트
//	int nBytesUsed = 0;
//	MSG_FC_AUCTION_CANCEL_REGISTER msgReg;
//	msgReg.ItemUID = nParam1;
//	Process_FC_AUCTION_CANCEL_REGISTER((char*)&msgReg, sizeof(MSG_FC_AUCTION_CANCEL_REGISTER), nBytesUsed);

//	// 타이머 테스트
//	m_TimerManager.StartTimerField(TE_TYPE_TEST, 2000, 1, 2, 3, 100);

// 	int nByteUsed = 0;
//	MSG_FC_GUILD_GET_MAP_OWNER_INFO msgGetOwnerInfo;
//	msgGetOwnerInfo.MapIndex = m_character.MapChannelIndex.MapIndex;
//	Process_FC_GUILD_GET_MAP_OWNER_INFO((char*)&msgGetOwnerInfo, sizeof(MSG_FC_GUILD_GET_MAP_OWNER_INFO), nByteUsed);

	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 임시 명령어 만듬
	if(0 == stricmp(szParam1, "Release")
		&& 0 == stricmp(szParam2, "Security")
		&& 0 == stricmp(szParam3, "System"))
	{
		CFieldIOCPSocket::SecurityServerClean();
		this->SendString128(STRING_128_ADMIN_CMD, "Released security system !!");
	}
}

BOOL CFieldIOCPSocket::CheckValidAttackTargetCharacter(CFieldMapChannel *i_pFMChann, ClientIndex_t i_targetIndex)
{
	CFieldIOCPSocket *pTargetSocket	= NULL;
	CHARACTER *pTargetCharacter		= NULL;

	return CheckValidAttackTargetCharacter(i_pFMChann, i_targetIndex, pTargetSocket, pTargetCharacter);
}

BOOL CFieldIOCPSocket::CheckValidAttackTargetCharacter(CFieldMapChannel *i_pFMChann, ClientIndex_t i_targetIndex, CFieldIOCPSocket *&o_pTargetSocket)
{
	CHARACTER *pTargetCharacter		= NULL;

	return CheckValidAttackTargetCharacter(i_pFMChann, i_targetIndex, o_pTargetSocket, pTargetCharacter);
}

BOOL CFieldIOCPSocket::CheckValidAttackTargetCharacter(CFieldMapChannel *i_pFMChann, ClientIndex_t i_targetIndex, CFieldIOCPSocket *&o_pTargetSocket, CHARACTER *&o_pTargetCharacter)
{
	o_pTargetSocket		= NULL;
	o_pTargetCharacter	= NULL;

	if (!IS_CHARACTER_CLIENT_INDEX(i_targetIndex))
	{
		return FALSE;
	}

	o_pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(i_targetIndex);

	// 피공격자의 IOCPSocket이 유효한지 체크
	if (NULL == o_pTargetSocket
		|| FALSE == o_pTargetSocket->IsValidCharacter()
		|| TRUE == COMPARE_BODYCON_BIT(o_pTargetSocket->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
		|| NULL == i_pFMChann
		|| i_pFMChann != o_pTargetSocket->GetCurrentFieldMapChannel())		// 2007-07-02 by cmkwon, 같은맵 비교 수정
	{
		o_pTargetSocket		= NULL;
		return FALSE;
	}

	// 피공격자의 캐릭터가 유효한지 체크
	o_pTargetCharacter = &o_pTargetSocket->m_character;
	return TRUE;
}

BOOL CFieldIOCPSocket::CheckValidAttackTargetMonster(BYTE i_byAttackCharInfluenceTy, ClientIndex_t i_nTargetIndex, ChannelIndex_t i_nChannelIndex, CFieldMonster *&o_pTargetMonster)
{
	if (FALSE == IS_MONSTER_CLIENT_INDEX(i_nTargetIndex))
	{
		return FALSE;
	}

	if (m_PeerSocketType == ST_NPC_SERVER
		&& m_pFieldMapProjectForNPC)
	{
		// 몬스터가 유효한지 체크
		o_pTargetMonster = m_pFieldMapProjectForNPC->GetFieldMonsterW(i_nChannelIndex, i_nTargetIndex, 102);
	}
	else if (m_PeerSocketType == ST_CLIENT_TYPE
		&& m_pCurrentFieldMapChannel)
	{
		// 몬스터가 유효한지 체크
		o_pTargetMonster = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(i_nChannelIndex, i_nTargetIndex, 103);
	}
	else
	{
		return FALSE;
	}

	if(NULL == o_pTargetMonster
		|| FALSE == o_pTargetMonster->IsValidMonster())
	{
		o_pTargetMonster = NULL;
		return FALSE;
	}

	if(IS_SAME_CHARACTER_MONSTER_INFLUENCE(i_byAttackCharInfluenceTy , o_pTargetMonster->MonsterInfoPtr->Belligerence))
	{// 2006-11-20 by cmkwon, 세력전 몬스터면서 캐릭터와 몬스터가 세력임
		return FALSE;
	}
// 2006-11-20 by cmkwon, 위와 같이 수정함
//	if( (IS_VCN_INFLUENCE_TYPE(i_byAttackCharInfluenceTy) && BELL_INFLUENCE_VCN == o_pTargetMonster->MonsterInfoPtr->Belligerence)
//		|| (IS_ANI_INFLUENCE_TYPE(i_byAttackCharInfluenceTy) && BELL_INFLUENCE_ANI == o_pTargetMonster->MonsterInfoPtr->Belligerence) )
//	{// 2005-12-28 by cmkwon, 캐릭터와 몬스터가 세력이 같으면 공격 할 수 없다
//		o_pTargetMonster = NULL;
//		return FALSE;
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 
	if(BELL_INFINITY_DEFENSE_MONSTER == o_pTargetMonster->MonsterInfoPtr->Belligerence)
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 
/// \author		cmkwon
/// \date		2010-03-17 ~ 2010-03-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckValidM2M(CFieldMapChannel *i_pFMChann, ClientIndex_t i_AttackerIdx, CFieldMonster **o_ppAttackMon, ClientIndex_t i_TargetIdx, CFieldMonster **o_ppTargetMon)
{
	*o_ppAttackMon	= NULL;
	*o_ppTargetMon	= NULL;

	if (FALSE == IS_MONSTER_CLIENT_INDEX(i_AttackerIdx)
		|| FALSE == IS_MONSTER_CLIENT_INDEX(i_TargetIdx))
	{
		return FALSE;
	}

	if(NULL == i_pFMChann
		|| IS_CITY_MAP_INDEX(i_pFMChann->GetMapChannelIndex().MapIndex))
	{
		return FALSE;
	}

	CFieldMonster *pAttFMon	= i_pFMChann->GetFieldMonster(i_AttackerIdx, 200);
	CFieldMonster *pTarFMon	= i_pFMChann->GetFieldMonster(i_TargetIdx, 201);
	if(NULL == pAttFMon || NULL == pTarFMon
		|| FALSE == pAttFMon->IsValidMonster() || FALSE == pTarFMon->IsValidMonster())
	{
		return FALSE;
	}

	// 2010-03-17 by cmkwon, 현재는 BELL_INFINITY_ATTACK_MONSTER와 BELL_INFINITY_DEFENSE_MONSTER만 전투가 가능하다.
	if(FALSE == IS_WARABLE_M2M_BELL(pAttFMon->MonsterInfoPtr->Belligerence, pTarFMon->MonsterInfoPtr->Belligerence))
	{
		return FALSE;
	}

	*o_ppAttackMon	= pAttFMon;
	*o_ppTargetMon	= pTarFMon;
	return TRUE;
}

Err_t CFieldIOCPSocket::CheckItemRequirements(ITEM *i_pItemInfo)
{
	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 컬렉션 등록용 아이템은 유닛의 종류를 체크하지 않는다.
	if ( FALSE == i_pItemInfo->IsExistDesParam(DES_COLLECTION_ARMOR_INDEX) )
	{
		if ((i_pItemInfo->ReqUnitKind & m_character.UnitKind) == 0)	// 필요유닛종류
		{
			return ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED;
		}
	}
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 컬렉션 등록용 아이템은 유닛의 종류를 체크하지 않는다.

// 2010-05-19 by cmkwon, 인피2차 이후 킬마크 사용시 버그 수정 - 아래와 같이 수정
// 	if (COMPARE_RACE(i_pItemInfo->ReqRace, m_character.Race) == FALSE)	// 필요종족
// 	{
// 		return ERR_PROTOCOL_REQ_RACE_NOT_MATCHED;
// 	}
	// 2010-05-19 by cmkwon, 인피2차 이후 킬마크 사용시 버그 수정 - 킬마크 아이템은 ReqRace를 체크하지 않아야 한다.
	if(FALSE == COMPARE_BIT_FLAG(i_pItemInfo->ItemAttribute, ITEM_ATTR_KILL_MARK_ITEM))
	{
		if (COMPARE_RACE(i_pItemInfo->ReqRace, m_character.Race) == FALSE)	// 필요종족
		{
			return ERR_PROTOCOL_REQ_RACE_NOT_MATCHED;
		}
	}

	if (i_pItemInfo->ReqGearStat.AttackPart > m_character.TotalGearStat.AttackPart)
	{
		return ERR_PROTOCOL_REQ_ATTACK_PART_NOT_MATCHED;
	}
	if (i_pItemInfo->ReqGearStat.DefensePart > m_character.TotalGearStat.DefensePart)
	{
		return ERR_PROTOCOL_REQ_DEFENSE_PART_NOT_MATCHED;
	}
	if (i_pItemInfo->ReqGearStat.FuelPart > m_character.TotalGearStat.FuelPart)
	{
		return ERR_PROTOCOL_REQ_FUEL_PART_NOT_MATCHED;
	}
	if (i_pItemInfo->ReqGearStat.SoulPart > m_character.TotalGearStat.SoulPart)
	{
		return ERR_PROTOCOL_REQ_SOUL_PART_NOT_MATCHED;
	}
	if (i_pItemInfo->ReqGearStat.ShieldPart > m_character.TotalGearStat.ShieldPart)
	{
		return ERR_PROTOCOL_REQ_SHIELD_PART_NOT_MATCHED;
	}
	if (i_pItemInfo->ReqGearStat.DodgePart > m_character.TotalGearStat.DodgePart)
	{
		return ERR_PROTOCOL_REQ_DODGE_PART_NOT_MATCHED;
	}

	return ERR_NO_ERROR;
}

Err_t CFieldIOCPSocket::CheckGeneralItemRequirements(ITEM_GENERAL *i_pGItem)
{
	int nReqMinLevel = 0;
	int nReqMaxLevel = 0;
	
	ms_pFieldIOCP->GetReqLevelApplyRare(&nReqMinLevel, &nReqMaxLevel, i_pGItem);

	//////////////////////////////////////////////////////////////////////////
	// 2008-10-01 by dhjin, 신규 인첸트
	if(ITEMKIND_SUPPORT == i_pGItem->Kind)
	{
		mt_auto_lock mtA(&m_mapEnchant);		// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
		mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(i_pGItem->UniqueNumber);
		if (m_mapEnchant.end() != itrEnchantList)
		{
			vectENCHANT &vecECH = itrEnchantList->second;
			for (int i = 0; i < vecECH.size(); i++)
			{
				ITEM *pEnchantItem = ms_pFieldIOCP->GetItemInfo(vecECH[i].EnchantItemNum);
				if (pEnchantItem != NULL)
				{
					// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
					//if(DES_REQ_MIN_LEVEL == pEnchantItem->DestParameter1)
					//{
					//	nReqMinLevel += pEnchantItem->ParameterValue1;
					//}
					if(DES_REQ_MIN_LEVEL == pEnchantItem->ArrDestParameter[0])
					{
						nReqMinLevel += pEnchantItem->ArrParameterValue[0];
					}
				}
			}
		}
	}

	if (0 != nReqMinLevel 
		&& nReqMinLevel > m_character.Level)	// 최소 필요 레벨
	{
		return ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED;
	}

	if (0 != nReqMaxLevel 
		&& nReqMaxLevel < m_character.Level)	// 최대 필요 레벨
	{
		return ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED;
	}

	return CheckItemRequirements(i_pGItem->ItemInfo);
}

Err_t CFieldIOCPSocket::CheckSkillItemRequirements(ITEM *i_pSItemInfo)
{
	if (0 != i_pSItemInfo->ReqMinLevel 
		&& i_pSItemInfo->ReqMinLevel > m_character.Level)	// 필요레벨
	{
		return ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED;
	}

	if (0 != i_pSItemInfo->ReqMaxLevel 
		&& i_pSItemInfo->ReqMaxLevel < m_character.Level)	// 필요레벨
	{
		return ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED;
	}

	return CheckItemRequirements(i_pSItemInfo);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckSpeedHack(DWORD i_dwClientTickGap, float i_fServerDistaceGap)
/// \brief		
/// \author		cmkwon
/// \date		2004-11-01 ~ 2004-11-01
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckSpeedHack(DWORD i_dwClientTickGap, float i_fServerDistaceGap)
{
	m_arrSpeedHackCheck[0].nRecvMoveCounts++;
	m_arrSpeedHackCheck[0].nSumClientTimeGap		+= i_dwClientTickGap;
	m_arrSpeedHackCheck[0].nSumServerDistanceGap	+= (int)i_fServerDistaceGap;
	
	DWORD dwCurTick = timeGetTime();
	m_arrSpeedHackCheck[0].nServerTimeGap = dwCurTick - m_dwLastTickSpeedHackCheck;
	if(m_arrSpeedHackCheck[0].nServerTimeGap > CHARACTER_SPEED_HACK_CHECK_TERM)
	{
		float fTemp = max(1.0f, (float)m_arrSpeedHackCheck[0].nSumClientTimeGap/1000.0f);
		m_arrSpeedHackCheck[0].nCurrentSpeed
			= (int)( (float)m_arrSpeedHackCheck[0].nSumServerDistanceGap/fTemp );

		if(m_arrSpeedHackCheck[0].nRecvMoveCounts > (m_arrSpeedHackCheck[0].nServerTimeGap*5)/1000 + 10)
		{
			this->WriteLogMessageSpeedHack(SPEEDHACK_CHECK_TYPE_BY_SERVER);
		}

		for(int i = ARRAYSIZE_SPEED_HACK_DATA-2; i >= 0; i--)
		{
			m_arrSpeedHackCheck[i+1] = m_arrSpeedHackCheck[i];
		}
		m_arrSpeedHackCheck[0].ResetSPEED_HACK_DATA();
		
		m_dwLastTickSpeedHackCheck	= dwCurTick;
	}
}

BOOL CFieldIOCPSocket::WriteLogMessageSpeedHack(BYTE i_bCheckType)
{
	int nCheckedCounts = 0;
	int nTotalMoveCounts = 0;
	for(int i = ARRAYSIZE_SPEED_HACK_DATA-1; i >= 0; i-- )
	{
		if(m_arrSpeedHackCheck[i].nServerTimeGap > CHARACTER_SPEED_HACK_CHECK_TERM)
		{
			nCheckedCounts++;
			nTotalMoveCounts += m_arrSpeedHackCheck[i].nRecvMoveCounts;
		}
	}

	if(nTotalMoveCounts < nCheckedCounts*50 + 10)
	{
		return FALSE;
	}
		
	for(i = ARRAYSIZE_SPEED_HACK_DATA-1; i >= 0; i-- )
	{
		if(0 != m_arrSpeedHackCheck[i].nServerTimeGap)
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2004-11-12, cmkwon, Speed Hack 사용자, DB에 저장 해야함
			// AccountName, CharacterName, MapChannelIndex
			// CheckType, ReceivedMoveCounts,
			// 엔진ItemNum, ServerPastTime, ClientPastTime, PastDistance, CurrentSpeed, 현재 시간(초단위)
			CAtumLogSender::SendLogMessageSpeedHack(this, i_bCheckType, m_arrSpeedHackCheck[i].nRecvMoveCounts
				, ((m_ItemRear.ItemNum == 0)?0 : ((ITEM_BASE*)m_ItemRear.ItemNum)->ItemInfo->ItemNum)
				, m_arrSpeedHackCheck[i].nServerTimeGap, m_arrSpeedHackCheck[i].nSumClientTimeGap
				, m_arrSpeedHackCheck[i].nSumServerDistanceGap, m_arrSpeedHackCheck[i].nCurrentSpeed);
			
			char szSystem[1024];
			sprintf(szSystem, "	SpeedHack User by Server ==> AccountName(%10s) CharacterName(%10s) MapChannelIndex(%s) RecvMoveCounts(%5d) ServerPastTime(%4d), ClientPastTime(%4d), PastDistance(%6d) CurrentSpeed(%d)\r\n"
				, m_character.AccountName
				, m_character.CharacterName
				, GET_MAP_STRING(m_character.MapChannelIndex)
				, m_arrSpeedHackCheck[i].nRecvMoveCounts
				, m_arrSpeedHackCheck[i].nServerTimeGap
				, m_arrSpeedHackCheck[i].nSumClientTimeGap
				, m_arrSpeedHackCheck[i].nSumServerDistanceGap
				, m_arrSpeedHackCheck[i].nCurrentSpeed);
// 			DBGOUT(szSystem);
			g_pFieldGlobal->WriteSystemLog(szSystem);
		}
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckMemoryHackWeapon(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK *i_pRealInfo)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckMemoryHackWeapon(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK *i_pRealInfo)
{
	if(NULL == i_pItemGen
		|| FALSE == IS_WEAPON(i_pItemGen->Kind))
	{
		return;
	}

	if(IS_PRIMARY_WEAPON(i_pItemGen->Kind))
	{
		CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_SHOTNUM, CAtumSJ::GetTotalPrimaryShotNumPerReattackTime(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->ShotNum0);
		CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_MULTINUM, 1, i_pRealInfo->MultiNum0);
	}
	else
	{
		CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_SHOTNUM, CAtumSJ::GetTotalSecondaryShotNumPerReattackTime(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->ShotNum0);
		CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_MULTINUM, CAtumSJ::GetSecondaryMultiNumCount(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->MultiNum0);
	}
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_REATTACKTIME, CAtumSJ::GetShotCountReattackTime(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->ReattackTime0);

	// 2008-05-29 by cmkwon, (버그 수정)탄두 인챈트 아이템 메모리핵 걸리는 버그 수정(G0010300) - 아래와 같이 수정
	//CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_REPEATTIME, i_pItemGen->ItemInfo->RepeatTime, i_pRealInfo->RepeatTime0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_REPEATTIME, CAtumSJ::GetWarHeadSpeed(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->RepeatTime0);	// 2008-05-29 by cmkwon, (버그 수정)탄두 인챈트 아이템 메모리핵 걸리는 버그 수정(G0010300) - CAtumSJ::GetWarHeadSpeed() 로 체크

	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_TIME, CAtumSJ::GetOverheatTime(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->Time0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_RANGEANGLE, CAtumSJ::GetAttackRangeAngle(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->RangeAngle0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_BOOSTERANGLE, i_pItemGen->ItemInfo->BoosterAngle, i_pRealInfo->BoosterAngle0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_ORBITTYPE, i_pItemGen->ItemInfo->OrbitType, i_pRealInfo->OrbitType0);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckMemoryHackEngine(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK *i_pRealInfo)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckMemoryHackEngine(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK *i_pRealInfo)
{
	if(NULL == i_pItemGen
		|| ITEMKIND_SUPPORT != i_pItemGen->Kind)
	{
		return;
	}

	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_ABILITYMIN, i_pItemGen->ItemInfo->AbilityMin, i_pRealInfo->AbilityMin0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_ABILITYMAX, i_pItemGen->ItemInfo->AbilityMax, i_pRealInfo->AbilityMax0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_SPEEDPENALTY, CAtumSJ::GetCircularAngle(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->SpeedPenalty0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_TIME, i_pItemGen->ItemInfo->Time, i_pRealInfo->Time0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_RANGE, (float)i_pItemGen->ItemInfo->Range, i_pRealInfo->Range0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_RANGEANGLE, CAtumSJ::GetEngineRangeAngle(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->RangeAngle0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_BOOSTERANGLE, CAtumSJ::GetEngineBoosterRangeAngle(i_pItemGen->ItemInfo, &m_ParamFactor), i_pRealInfo->BoosterAngle0);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CheckMemoryHackTotalWeight(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK *i_pRealInfo)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CheckMemoryHackTotalWeight(ITEM_GENERAL *i_pItemGen, MSG_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK *i_pRealInfo)
{
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_TRANSPORT, CAtumSJ::GetTransport(&m_character), i_pRealInfo->Transport0);
	CheckMemoryHackByMemoryHackCheckTy(i_pItemGen, HACK_CHECK_TYPE_TOTALWEIGHT, m_ItemManager.GetCurrentCarryingItemWeight(), i_pRealInfo->TotalWeight0);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckMemoryHackByMemoryHackCheckTy(ITEM_GENERAL *i_pItemGen, int i_nMemoryHackCheckTy, float i_fValidValue, float i_fCurrentValue, int i_nParam1/*=0*/)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckMemoryHackByMemoryHackCheckTy(ITEM_GENERAL *i_pItemGen, int i_nMemoryHackCheckTy
														  , float i_fValidValue, float i_fCurrentValue, int i_nParam1/*=0*/)
{
#ifdef S_AUTO_BLOCK_REATTACKETIME_EXCEPT_JHSEOL
	if(HACK_CHECK_TYPE_REATTACKTIME == i_nMemoryHackCheckTy) return TRUE;	// 2013-07-29 by jhseol, japan Memory Hack Auto Block ReAttackeTime tamp bug adjust
#endif
	int		nValidValue		= fastf2i(100.0f*i_fValidValue);		// 2008-06-26 by cmkwon, float -> int 형변환 함수 추가 - 
	int		nCurValue		= fastf2i(100.0f*i_fCurrentValue);		// 2008-06-26 by cmkwon, float -> int 형변환 함수 추가 - 
	int		nThValue		= 5;	// 2010-11-12 by khkim 메모리핵:4 탄두속도 오류

	switch(i_nMemoryHackCheckTy)
	{
	case HACK_CHECK_TYPE_TOTALWEIGHT:
	case HACK_CHECK_TYPE_TRANSPORT:
	case HACK_CHECK_TYPE_POSITION:
	case HACK_CHECK_TYPE_REPEATTIME:	// 2008-06-26 by cmkwon, (버그 수정)탄두 인챈트 아이템 메모리핵 걸리는 버그 추가 수정(G0010300) - HACK_CHECK_TYPE_REPEATTIME 체크도 실제값으로 해야 한다.
		{
			nValidValue		= (int)(i_fValidValue);
			nCurValue		= (int)(i_fCurrentValue);
			break;
		}
	default:
		break;
	}

	// 2012-11-12 start by khkim 메모리핵:4 탄두속도 오류
	switch(i_nMemoryHackCheckTy)
	{
	case HACK_CHECK_TYPE_REPEATTIME:
		{
			nThValue = 350;			// 임시방편임
			break;
		}							
	default:
		break;
	}
	// End 2012-11-12 by khkim 메모리핵 탄두속도

	if(nValidValue == nCurValue)
	{
		m_MemoryHackHistory.InsertResult(i_nMemoryHackCheckTy, i_pItemGen->Kind, FALSE);		// 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현

		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 절대값을 구해서 차이가 5이상일때 메모리핵 사용
	if(nValidValue > nCurValue)
	{
		if(labs(nValidValue - nCurValue) < nThValue) // 2010-11-12 by khkim 메모리핵:4 탄두속도 오류
		{
			m_MemoryHackHistory.InsertResult(i_nMemoryHackCheckTy, i_pItemGen->Kind, FALSE);		// 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현

			return FALSE;
		}
	}
	else
	{
		if(labs(nCurValue - nValidValue) < nThValue) // 2010-11-12 by khkim 메모리핵:4 탄두속도 오류
		{
			m_MemoryHackHistory.InsertResult(i_nMemoryHackCheckTy, i_pItemGen->Kind, FALSE);		// 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현

			return FALSE;
		}
	}

	int nItemKind	= i_pItemGen->Kind;
	int nItemNum	= i_pItemGen->ItemNum;
	int nItemUID	= i_pItemGen->UniqueNumber;

	if(IS_PRIMARY_WEAPON(i_pItemGen->Kind))
	{
		nItemKind	= ITEMKIND_PRIMARY_WEAPON_ALL;
	}
	else if(IS_SECONDARY_WEAPON(i_pItemGen->Kind))
	{
		nItemKind	= ITEMKIND_SECONDARY_WEAPON_ALL;
	}
		
	CAtumLogSender::SendLogMessageMemoryHack(this, nItemKind, nItemNum, nItemUID, i_nMemoryHackCheckTy, i_fValidValue, i_fCurrentValue, i_nParam1);

	// 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현
#ifdef S_AUTO_BLOCK_SYSTEM_HSKIM
	m_MemoryHackHistory.InsertResult(i_nMemoryHackCheckTy, i_pItemGen->Kind, TRUE);
	if( TRUE == m_MemoryHackHistory.IsBlock(i_nMemoryHackCheckTy, i_pItemGen->Kind) )
	{
		if( FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
		{
			SBLOCKED_ACCOUNT_INFO blockedAccInfo;
			MEMSET_ZERO(&blockedAccInfo, sizeof(SBLOCKED_ACCOUNT_INFO));

			blockedAccInfo.AdminFieldServerClientIndex	= GetCharacter()->ClientIndex;
			sprintf(blockedAccInfo.szBlockedAccountName, "%s", m_character.AccountName);
			sprintf(blockedAccInfo.szBlockAdminAccountName, "AutoBlockSystem");
			blockedAccInfo.enBlockedType = T_BLOCKEDACCOUNT_MEMORYHACK_AUTOBLOCK;
			blockedAccInfo.atimeStartTime.SetCurrentDateTime();
			
#if defined(TEST140) || defined(WIKIGAMES_ENG)		// 2013-05-22 by bckim, 캐나다 영구블럭 정책에 따르는 기간변경 +(2000년 + 하루)
			blockedAccInfo.atimeEndTime.SetDateTime(blockedAccInfo.atimeStartTime.Year + 2000, blockedAccInfo.atimeStartTime.Month, blockedAccInfo.atimeStartTime.Day+1, 1, 1, 1);
#else
			blockedAccInfo.atimeEndTime.SetDateTime(2200, 1, 1, 1, 1, 1); //AddDateTime(0, 0, 72000);		// 데충 200년				//blockedAccInfo.atimeEndTime	= blockedAccInfo.atimeStartTime;
#endif			
			sprintf(blockedAccInfo.szBlockedReasonForUser, "Blocked");
			sprintf(blockedAccInfo.szBlockedReasonForOnlyAdmin, "MemHack : HACK_CHECK_TYPE(%d)", i_nMemoryHackCheckTy);

			INIT_MSG_WITH_BUFFER(MSG_FP_ADMIN_BLOCKACCOUNT, T_FP_ADMIN_BLOCKACCOUNT, pBlockAcc, SendBuf);
			pBlockAcc->blockAccInfo	= blockedAccInfo;
			ms_pFieldIOCP->Send2PreServerW(SendBuf, MSG_SIZE(MSG_FP_ADMIN_BLOCKACCOUNT));
		}		
	}
#endif
	// end 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현

	return TRUE;
}



void CFieldIOCPSocket::InsertAttackTargetIndexVector(ClientIndex_t i_Index)
{
	if(FALSE == IS_MONSTER_CLIENT_INDEX(i_Index))
	{// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
		return;
	}

	mt_auto_lock mtAuto(&m_mtvectAttackTargetMonsterIndex);
	
	if(i_Index == GetLastMonsterIndexAttack2Me())
	{// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
		return;
	}

	vectorClientIndex::iterator it = find(m_mtvectAttackTargetMonsterIndex.begin(), m_mtvectAttackTargetMonsterIndex.end(), i_Index);
	if(it == m_mtvectAttackTargetMonsterIndex.end())
	{
		if(m_mtvectAttackTargetMonsterIndex.size() >= 20)
		{// 타겟 인덱스는 최대 20개만 유지한다

			m_mtvectAttackTargetMonsterIndex.erase(m_mtvectAttackTargetMonsterIndex.begin());
		}
		m_mtvectAttackTargetMonsterIndex.push_back(i_Index);		
	}	
	SetLastMonsterIndexAttack2Me(i_Index);

// 2009-12-10 by cmkwon, TEMP 
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 091210 %s inserted MonsterIndex(%d) ListCnt(%d) AttckMonIdx(%d) TargetMonIdx(%d)\r\n"
//		, GetCharacterString(GetCharacter(), string()), i_Index, m_mtvectAttackTargetMonsterIndex.size(), GetLastMonsterIndexAttack2Me(), m_nTargetMonsterIndex);
}


void CFieldIOCPSocket::DeleteAttackTargetIndexVector(ClientIndex_t i_Index)
{
	mt_auto_lock mtAuto(&m_mtvectAttackTargetMonsterIndex);
	vectorClientIndex::iterator it = find(m_mtvectAttackTargetMonsterIndex.begin(), m_mtvectAttackTargetMonsterIndex.end(), i_Index);
	if(it != m_mtvectAttackTargetMonsterIndex.end())
	{
		m_mtvectAttackTargetMonsterIndex.erase(it);
	}

	// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	if(i_Index == GetLastMonsterIndexAttack2Me())
	{
		SetLastMonsterIndexAttack2Me(0);
	}
	if(i_Index == GetTargetMonsterIndex())
	{
		SetTargetMonsterIndex(0);
	}

// 2009-12-10 by cmkwon, TEMP 
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 091210 %s deleted MonsterIndex(%d) ListCnt(%d) AttckMonIdx(%d) TargetMonIdx(%d)\r\n"
//		, GetCharacterString(GetCharacter(), string()), i_Index, m_mtvectAttackTargetMonsterIndex.size(), GetLastMonsterIndexAttack2Me(), m_nTargetMonsterIndex);
}


struct For_Each_DeleteMe_From_MonsterAttackedList
{
	For_Each_DeleteMe_From_MonsterAttackedList(ClientIndex_t nDelIdx, CFieldMapChannel *pFieldMapChannel):m_nDelIndex(nDelIdx), m_pFieldMapChannel(pFieldMapChannel){};
	void operator()(ClientIndex_t &index)
	{
		CFieldMonster *pMon = m_pFieldMapChannel->GetFieldMonster(index, 9);
		if(pMon)
		{
			pMon->DeleteAttackedInfowithIndex(m_nDelIndex);			
		}
	}
	CFieldMapChannel	*m_pFieldMapChannel;
	ClientIndex_t		m_nDelIndex;
};

void CFieldIOCPSocket::DeleteMeFromMonsterAttackedList(void)
{
	if(NULL == m_pCurrentFieldMapChannel){				return;}

	mt_auto_lock mtAuto(&m_mtvectAttackTargetMonsterIndex);
// 2009-12-10 by cmkwon, TEMP 
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 091210 %s clear MonsterTargetList ListCnt(%d) AttckMonIdx(%d) TargetMonIdx(%d)\r\n"
//		, GetCharacterString(GetCharacter(), string()), m_mtvectAttackTargetMonsterIndex.size(), GetLastMonsterIndexAttack2Me(), m_nTargetMonsterIndex);

	if(m_mtvectAttackTargetMonsterIndex.empty())
	{
		return;
	}
	mtvectClientIndex_t		tempMtvect;
	tempMtvect.reserve(m_mtvectAttackTargetMonsterIndex.size());
	tempMtvect.insert(tempMtvect.begin()
		, m_mtvectAttackTargetMonsterIndex.begin(), m_mtvectAttackTargetMonsterIndex.end());
	m_mtvectAttackTargetMonsterIndex.clear();
	SetLastMonsterIndexAttack2Me(0);		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	SetTargetMonsterIndex(0);				// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	mtAuto.auto_unlock_cancel();

	for_each(tempMtvect.begin(), tempMtvect.end()
		, For_Each_DeleteMe_From_MonsterAttackedList(m_character.ClientIndex, m_pCurrentFieldMapChannel));
	
}

BOOL CFieldIOCPSocket::SendAddDataBuffer(GBUFFER_SIZE_MAX_PACKET &i_gbuffer, EN_PACKET_PRIORITY i_enPacketPriority)
{
	return CIOCPSocket::SendAddData(i_gbuffer.GetPtr(), i_gbuffer.GetSize(), i_enPacketPriority);
}

BOOL CFieldIOCPSocket::IsTrivialMessageType(MessageType_t msgType)
{
	if (T0_FC_STRING			== HIBYTE(msgType) ||
		T0_FC_MOVE				== HIBYTE(msgType) ||
//		T0_FC_BATTLE			== HIBYTE(msgType) ||
		T0_FC_CHARACTER			== HIBYTE(msgType) ||
		T0_FC_ADMIN				== HIBYTE(msgType) ||
		T_FC_MONSTER_MOVE_OK	== msgType ||
		IS_ALIVE_MSG(msgType)
	)
	{
		return TRUE;
	}

	return FALSE;
}

#ifdef _DEBUG
// check: EVENT 관련 MSG 못 보내는 등의 문제 있음! 좋은 방법 찾아야 함.
// check: SendInRangeXXX() 등에서 casting 없이 CIOCPSocket::SendAddData()를 바로 호출하는 경우는 안 갈 수 있다. 20040831, kelovon.
BOOL CFieldIOCPSocket::SendAddData(BYTE* pData, int nSize)
{
//	if (m_PeerSocketType == ST_CLIENT && COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
//	{
//		DBGOUT("SendAddData Failed: %s %d", GetCharacterString(&m_character, string()), m_PeerSocketType);
//		return FALSE;
//	}

	MessageType_t msgType = *(MessageType_t*)pData;

	if (m_PeerSocketType == ST_CLIENT_TYPE
		&& m_bSendMessgeTypeDBG
		&& !IsTrivialMessageType(msgType)
	)
	{
		SendString128(STRING_128_USER_NOTICE, "[F->C]%s", GetProtocolTypeString(msgType));
	}

	if (g_exchangeMsgPrintLevel != PRINTLEVEL_NO_MSG)
	{
		PrintExchangeMsg(SEND_TYPE, msgType, m_szPeerIP, m_PeerSocketType, GGetexchangeMsgPrintLevel());
	}

	return CIOCPSocket::SendAddData(pData, nSize);
}
#endif


void CFieldIOCPSocket::IncrementInsertingStoreCounts(void)
{
	this->m_dwLastTickInsertingStoreItem = timeGetTime();
	InterlockedIncrement(&this->m_nInsertingStoreItemCounts);
}

void CFieldIOCPSocket::DecrementInsertingStoreCounts(void)
{
	if(0 > InterlockedDecrement(&this->m_nInsertingStoreItemCounts))
	{
		this->m_nInsertingStoreItemCounts = 0;
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InfluenceWarCheckInvasion(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-28 ~ 2005-12-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfluenceWarCheckInvasion(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-01-10 by cmkwon - 전체맵으로 체크하던것을 각 맵별 체크로 수정함, 메시지 전송도 현재맵으로만 전송함


	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return;
	}

	// 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현
	if(COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER)
		|| COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_NORMAL))
	{// 2006-01-10 by cmkwon, 관리자, GM은 체크하지 않는다, // 2007-05-22 by cmkwon, 일반세력도 체크하지 않는다
		return;
	}

	int nMapInfl = GetCurrentFieldMapChannel()->GetMapInfluenceTypeW();
	// 2007-05-22 by cmkwon, 일반세력도시맵(아카데미맵) 구현
	if(MAP_INFLUENCE_NEUTRALITY == nMapInfl
		|| IS_MAP_INFLUENCE_EVENT_AREA(nMapInfl)		// 2007-05-22 by cmkwon, 이벤트맵도 체크하지 않는다
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::InfluenceWarCheckInvasion#, 
//		|| IS_SAME_CHARACTER_8_MAP_INFLUENCE(m_character.InfluenceType, nMapInfl))
		|| CAtumSJ::IsSameCharacterInfluence8MapInfluence(m_character.InfluenceType, nMapInfl))		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
	{// 중립영역 맵이거나 캐릭과 같은 세력맵이다.
		return;
	}

	DWORD		dwCurTick = timeGetTime();
	if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN))
	{// 바이제니유 세력이 다른 세력맵에서 이동중이다
		if(dwCurTick-pFMChann->m_dwLastTickANIInfluenceAttackedMsg <= TICKGAP_SEND_INVASION_MSG)
		{
			return;
		}
		pFMChann->m_dwLastTickANIInfluenceAttackedMsg = dwCurTick;
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INVASION, T_FC_WAR_NOTIFY_INVASION, pSInvasion, SendBuf);
		pSInvasion->MapChannelIndex0		= GetCurrentFieldMapChannel()->GetMapChannelIndex();
		pFMChann->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INVASION), INFLUENCE_TYPE_ANI);

		///////////////////////////////////////////////////////////////////////////////
		// 2006-12-08 by dhjin, 지도자, 부지도자에게 전송
		ms_pFieldIOCP->Send2LeaderANDSubLeader(INFLUENCE_TYPE_ANI, SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INVASION), pFMChann);
	}
	else if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_ANI))
	{// 알링턴 세력이 다른 세력맵에서 이동중이다.
		if(dwCurTick-pFMChann->m_dwLastTickVCNInfluenceAttackedMsg <= TICKGAP_SEND_INVASION_MSG)
		{
			return;
		}
		pFMChann->m_dwLastTickVCNInfluenceAttackedMsg = dwCurTick;
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INVASION, T_FC_WAR_NOTIFY_INVASION, pSInvasion, SendBuf);
		pSInvasion->MapChannelIndex0		= GetCurrentFieldMapChannel()->GetMapChannelIndex();
		pFMChann->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INVASION), INFLUENCE_TYPE_VCN);

		///////////////////////////////////////////////////////////////////////////////
		// 2006-12-08 by dhjin, 지도자, 부지도자에게 전송
		ms_pFieldIOCP->Send2LeaderANDSubLeader(INFLUENCE_TYPE_VCN, SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INVASION), pFMChann);
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InfluenceWarBonus2Killer(CFieldIOCPSocket *i_pFISockDeaded)
/// \brief		
/// \author		cmkwon
/// \date		2006-02-09 ~ 2006-02-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfluenceWarBonus2Killer(CFieldIOCPSocket *i_pFISockDeaded)
{
	const CHARACTER *pDeadedChar = i_pFISockDeaded->GetCharacter();

	///////////////////////////////////////////////////////////////////////////////	
	// 2006-02-09 by cmkwon, 킬마크 넣어 주기
	ITEM *pKillMarkItem = i_pFISockDeaded->GetGiveKillMarkItemPtr2Killer();
	if(pKillMarkItem)
	{
		BOOL bInserted = m_ItemManager.InsertItemBaseByItemNum(pKillMarkItem->ItemNum, 1, IUT_INFLUENCEWAR_KILLER_BONUS, TRUE);
		if(FALSE == bInserted)
		{
			// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVENTORY_FULL_ITEM, m_ItemManager.GetMaxInventoryCount(), m_ItemManager.GetInventoryItemCounts());
		}
	}

	// 2006-02-09 by cmkwon, 명성치 보너스
	this->AddCharacterFame();

	CHARACTER2ITEMLIST *pChar2ItemList = ms_pFieldIOCP->FindCharacter2Item(pDeadedChar->InfluenceType, pDeadedChar->UnitKind);
	if(NULL == pChar2ItemList)
	{
		return;
	}

	float fPlusDropItem		= i_pFISockDeaded->GetPlusRateDropItem() - 1.0f;
	for(int i=0; i < pChar2ItemList->vectCharacter2Item.size(); i++)
	{
		CHARACTER2ITEM *pChar2Item = &pChar2ItemList->vectCharacter2Item[i];
		ITEM	*pDropItem	= ms_pFieldIOCP->GetItemInfo(pChar2Item->ItemNumber);
		if (pDropItem == NULL
			|| FALSE == COMPARE_BIT_FLAG(pDropItem->ItemAttribute, ITEM_ATTR_QUEST_ITEM)
			|| FALSE == COMPARE_BIT_FLAG(pDropItem->ItemAttribute, ITEM_ATTR_KILL_MARK_ITEM)
			|| 0 >= pChar2Item->QuestIndex)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] Character DropItem Error1, Influence(%2d) UnitKind(%8d) ItemNum(%8d) QuestIndex(%4d)\r\n"
				, pDeadedChar->InfluenceType, pDeadedChar->UnitKind, pChar2Item->ItemNumber, pChar2Item->QuestIndex);
			continue;
		}

		if(FALSE == IS_IN_RANGE(pDropItem->ReqMinLevel, pDeadedChar->Level, pDropItem->ReqMaxLevel))
		{
			continue;
		}
	
		mt_auto_lock mtA(&this->m_mapQuest);
		CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();
		if(NULL == pFCharQuest
			|| pChar2Item->QuestIndex != pFCharQuest->QuestIndex)
		{// 2006-03-02 by cmkwon, 진행중 퀘스트가 없거나 퀘스트가 다르면
			continue;
		}

		int pValue = RAND1000K();
		if (pChar2Item->Probability < pValue - (Prob1000K_t)(pChar2Item->Probability*fPlusDropItem))
		{// 생성 실패
			continue;
		}
	
		if(pChar2Item->MinCount < 0
			|| pChar2Item->MaxCount < 0
			|| pChar2Item->MaxCount < pChar2Item->MinCount)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] Character DropItem Error2, Influence(%2d) UnitKind(%8d) ItemNum(%8d) MinCount(%4d) MaxCount(%8d)\r\n"
				, pDeadedChar->InfluenceType, pDeadedChar->UnitKind, pChar2Item->ItemNumber, pChar2Item->MinCount, pChar2Item->MaxCount);
			continue;
		}

		INT nAmount = RANDI(pChar2Item->MinCount, pChar2Item->MaxCount);
		if(0 >= nAmount)
		{
			continue;
		}
		BOOL bInserted = m_ItemManager.InsertItemBaseByItemNum(pDropItem->ItemNum, nAmount, IUT_INFLUENCEWAR_KILLER_BONUS, TRUE);
		if(FALSE == bInserted)
		{
			// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVENTORY_FULL_ITEM, m_ItemManager.GetMaxInventoryCount(), m_ItemManager.GetInventoryItemCounts());
			break;
		}
	}
}


// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
/////////////////////////////////////////////////////////////////////////////////
///// \fn			Err_t CFieldIOCPSocket::SecurityCheckVersion(MSG_FC_MOVE_HACKSHIELD_GuidAckMsg *i_pGuidAckMsg/*=NULL*/)
///// \brief		
///// \author		cmkwon
///// \date		2006-06-05 ~ 2006-06-05
///// \warning	
/////
///// \param		
///// \return		
/////////////////////////////////////////////////////////////////////////////////
//Err_t CFieldIOCPSocket::SecurityCheckVersion(MSG_FC_MOVE_HACKSHIELD_GuidAckMsg *i_pGuidAckMsg/*=NULL*/)
//{
// 	if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
// 	{// 2006-06-05 by cmkwon
// 		return ERR_NO_ERROR;
// 	}
// 
// 	switch(g_pFieldGlobal->GetLanguageType())
// 	{
// 	case LANGUAGE_TYPE_KOREAN:
// 	case LANGUAGE_TYPE_VIETNAMESE:
// // 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
// //	case LANGUAGE_TYPE_ENGLISH:				// 2006-07-04 by cmkwon
// 	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정
// 		{
// 			if(NULL == i_pGuidAckMsg)
// 			{
// 				if(FALSE == m_Security_bCheckVersion)
// 				{
// 					INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_HACKSHIELD_GuidReqMsg, T_FC_MOVE_HACKSHIELD_GuidReqMsg, pSGuidReq, SendBuf);
// 					DWORD dwRet = _AntiCpSvr_MakeGuidReqMsg(pSGuidReq->pbyGuidReqMsg, m_Security_pbyGuidReqInfo);
// 					if(ERROR_SUCCESS != dwRet)
// 					{
// 						char szSysLog[1024];
// 						wsprintf(szSysLog, "[Error] CFieldIOCPSocket::SecurityCheckVersion_ _AntiCpSvr_MakeGuidReqMsg() error(0x%X)\r\n", dwRet);
// 						g_pFieldGlobal->WriteSystemLog(szSysLog);
// 						DbgOut(szSysLog);
// 						return ERR_NO_ERROR;
// 					}
// 
// // 2008-03-25 by cmkwon, 테스트용 로그
// // 					char szTmReqMsg[1024];
// // 					char szTmReqInfo[1024];
// // 					XOR::XORBinary2String(szTmReqMsg, pSGuidReq->pbyGuidReqMsg, SIZEOF_GUIDREQMSG);
// // 					XOR::XORBinary2String(szTmReqInfo, m_Security_pbyGuidReqInfo, SIZEOF_GUIDREQINFO);
// // 					g_pFieldGlobal->WriteSystemLogEX(TRUE, "CFieldIOCPSocket::SecurityCheckVersion_ Req   %s, %s\r\n", szTmReqMsg, szTmReqInfo);
// 
// 					SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_HACKSHIELD_GuidReqMsg));
// 					return ERR_SECURITY_NOT_CHECK_VERSION;
// 				}
// 			}
// 			else
// 			{
// 
// // 2008-03-25 by cmkwon, 테스트용 로그
// // 				char szTmReqMsg[1024];
// // 				char szTmReqInfo[1024];
// // 				XOR::XORBinary2String(szTmReqMsg, i_pGuidAckMsg->pbyGuidAckMsg, SIZEOF_GUIDACKMSG);
// // 				XOR::XORBinary2String(szTmReqInfo, m_Security_pbyGuidReqInfo, SIZEOF_GUIDREQINFO);
// // 				g_pFieldGlobal->WriteSystemLogEX(TRUE, "CFieldIOCPSocket::SecurityCheckVersion_ Recvd %s, %s\r\n", szTmReqMsg, szTmReqInfo);
// 
// 				// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 아래와 같이 인자 수정됨
// 				//DWORD dwRet = _AntiCpSvr_AnalyzeGuidAckMsg(i_pGuidAckMsg->pbyGuidAckMsg, m_Security_pbyGuidReqInfo, &m_Security_plCRCInfo);
// 				DWORD dwRet = _AntiCpSvr_AnalyzeGuidAckMsg(i_pGuidAckMsg->pbyGuidAckMsg, m_Security_pbyGuidReqInfo, &m_Security_ClientContext);
// 				if(ERROR_SUCCESS != dwRet)
// 				{
// 					char szSysLog[1024];
// 					wsprintf(szSysLog, "[Error] CFieldIOCPSocket::SecurityCheckVersion_ _AntiCpSvr_AnalyzeGuidAckMsg() error(0x%X)\r\n", dwRet);
// 					g_pFieldGlobal->WriteSystemLog(szSysLog);
// 					DbgOut(szSysLog);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_GUID);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_GuidReqMsg, ERR_SECURITY_HACKING_GUID, 0, 0, NULL, TRUE); 
// 					this->Close(0, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 
// 				m_Security_bCheckVersion	= TRUE;
// 			}
// 		}
// 		break;
// 	default:
// 		{
// 			return ERR_NO_ERROR;
// 		}
// 	}
//
//	return ERR_NO_ERROR;
//}
//
/////////////////////////////////////////////////////////////////////////////////
///// \fn			Err_t CFieldIOCPSocket::SecurityCheckClient_1(MSG_FC_MOVE_HACKSHIELD_CRCAckMsg *i_pCRCAckMsg/*=NULL*/)
///// \brief		
///// \author		cmkwon
///// \date		2006-06-05 ~ 2006-06-05
///// \warning	
/////
///// \param		
///// \return		
/////////////////////////////////////////////////////////////////////////////////
//Err_t CFieldIOCPSocket::SecurityCheckClient_1(MSG_FC_MOVE_HACKSHIELD_CRCAckMsg *i_pCRCAckMsg/*=NULL*/)
//{
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
// 	if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
// 	{// 2006-06-05 by cmkwon
// 		return ERR_NO_ERROR;
// 	}
// 
// 	if(FALSE == m_Security_bCheckVersion)
// 	{// 2006-06-05 by cmkwon, 초기화 안됨
// 		return ERR_NO_ERROR;
// 	}
// 
// 	switch(g_pFieldGlobal->GetLanguageType())
// 	{
// 	case LANGUAGE_TYPE_KOREAN:
// 	case LANGUAGE_TYPE_VIETNAMESE:
// // 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
// //	case LANGUAGE_TYPE_ENGLISH:				// 2006-07-04 by cmkwon
// 	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정
// 		{
// 
// 			if(NULL == i_pCRCAckMsg)
// 			{
// 				if(m_Security_bSendCRCReqMsg)
// 				{// 2006-06-08 by cmkwon, 이전에 보낸 메시지 응답을 받지 못한 상태이다
// 					char szSysLog[1024];
// 					DWORD dwCur = timeGetTime();
// 					wsprintf(szSysLog, "[Error] CFieldIOCPSocket::SecurityCheckClient_1_ TermTick(%d) = CurrentTick(%d) - BeforeTick(%d)\r\n"
// 						, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
// 					g_pFieldGlobal->WriteSystemLog(szSysLog);
// 					DbgOut(szSysLog);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// 					this->Close(0, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 
// 				INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_HACKSHIELD_CRCReqMsg, T_FC_MOVE_HACKSHIELD_CRCReqMsg, pSCRCReq, SendBuf);
// 				// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 아래와 같이 인자 수정됨
// 				//DWORD dwRet = _AntiCpSvr_MakeReqMsg(m_Security_plCRCInfo, pSCRCReq->pbyReqMsg, m_Security_pbyReqInfo, m_Security_ulOption);
// 				DWORD dwRet = _AntiCpSvr_MakeReqMsg(&m_Security_ClientContext, pSCRCReq->pbyReqMsg, m_Security_pbyReqInfo, m_Security_ulOption);
// 				if(ERROR_SUCCESS != dwRet)
// 				{
// 					char szSysLog[1024];
// 					wsprintf(szSysLog, "[Error] CFieldIOCPSocket::SecurityCheckClient_1_ _AntiCpSvr_MakeReqMsg() error(0x%X)\r\n", dwRet);
// 					g_pFieldGlobal->WriteSystemLog(szSysLog);
// 					DbgOut(szSysLog);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// 					this->Close(0, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 				SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_HACKSHIELD_CRCReqMsg));
// 
// 				m_Security_bSendCRCReqMsg			= TRUE;							// 2006-06-08 by cmkwon
// 				m_Security_ulOption					= ANTICPSVR_CHECK_GAME_MEMORY;	// 2006-06-05 by cmkwon, 한번 실행 후 변경
// 				m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();				// 2006-10-21 by cmkwon, 추가
// 				return ERR_SECURITY_NOT_CHECK_VERSION;
// 			}
// 			else
// 			{
// 				// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 아래와 같이 인자 수정됨
// 				//DWORD dwRet = _AntiCpSvr_AnalyzeAckMsg(m_Security_plCRCInfo, i_pCRCAckMsg->pbyAckMsg, m_Security_pbyReqInfo);
// 				DWORD dwRet = _AntiCpSvr_AnalyzeAckMsg(&m_Security_ClientContext, i_pCRCAckMsg->pbyAckMsg, m_Security_pbyReqInfo);
// 				if(ERROR_SUCCESS != dwRet)
// 				{
// 					char szSysLog[1024];
// 					wsprintf(szSysLog, "[Error] CFieldIOCPSocket::SecurityCheckClient_1_ _AntiCpSvr_AnalyzeAckMsg() error(0x%X)\r\n", dwRet);
// 					g_pFieldGlobal->WriteSystemLog(szSysLog);
// 					DbgOut(szSysLog);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// 					this->Close(0, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 				m_Security_bSendCRCReqMsg		= FALSE;				// 2006-06-08 by cmkwon
// 			}
// 		}
// 		break;
// 	default:
// 		{
// 			return ERR_NO_ERROR;
// 		}
// 	}
//
//	return ERR_NO_ERROR;
//}

///////////////////////////////////////////////////////////////////////////////
// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
BOOL CFieldIOCPSocket::ms_bUsingSecuritySystem					= FALSE;


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
/// \author		cmkwon
/// \date		2009-11-05 ~ 2009-11-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetInitSecurityClient(void)
{
	return m_bInitSecurityClient;
}

// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 
AHNHS_SERVER_HANDLE	CFieldIOCPSocket::ms_hAhnHSServerHandle		= ANTICPX_INVALID_HANDLE_VALUE;
IXigncodeServer* CFieldIOCPSocket::m_XignCodeServer				= NULL;// 2012-10-13 by jhahn Xigncode 한국 적용

int CFieldIOCPSocket::ms_nPeriodMinutesforSecurityCheck			= 1;		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 기본은 1분마다 체크

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SecurityServerInit(void)
/// \brief		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - CFieldIOCPSocket::SecurityServerInit() 추가
/// \author		cmkwon
/// \date		2008-04-03 ~ 2008-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SecurityServerInit(void)
{
// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 범용으로 체크하기 위해서 아래와 같이 함수로 변경
// 	if(ANTICPX_INVALID_HANDLE_VALUE != ms_hAhnHSServerHandle)
// 	{
// 		return FALSE;
// 	}

	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - ArenaServer는 게임 가드를 사용하지 않게 처리
	if(g_pFieldGlobal->IsArenaServer())
	{
		return TRUE;
	}

	if(FALSE != CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# SecuritySystem initialize error !! IsInitFlag(%d) \r\n", CFieldIOCPSocket::IsInitializedSecurityServer());
		return FALSE;
	}

	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 서버 초기화

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_KOREAN:
		{
// 2009-05-27 by jhahn Xigncode 한국 적용			
			// 2012-10-17 by bhsohn XignCode작업
#if defined(YEDANG_KOR)
			if(CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return FALSE;
			}			
			CFieldIOCPSocket::ms_bUsingXignCode = FALSE; 
			// END 2012-10-17 by bhsohn XignCode작업
			
 			CreateXigncodeServer XingCode = LoadHelperDll(SECURITY_XIGNCODE_DIRECTORY_PATH);
			
			if(!XingCode)
			{				
				DBGOUT("XignCode Init error \n");
				return FALSE;	// 2012-10-17 by bhsohn XignCode작업
			}
			
			if(!XingCode(&CFieldIOCPSocket::m_XignCodeServer, XignCodeSendProc, XignCodeVerifyProc))
 			{ 			
 				DBGOUT("XingCode CreateXigncodeServerW \n");
				return FALSE; // 2012-10-17 by bhsohn XignCode작업
 			} 			
 		
 			
			if(!CFieldIOCPSocket::m_XignCodeServer->OnBegin(XC_PACKET_SIZE) )
			{
				DBGOUT("XingCode Begin Error[%d] \n", GetLastError());
				return FALSE; // 2012-10-17 by bhsohn XignCode작업
			}

			CFieldIOCPSocket::ms_bUsingXignCode = TRUE;  // 2012-10-17 by bhsohn XignCode작업			
			DBGOUT("CFieldIOCPSocket::SecurityServerInit [%d] \r\n", 
					CFieldIOCPSocket::ms_bUsingXignCode);
#endif
		}
		break;
//end 2012-10-13 by jhahn Xigncode 한국 적용

// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
//	case LANGUAGE_TYPE_VIETNAMESE:
// 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
//	case LANGUAGE_TYPE_ENGLISH:			// 2006-07-04 by cmkwon

// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 
//	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정

// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
//	case LANGUAGE_TYPE_THAI:				// 2008-07-14 by cmkwon, WinnerOnline_Tha 에 핵쉴드 적용

// 2008-10-14 by cmkwon, 영국 Gameforge4D(영어, 독어) 모두 핵쉴드 적용 - 아래와 같이 수정함.
// #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-09-19 by cmkwon, 캐나다 Wikigames_Eng 핵쉴드 적용하기 - 핵쉴드 서버 초기화에 추가
// 	case LANGUAGE_TYPE_ENGLISH:
// #endif // END - #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-16 by cmkwon, 영국 Gameforge4D 모두 언어 핵쉴드 적용 - 
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 

// 2008-11-24 by dhjin, 대만 핵쉴드 제거 - 
//	case LANGUAGE_TYPE_TAIWANESE:		// 2008-11-14 by cmkwon, 대만 Netpower_Tpe 에 핵쉴드 적용 - 
		{
// #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 핵쉴드는 여기에서 체크
// 			if(ANTICPX_INVALID_HANDLE_VALUE != ms_hAhnHSServerHandle)
// 			{
// 				return FALSE;
// 			}
// 
// 			char szFullPathOfhsbFile[1024];
// 			char szCurDir[1024];
// 			GetCurrentDirectory(1024, szCurDir);
// 			wsprintf(szFullPathOfhsbFile, "%s\\%s\\%s", szCurDir, SECURITY_HACKSHIELD_DIRECTORY_PATH, "AntiCpx.hsb");			
// 			ms_hAhnHSServerHandle = _AhnHS_CreateServerObject(szFullPathOfhsbFile);
// 			if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 			{
// 				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityInit_ excute _AhnHS_CreateServerObject() error !! FullPath(%s)\r\n", szFullPathOfhsbFile);
// 				return FALSE;
// 			}
// #endif // END - #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
#if defined(_DEFINED_GAMEFORGE4D_)
			if(CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return FALSE;
			}

			if(g_pFieldGlobal->IsArenaServer())
			{
				return TRUE;
			}
			
			UINT32 uiRet = InitCSAuth3((char*)(SECURITY_NPROTECT_DIRECTORY_PATH));
			if(uiRet != ERROR_SUCCESS)
			{
				char szCurDir[MAX_PATH];
				GetCurrentDirectory(MAX_PATH, szCurDir);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# excute InitCSAuth3() error !! Path(%s), CurDir(%s), Error(%d)\r\n", SECURITY_NPROTECT_DIRECTORY_PATH, szCurDir, uiRet);
				return FALSE;
			}
			CFieldIOCPSocket::ms_nPeriodMinutesforSecurityCheck		= 3;	// 2009-03-10 by cmkwon, nProtect는 3분마다 1번씩 체크
			CFieldIOCPSocket::ms_bUsingNProtect						= TRUE;
#endif
		}
		break;

	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:			// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 서버 모듈 초기화
		{
#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
			if(CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return FALSE;
			}

			if(g_pFieldGlobal->IsArenaServer())
			{// 2008-12-18 by cmkwon, 대만 Netpower 아레나 서버 XignCode 관련 버그 수정 - 아레나 서버에서는 XignCode를 사용하지 않는다.
				return TRUE;
			}

			// 2009-05-27 by cmkwon, Xigncode SDK 2.0으로 업그레이드 - 이 함수를 ZSWAVE_Initialize() 전에 처리 해야함.
			if(FALSE == ZSWAVE_Link(SECURITY_XIGNCODE_DIRECTORY_PATH))
			{
				char szCurDir[MAX_PATH];
				GetCurrentDirectory(MAX_PATH, szCurDir);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit_ excute ZXWAVE_Link() error !! Path(%s), CurDir(%s), GetLastError(%d)\r\n", SECURITY_XIGNCODE_DIRECTORY_PATH, szCurDir, GetLastError());
				return FALSE;
			}

			CFieldIOCPSocket::ms_bUsingXignCode = ZSWAVE_Initialize(SECURITY_XIGNCODE_DIRECTORY_PATH);
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				char szCurDir[MAX_PATH];
				GetCurrentDirectory(MAX_PATH, szCurDir);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit_ excute ZSWAVE_Initialize() error !! Path(%s), CurDir(%s), GetLastError(%d)\r\n", SECURITY_XIGNCODE_DIRECTORY_PATH, szCurDir, GetLastError());
				return FALSE;
			}

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
		}
		break;
	case LANGUAGE_TYPE_JAPANESE:
		{
#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
			///////////////////////////////////////////////////////////////////////////////
			// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - CFieldIOCPSocket::SecurityServerInit()에서 모듈 로딩
			if(CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return FALSE;
			}

			if(g_pFieldGlobal->IsArenaServer())
			{// 2009-03-18 by cmkwon, 일본 Arario nProtect 관련 수정 - 아레나 서버에서는 CS인증을 사용하지 않는다.
				return TRUE;
			}

			if(MAX_PACKET_SIZE_FOR_NPROTECT < sizeof(GG_AUTH_DATA))
			{// 2009-03-09 by cmkwon, 프로토콜 구조체 사이즈 체크
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# struct size error !! MaxPacketSize for nProtect(%d) < sizeof(GG_AUTH_DATA)(%d) \r\n", MAX_PACKET_SIZE_FOR_NPROTECT, sizeof(GG_AUTH_DATA));
				return FALSE;
			}

			UINT32 uiRet = InitGameguardAuth((char*)(SECURITY_NPROTECT_DIRECTORY_PATH), 50, true, 0x03);
			if(uiRet != ERROR_SUCCESS)
			{
				char szCurDir[MAX_PATH];
				GetCurrentDirectory(MAX_PATH, szCurDir);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# excute InitGameguardAuth() error !! Path(%s), CurDir(%s), Error(%d)\r\n", SECURITY_NPROTECT_DIRECTORY_PATH, szCurDir, uiRet);
				return FALSE;
			}
			SetUpdateCondition(30, 50);		// 2009-03-09 by cmkwon, CS인증 버젼 업데이트 조건 설정(30분, 50%)
			CFieldIOCPSocket::ms_nPeriodMinutesforSecurityCheck		= 3;	// 2009-03-10 by cmkwon, nProtect는 3분마다 1번씩 체크
			CFieldIOCPSocket::ms_bUsingNProtect						= TRUE;
#endif
		}
		break;
	}

#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1) || defined(SC_XTRAP_VTC_GAMEGUARD_BHSOHN_JHSEOL)	// 2013-10-09 by jhseol, X-Trap + VTC 게임가드		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - CFieldIOCPSocket::SecurityServerInit# 처리
		char szPrefixFilename[MAX_PATH];
		STRNCPY_MEMSET(szPrefixFilename, CLIENT_EXEUTE_FILE_NAME, min(MAX_PATH, strlen(CLIENT_EXEUTE_FILE_NAME)-3));	
		if(FALSE == CFieldIOCPSocket::XTrapLoadMapFile(SECURITY_XTRAP_DIRECTORY_PATH, szPrefixFilename))
		{
			char szCurDir[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, szCurDir);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# load map error !! Dir(%s), PrefixFileName(%s), CurDir(%s)\r\n", SECURITY_XTRAP_DIRECTORY_PATH, szPrefixFilename, szCurDir);
			return FALSE;
		}
		DWORD dwRet = XTrap_S_LoadDll();
		if(0 != dwRet)
		{
			char szCurDir[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, szCurDir);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# XTrap_S_LoadDll error !! CurDir(%s), dwRet(%d) \r\n", szCurDir, dwRet);
			return FALSE;
		}
		dwRet = XTrap_S_Start(600, XTRAP_CSFILE_NUM, ms_XTrapMap, NULL);
		if(0 != dwRet && 7 != dwRet )	// 2013-12-19 by jhseol, 리턴 7 예외 추가 : 7은 메뉴얼 상에서 정상으로 분류된다고 함.
		{
			char szCurDir[MAX_PATH];
			GetCurrentDirectory(MAX_PATH, szCurDir);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityInit# XTrap_S_Start error !! CurDir(%s), dwRet(%d) \r\n", szCurDir, dwRet);
			return FALSE;
		}
		CFieldIOCPSocket::ms_XTrapUsingFlag		= TRUE;

	}	
#endif // END - #if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1)


#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerInit#
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerInit#, 
		CHSStart(CFieldIOCPSocket::SecurityApexSendData, ms_pfRec4Apex);
		CHSSetFunc((void*)(CFieldIOCPSocket::SecurityApexKillUser), FLAG_KILLUSER);

// 2009-11-04 by cmkwon, 임시용
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityInit# ms_pfRec4Apex(0x%X) \r\n", ms_pfRec4Apex);
	}
#endif

	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
	CFieldIOCPSocket::ms_bUsingSecuritySystem		= TRUE;		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerInit#, 보안시스템서버 준비 
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SecurityServerClean(void)
/// \brief		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - CFieldIOCPSocket::SecurityServerClean() 추가
/// \author		cmkwon
/// \date		2008-04-03 ~ 2008-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SecurityServerClean(void)
{
// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 범용으로 체크하기 위해서 아래와 같이 함수로 변경
// 	if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 	{
// 		return;
// 	}
	if(FALSE == CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
	CFieldIOCPSocket::ms_bUsingSecuritySystem		= FALSE;	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerClean#, 보완시스템 서버 초기화


	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 서버 종료

	switch(g_pFieldGlobal->GetLanguageType())
	{
	// 2012-10-17 by bhsohn XignCode작업
case LANGUAGE_TYPE_KOREAN:
		{
#if defined(YEDANG_KOR)
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return;
			}
		
			CFieldIOCPSocket::ms_bUsingXignCode		= FALSE;

			//싸인코드 종료
			if(CFieldIOCPSocket::m_XignCodeServer)
			{
				CFieldIOCPSocket::m_XignCodeServer->OnEnd();
				CFieldIOCPSocket::m_XignCodeServer->Release();
			}
			DBGOUT("CFieldIOCPSocket::SecurityServerClean [%d] \r\n", 
					CFieldIOCPSocket::ms_bUsingXignCode);
#endif
		}
		break;
		// END 2012-10-17 by bhsohn XignCode작업
// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
//	case LANGUAGE_TYPE_VIETNAMESE:
// 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
//	case LANGUAGE_TYPE_ENGLISH:			// 2006-07-04 by cmkwon

// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 
//	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정

// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
//	case LANGUAGE_TYPE_THAI:				// 2008-07-14 by cmkwon, WinnerOnline_Tha 에 핵쉴드 적용

// 2008-10-14 by cmkwon, 영국 Gameforge4D(영어, 독어) 모두 핵쉴드 적용 - 아래와 같이 수정
// #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-09-19 by cmkwon, 캐나다 Wikigames_Eng 핵쉴드 적용하기 - 핵쉴드 서버 종료 처리에 추가
// 	case LANGUAGE_TYPE_ENGLISH:
// #endif // END - #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-16 by cmkwon, 영국 Gameforge4D 모두 언어 핵쉴드 적용 - 
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 

// 2008-11-24 by dhjin, 대만 핵쉴드 제거 - 
//	case LANGUAGE_TYPE_TAIWANESE:		// 2008-11-14 by cmkwon, 대만 Netpower_Tpe 에 핵쉴드 적용 - 
		{
// #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 			if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 			{
// 				return;
// 			}
// 
// 			_AhnHS_CloseServerHandle(ms_hAhnHSServerHandle);
// 			ms_hAhnHSServerHandle	= ANTICPX_INVALID_HANDLE_VALUE;
// #endif // END - #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
#if defined(_DEFINED_GAMEFORGE4D_)
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return;
			}

			CloseCSAuth3();
			
			CFieldIOCPSocket::ms_bUsingNProtect		= FALSE;
#endif
		}
		break;

	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:			// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 서버 모듈 종료
		{
#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return;
			}

			ZSWAVE_Uninitialize();
			CFieldIOCPSocket::ms_bUsingXignCode		= FALSE;

			// 2009-05-27 by cmkwon, Xigncode SDK 2.0으로 업그레이드 - ZSWAVE_Uninitialize() 이후에 처리 해야함.
			ZSWAVE_UnLink();

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
		}
		break;
	case LANGUAGE_TYPE_JAPANESE:
		{
#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
			///////////////////////////////////////////////////////////////////////////////
			// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - CFieldIOCPSocket::SecurityServerClean()에서 모듈을 내린다.
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return;
			}

			CleanupGameguardAuth();

			CFieldIOCPSocket::ms_bUsingNProtect		= FALSE;
#endif
		}
		break;
	}

#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1) || defined(SC_XTRAP_VTC_GAMEGUARD_BHSOHN_JHSEOL)	// 2013-10-09 by jhseol, X-Trap + VTC 게임가드		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경
	{		
		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - CFieldIOCPSocket::SecurityServerClean# 처리
		if(FALSE == CFieldIOCPSocket::ms_XTrapUsingFlag)
		{
			return;
		}

		CFieldIOCPSocket::ms_XTrapUsingFlag		= FALSE;

		XTrap_S_FreeDll();

		MEMSET_ZERO(ms_XTrapMap, XTRAP_CS4_BUFSIZE_MAP);
	}
#endif // END - #if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1)


#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerClean#
	{
// 2009-11-04 by cmkwon, 임시용
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityServerClean# pRec4Apex(0x%X) \r\n", ms_pfRec4Apex);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityServerClean#
		ms_pfRec4Apex		= NULL;
		CHSEnd();
	}
#endif

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::SecurityClientInit(void)
/// \brief		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - CFieldIOCPSocket::SecurityClientInit() 추가
/// \author		cmkwon
/// \date		2008-04-04 ~ 2008-04-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::SecurityClientInit(void)
{
// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 범용으로 체크하기 위해서 아래와 같이 함수로 변경
// 	if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 	{
// 		return ERR_NO_ERROR;		// 2008-04-25 by cmkwon, 버그 수정
// 	}
	if(FALSE == CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		return ERR_NO_ERROR;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
	if(this->GetInitSecurityClient())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "\r\n[Error] CFieldIOCPSocket::SecurityClientInit# SecurityClient initialize error !! %s IsInitSecurityClient(%d) \r\n", GetCharacterString(GetCharacter(), string()), this->GetInitSecurityClient());
		return ERR_NO_ERROR;
	}


// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 핵쉴드 전용이므로 아래로 이동 시킴
// 	if(ANTICPX_INVALID_HANDLE_VALUE != m_hAhnHSClientHandle)
// 	{
// 		return ERR_SECURITY_ANTICPX_INVALID_HANDLE;
// 	}
// 
// 	if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
// 	{// 2006-06-05 by cmkwon
// 		return ERR_NO_ERROR;
// 	}

	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 클라이언트 초기화

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_KOREAN:
		{
			// 2012-10-17 by bhsohn XignCode작업
#if defined(YEDANG_KOR)
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return ERR_NO_ERROR;
			}			
			// 2012-10-17 by bhsohn XignCode작업
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "CFieldIOCPSocket::SecurityClientInit m_bXignCodeClient[%d] CharacterUniqueNumber[%d] \r\n", 
					m_bXignCodeClient, this->m_character.CharacterUniqueNumber);
			DBGOUT("CFieldIOCPSocket::SecurityClientInit m_bXignCodeClient[%d] CharacterUniqueNumber[%d] \r\n", 
					m_bXignCodeClient, this->m_character.CharacterUniqueNumber);
			if(!m_bXignCodeClient)
			{
				CFieldIOCPSocket::m_XignCodeServer->OnAccept((xpvoid)this->m_character.CharacterUniqueNumber, NULL);			
				m_bXignCodeClient = TRUE;
			}
#endif
			// END 2012-10-17 by bhsohn XignCode작업

			// 2009-05-27 by jhahn Xigncode 한국 적용
		}//end 2009-05-27 by jhahn Xigncode 한국 적용
		break;
// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
//	case LANGUAGE_TYPE_VIETNAMESE:
// 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
//	case LANGUAGE_TYPE_ENGLISH:			// 2006-07-04 by cmkwon

// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 
//	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정

// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
//	case LANGUAGE_TYPE_THAI:				// 2008-07-14 by cmkwon, WinnerOnline_Tha 에 핵쉴드 적용

// 2008-10-14 by cmkwon, 영국 Gameforge4D(영어, 독어) 모두 핵쉴드 적용 - 아래왁 같이 수정
// #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-09-19 by cmkwon, 캐나다 Wikigames_Eng 핵쉴드 적용하기 - 클라이언트 초기화 처리에 추가
// 	case LANGUAGE_TYPE_ENGLISH:
// #endif // END - #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-16 by cmkwon, 영국 Gameforge4D 모두 언어 핵쉴드 적용 - 
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 

// 2008-11-24 by dhjin, 대만 핵쉴드 제거 - 
//	case LANGUAGE_TYPE_TAIWANESE:		// 2008-11-14 by cmkwon, 대만 Netpower_Tpe 에 핵쉴드 적용 - 
		{
// #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 아래와 같이 핵쉴드 관련 체크를 여기에서 한다.
// 			if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 			{
// 				return ERR_NO_ERROR;		// 2008-04-25 by cmkwon, 버그 수정
// 			}
// 			if(ANTICPX_INVALID_HANDLE_VALUE != m_hAhnHSClientHandle)
// 			{
// 				return ERR_SECURITY_ANTICPX_INVALID_HANDLE;
// 			}			
// 			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
// 			{// 2006-06-05 by cmkwon
// 				return ERR_NO_ERROR;
// 			}
// 
// #if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_KOREAN_SERVER_2)
// 			///////////////////////////////////////////////////////////////////////////////
// 			// 2010-01-12 by cmkwon, 실행파일 비교 제외(테스트를 위해) - 핵쉴드 서버인증 제외
// 			if(0 == strnicmp("cmkwon", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)			// 마상 권철민
// 				|| 0 == strnicmp("kjp81", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)		// 마상 박건주
// 				|| 0 == strnicmp("jwyoon", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)		// 마상 윤제원
// 				|| 0 == strnicmp("aiuy", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)		// YD
// 				|| 0 == strnicmp("minioo", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)		// YD
// 				|| 0 == strnicmp("rnsghkd", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)		// YD
// 				|| 0 == strnicmp("kclup0621", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME)	// YD
// 				|| 0 == strnicmp("rebanto", m_character.AccountName, SIZE_MAX_ACCOUNT_NAME))	// YD
// 			{
// 				return ERR_NO_ERROR;
// 			}
// #endif // END - #if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_KOREAN_SERVER_2)
// 
// 			m_hAhnHSClientHandle = _AhnHS_CreateClientObject(ms_hAhnHSServerHandle);
// 			if(ANTICPX_INVALID_HANDLE_VALUE == m_hAhnHSClientHandle)
// 			{
// 				return ERR_SECURITY_CREATE_CLIENT_FAIL;
// 			}
// #endif // END - #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
#if defined(_DEFINED_GAMEFORGE4D_)
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return ERR_NO_ERROR;
			}			
			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
			{
				return ERR_NO_ERROR;
			}
			m_csAuth3forNProtect.Init(TRUE);
			
			this->SecurityClientCheck_GFNP(NULL, FALSE);
#endif
		}
		break;

	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:			// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 클라이언트를 위한 모듈 초기화
		{
#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return ERR_NO_ERROR;
			}

			if(m_bXignCodeReceivedReqScanInitOK)
			{// 2008-11-28 by cmkwon, 인증을 거친 상태이므로 정상 처리
				return ERR_NO_ERROR;
			}

			if(m_hXignCodeAntiCheatHandle)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SecurityClientInit# error !!, %s XignCodeHandle(%d)\r\n"
					, GetCharacterString(this->GetCharacter(), string()), m_hXignCodeAntiCheatHandle);
				return ERR_SECURITY_ANTICPX_INVALID_HANDLE;
			}

			HANDLE hAntiCheat = ZSWAVE_Open(MAX_PACKET_SIZE_FOR_XIGNCODE, Z_SCAN_TYPE_ANTI_CHEAT_ENGINE);
			if(NULL == hAntiCheat)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SecurityClientInit# ZSWAVE_Open() error !!, %s GetLastError(%d)\r\n"
					, GetCharacterString(this->GetCharacter(), string()), GetLastError());
				return ERR_SECURITY_CREATE_CLIENT_FAIL;
			}

			INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_INIT, T_FC_MOVE_XIGNCODE_REQ_SCAN_INIT, pScanInit, SendBuf);
			pScanInit->byDataCount = ZSWAVE_GetDataCount(hAntiCheat);
			for(int i=0; i < pScanInit->byDataCount; i++)
			{
				ZSWAVE_GetDataAt(hAntiCheat, i, (char*)pScanInit->byCheckData);

				pScanInit->byCurDataIndex	= i;
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_INIT));
			}
			m_hXignCodeAntiCheatHandle			= hAntiCheat;

			return ERR_SECURITY_NOT_CHECK_VERSION;	// 2008-11-28 by cmkwon, 에러를 리턴한다.

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
		}
		break;
	case LANGUAGE_TYPE_JAPANESE:
		{
#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
			///////////////////////////////////////////////////////////////////////////////
			// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 클라이언트별로 초기화
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return ERR_NO_ERROR;
			}
			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
			{// 2009-03-11 by cmkwon, 관리자는 CS인증을 제외한다.
				return ERR_NO_ERROR;
			}

			m_csAuth2forNProtect.Init();

			// 2009-03-09 by cmkwon, 첫번째 인증 요청을 전송한다.
			this->SecurityClientCheck(NULL, FALSE);
#endif
		}
		break;
	}

#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1) || defined(SC_XTRAP_VTC_GAMEGUARD_BHSOHN_JHSEOL)	// 2013-10-09 by jhseol, X-Trap + VTC 게임가드		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - CFieldIOCPSocket::SecurityClientInit# 처리
		if(FALSE == CFieldIOCPSocket::ms_XTrapUsingFlag)
		{
			return ERR_NO_ERROR;
		}
		if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
		{// 2009-10-08 by cmkwon, 관리자는 CS인증을 제외한다.
			return ERR_NO_ERROR;
		}

		DWORD dwRet = XTrap_S_SessionInit(600, XTRAP_CSFILE_NUM, ms_XTrapMap, m_XTrapSessionBuf);
		if(0 != dwRet)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SecurityClientInit# XTrap_S_SessionInit() error !!, %s dwRet(%ld)\r\n"
				, GetCharacterString(this->GetCharacter(), string()), dwRet);
			return ERR_SECURITY_CREATE_CLIENT_FAIL;
		}

		this->SecurityClientCheck(NULL, FALSE);
	}
#endif // END - #if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1)


#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientInit#
	{
//		// 2009-11-04 by cmkwon, 임시용
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityClientInit# %s pRec4Apex(0x%X) \r\n", GetCharacterString(this->GetCharacter(), string()), ms_pfRec4Apex);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientInit#
		if(ms_pfRec4Apex)
		{
			ms_pfRec4Apex('L', GetCharacter()->ClientIndex, GetCharacter()->CharacterName, strlen(GetCharacter()->CharacterName));

			char szBuf[5]		= {0};
			szBuf[0]			= SECURITY_APEX_ClientIpFlag;
			*(int*)(&szBuf[1])	= this->GetPeerIP4();
			ms_pfRec4Apex('S', GetCharacter()->ClientIndex, (const char*)szBuf, 5);
		}
	}
#endif

	m_dwReadyTickforSecurityCheck		= timeGetTime();		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 클라이언트 체크 준비 Tick 설정
	m_bInitSecurityClient				= TRUE;					// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientInit#
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SecurityClientClean(void)
/// \brief		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - CFieldIOCPSocket::SecurityClientClean() 추가
/// \author		cmkwon
/// \date		2008-04-04 ~ 2008-04-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SecurityClientClean(void)
{
// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 범용으로 체크하기 위해서 아래와 같이 함수로 변경
// 	if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 	{
// 		return;
// 	}
	if(FALSE == CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientClean#, 체크
	if(FALSE == this->GetInitSecurityClient())
	{
		return;
	}
	m_bInitSecurityClient			= FALSE;	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientClean#, 초기화 

// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 핵쉴드 관련 아래로 이동함
// 	if(ANTICPX_INVALID_HANDLE_VALUE == m_hAhnHSClientHandle)
// 	{
// 		return;
// 	}

	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 클라이언트 종료

	switch(g_pFieldGlobal->GetLanguageType())
	{
	// 2012-10-17 by bhsohn XignCode작업
	case LANGUAGE_TYPE_KOREAN:
		{
#if defined(YEDANG_KOR)
			if(FALSE == CFieldIOCPSocket::ms_bUsingXignCode)
			{
				return;
			}			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "CFieldIOCPSocket::SecurityClientClean m_bXignCodeClient[%d] CharacterUniqueNumber[%d] \r\n", 
					m_bXignCodeClient, this->m_character.CharacterUniqueNumber);

			DBGOUT("CFieldIOCPSocket::SecurityClientClean m_bXignCodeClient[%d] CharacterUniqueNumber[%d] \r\n", 
					m_bXignCodeClient, this->m_character.CharacterUniqueNumber);
			if(m_bXignCodeClient)
			{
				CFieldIOCPSocket::m_XignCodeServer->OnDisconnect((xpvoid)this->m_character.CharacterUniqueNumber);			
				m_bXignCodeClient = FALSE;
			}
#endif
		}
		break;
		// END 2012-10-17 by bhsohn XignCode작업
	case LANGUAGE_TYPE_VIETNAMESE:
	case LANGUAGE_TYPE_ARGENTINA:	// 2010-11-01 by shcho, Lin 아르헨티나 서비스 시작 준비 - 베트남과 동일
// 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
//	case LANGUAGE_TYPE_ENGLISH:			// 2006-07-04 by cmkwon

// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 
//	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정

// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
//	case LANGUAGE_TYPE_THAI:				// 2008-07-14 by cmkwon, WinnerOnline_Tha 에 핵쉴드 적용

// 2008-10-14 by cmkwon, 영국 Gameforge4D(영어, 독어) 모두 핵쉴드 적용 - 아래와 같이 수정
// #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-09-19 by cmkwon, 캐나다 Wikigames_Eng 핵쉴드 적용하기 - 핵쉴드 클라이언트 종료 처리에 추가
// 	case LANGUAGE_TYPE_ENGLISH:
// #endif // END - #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-16 by cmkwon, 영국 Gameforge4D 모두 언어 핵쉴드 적용 - 
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 

// 2008-11-24 by dhjin, 대만 핵쉴드 제거 - 
//	case LANGUAGE_TYPE_TAIWANESE:		// 2008-11-14 by cmkwon, 대만 Netpower_Tpe 에 핵쉴드 적용 - 
		{
// #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 핵쉴드 관련은 여기에서 체크
// 			if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 			{
// 				return;
// 			}
// 			if(ANTICPX_INVALID_HANDLE_VALUE == m_hAhnHSClientHandle)
// 			{
// 				return;
// 			}
// 
// 			_AhnHS_CloseClientHandle(m_hAhnHSClientHandle);
// 			m_hAhnHSClientHandle	= ANTICPX_INVALID_HANDLE_VALUE;
// 			m_Security_bSendCRCReqMsg		= FALSE;							// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 여기에서 초기화
// #endif // END - #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
			// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
#if defined(_DEFINED_GAMEFORGE4D_)
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return;
			}
			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
			{// 2009-03-11 by cmkwon, 관리자는 CS인증을 제외한다.
				return;
			}

			m_csAuth3forNProtect.Close();
#endif
		}
		break;


	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:				// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 클라이언트를 위한 모듈 종료
		{
#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
			if(FALSE == ms_bUsingXignCode)
			{
				return;
			}

			if(m_hXignCodeAntiCheatHandle)
			{
				ZSWAVE_Close(m_hXignCodeAntiCheatHandle);
				m_hXignCodeAntiCheatHandle			= NULL;
			}
			
			// 2008-12-04 by cmkwon, 대만 XignCode 버그 수정 - 게임 실행 후 한번만 처리되도록 수정하기 위해 여기에서는 초기화 하면 안됨, 소켓 종료시에만 초기화 해야 함.
			//m_bXignCodeReceivedReqScanInitOK	= FALSE;

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
		}
		break;
	case LANGUAGE_TYPE_JAPANESE:
		{
#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
			///////////////////////////////////////////////////////////////////////////////
			// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 클라이언트별 종료처리
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return;
			}
			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
			{// 2009-03-11 by cmkwon, 관리자는 CS인증을 제외한다.
				return;
			}

			m_csAuth2forNProtect.Close();
#endif
		}
		break;
	}


#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientClean#
	{
//		// 2009-11-04 by cmkwon, 임시용
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityClientClean# %s pRec4Apex(0x%X) \r\n", GetCharacterString(this->GetCharacter(), string()), ms_pfRec4Apex);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientClean#
		if(ms_pfRec4Apex)
		{
			ms_pfRec4Apex('G', GetCharacter()->ClientIndex, GetCharacter()->CharacterName, strlen(GetCharacter()->CharacterName));
		}
	}
#endif

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::SecurityClientCheck(MSG_FC_MOVE_HACKSHIELD_CRCAckMsg *i_pCRCAckMsg/*=NULL*/)
/// \brief		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - CFieldIOCPSocket::SecurityClientCheck() 추가
///				// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 인자추가(, BOOL i_bCheckTerm=TRUE)
/// \author		cmkwon
/// \date		2008-04-04 ~ 2008-04-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::SecurityClientCheck(MSG_FC_MOVE_HACKSHIELD_CRCAckMsg *i_pCRCAckMsg/*=NULL*/, BOOL i_bCheckTerm/*=TRUE*/)
{
// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 범용으로 체크하기 위해서 아래와 같이 함수로 변경
// 	if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 	{
// 		return ERR_NO_ERROR;
// 	}
//
//	if(ANTICPX_INVALID_HANDLE_VALUE == m_hAhnHSClientHandle)
//	{
//		return ERR_NO_ERROR;
//	}

	if(FALSE == CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		return ERR_NO_ERROR;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientCheck#, 체크
	if(FALSE == this->GetInitSecurityClient())
	{
		return ERR_NO_ERROR;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - CFieldIOCPSocket::SecurityClientInit()이 처리된 후 경과 시간 체크
	if(NULL == i_pCRCAckMsg
		&& i_bCheckTerm)
	{
		int nTermTick = timeGetTime() - m_dwReadyTickforSecurityCheck;
		if(50000 > nTermTick)
		{// 2009-03-10 by cmkwon, 50초 경과 체크
			return ERR_NO_ERROR;
		}
	}

	// 2012-06-25 by hskim, 라이브 디버깅 환경 구축 
	if( 0 == strncmp(MASANG_LIVE_PC_IP, this->GetPeerIP(), SIZE_MAX_IPADDRESS) )
	{
		return ERR_NO_ERROR;
	}
	// end 2012-06-25 by hskim, 라이브 디버깅 환경 구축 

	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 일정 시간 마다 체크

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_KOREAN:
		{// 2012-10-13 by jhahn Xigncode 한국 적용

		}//end 2012-10-13 by jhahn Xigncode 한국 적용
		break;
// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
//	case LANGUAGE_TYPE_VIETNAMESE:
// 2007-12-28 by cmkwon, 영어는 핵쉴드 제외
//	case LANGUAGE_TYPE_ENGLISH:			// 2006-07-04 by cmkwon
	
// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 
//	case LANGUAGE_TYPE_CHINESE:				// 2007-11-23 by cmkwon, 중국 핵쉴드 버그 수정

// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
//	case LANGUAGE_TYPE_THAI:				// 2008-07-14 by cmkwon, WinnerOnline_Tha 에 핵쉴드 적용

// 2008-10-14 by cmkwon, 영국 Gameforge4D(영어, 독어) 모두 핵쉴드 적용 - 아래와 같이 수정
// #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-09-19 by cmkwon, 캐나다 Wikigames_Eng 핵쉴드 적용하기 - 핵쉴드 일정 시간 마다 체크 처리에 추가
// 	case LANGUAGE_TYPE_ENGLISH:
// #endif // END - #if defined(SERVICE_TYPE_ENGLISH_SERVER_1)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-16 by cmkwon, 영국 Gameforge4D 모두 언어 핵쉴드 적용 - 
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 

// 2008-11-24 by dhjin, 대만 핵쉴드 제거 - 
//	case LANGUAGE_TYPE_TAIWANESE:		// 2008-11-14 by cmkwon, 대만 Netpower_Tpe 에 핵쉴드 적용 - 
		{
// #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
// 			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 핵쉴드 체크
// 			if(ANTICPX_INVALID_HANDLE_VALUE == ms_hAhnHSServerHandle)
// 			{
// 				return ERR_NO_ERROR;
// 			}
// 			if(ANTICPX_INVALID_HANDLE_VALUE == m_hAhnHSClientHandle)
// 			{
// 				return ERR_NO_ERROR;
// 			}
// 
// 			if(NULL == i_pCRCAckMsg)
// 			{
// 				// 2008-04-04 by cmkwon, 클라이언트로 요청 메시지 보낸다.
// 
// 				if(m_Security_bSendCRCReqMsg)
// 				{// 2006-06-08 by cmkwon, 이전에 보낸 메시지 응답을 받지 못한 상태이다
// 					DWORD dwCur = timeGetTime();
// 					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ TermTick(%d) = CurrentTick(%d) - BeforeTick(%d)\r\n"
// 						, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// 					this->Close(0x1406A, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 
// 
// 				INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_HACKSHIELD_CRCReqMsg, T_FC_MOVE_HACKSHIELD_CRCReqMsg, pSCRCReq, SendBuf);
// 				ULONG ulRet = _AhnHS_MakeRequest(m_hAhnHSClientHandle, &(pSCRCReq->stRequestBuf));
// 				if(ERROR_SUCCESS != ulRet)
// 				{
// 					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ _AhnHS_MakeRequest() error !!(0x%X)\r\n", ulRet);
// 
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// 					this->Close(0x1406B, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 				SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_HACKSHIELD_CRCReqMsg));
// 
// 				m_Security_bSendCRCReqMsg			= TRUE;							// 2006-06-08 by cmkwon
// 				m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();				// 2006-10-21 by cmkwon, 추가
// 			}
// 			else
// 			{
// 				// 2008-04-04 by cmkwon, 응답 받은 메시지 유효성 체크한다.
// 
// // 2009-03-13 by cmkwon, 핵쉴드 647버전 업데이트 - 아래와 같이 _AhnHS_VerifyResponseEx()로 변경
// //				ULONG ulRet = _AhnHS_VerifyResponse(m_hAhnHSClientHandle, i_pCRCAckMsg->stResponseBuf.byBuffer, i_pCRCAckMsg->stResponseBuf.nLength);
// //				if(ERROR_SUCCESS != ulRet)
// //				{
// //					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ _AhnHS_VerifyResponse() error !!(0x%X)\r\n", ulRet);
// //					
// //					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// //					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
// //					this->Close(0, FALSE, 3000);
// //					return ERR_NO_ERROR;
// //				}
// 				// 2009-03-13 by cmkwon, 핵쉴드 647버전 업데이트 - 아래와 같이 _AhnHS_VerifyResponseEx()로 변경
// 				ULONG ulErrCode = 0;
// 				ULONG ulRet = _AhnHS_VerifyResponseEx(m_hAhnHSClientHandle, i_pCRCAckMsg->stResponseBuf.byBuffer, i_pCRCAckMsg->stResponseBuf.nLength, &ulErrCode);
// 				if(ANTICPX_RECOMMAND_KEEP_SESSION != ulRet)
// 				{
// 					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ _AhnHS_VerifyResponseEx() error !! Ret(0x%X) ErrorCode(0x%X)\r\n", ulRet, ulErrCode);
// 				
// 					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
// 					SendErrorMessage(T_FC_MOVE_HACKSHIELD_CRCAckMsg, ERR_SECURITY_HACKING_CRC, ulRet, ulErrCode, NULL, TRUE); 
// 					this->Close(0x1406C, FALSE, 3000);
// 					return ERR_NO_ERROR;
// 				}
// 				m_Security_bSendCRCReqMsg		= FALSE;				// 2006-06-08 by cmkwon
// 
// 			}
// #endif // END - #if defined(_USING_HACKSHIELD_)		// 2009-04-29 by cmkwon, 핵쉴드 사용 여부 #define 으로 처리 - 
			// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
		}
		break;

	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:			// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - 일정시간마다 체크
		{
#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
			if(FALSE == ms_bUsingXignCode)
			{
				return ERR_NO_ERROR;
			}

			if(NULL == i_pCRCAckMsg)
			{
				if(m_hXignCodeAntiCheatHandle)
				{// 2008-11-28 by cmkwon, 이전에 보낸 메시지 응답을 받지 못한 상태이다
					DWORD dwCur = timeGetTime();
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ TermTick(%d) = CurrentTick(%d) - BeforeTick(%d)\r\n"
						, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
					
					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
					SendErrorMessage(T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
					this->Close(0x1406D, FALSE, 3000);
					return ERR_NO_ERROR;
				}

				HANDLE hAntiCheat = ZSWAVE_Open(MAX_PACKET_SIZE_FOR_XIGNCODE, Z_SCAN_TYPE_ANTI_CHEAT_ENGINE);
				if(NULL == hAntiCheat)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_ ZSWAVE_Open() error !!(%d)\r\n", GetLastError());
					
					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
					SendErrorMessage(T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
					this->Close(0x1406E, FALSE, 3000);
					return ERR_NO_ERROR;
				}
				
				INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK, T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK, pScanCheck, SendBuf);
				pScanCheck->byDataCount		= ZSWAVE_GetDataCount(hAntiCheat);
				pScanCheck->byCurDataIndex	= 0;
				ZSWAVE_GetDataAt(hAntiCheat, pScanCheck->byCurDataIndex, (char*)pScanCheck->byCheckData);
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK));

				m_hXignCodeAntiCheatHandle			= hAntiCheat;
				m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();		// 2008-11-28 by cmkwon, 추가
			}
			else
			{// 2008-11-28 by cmkwon, 응답 받은 메시지 유효성 체크한다.

				MSG_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK *pReqScanCheckOK = (MSG_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK*)i_pCRCAckMsg;
				if(NULL == m_hXignCodeAntiCheatHandle)
				{
					return ERR_NO_ERROR;
				}

				BOOL bReqScanInitOK = TRUE;
				if(FALSE == ZSWAVE_Verify(m_hXignCodeAntiCheatHandle, pReqScanCheckOK->byResultData, MAX_PACKET_SIZE_FOR_XIGNCODE))
				{
					if(FALSE == this->SecurityXignCodeGetErrorString(m_hXignCodeAntiCheatHandle, (char*)pReqScanCheckOK->byResultData))
					{
						g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck_# SecurityXignCodeGetErrorString() error !! %s\r\n"
							, GetCharacterString(this->GetCharacter(), string()));
						
						CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
						SendErrorMessage(T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
						this->Close(0x1406F, FALSE, 3000);
						return ERR_NO_ERROR;
					}
				}
				ZSWAVE_Close(m_hXignCodeAntiCheatHandle);
				m_hXignCodeAntiCheatHandle			= NULL;
			}

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)
		}
		break;
	case LANGUAGE_TYPE_JAPANESE:
		{

#if defined(SERVICE_TYPE_JAPANESE_SERVER_1)
			///////////////////////////////////////////////////////////////////////////////
			// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 주기당 체크
			if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
			{
				return ERR_NO_ERROR;
			}

			if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
			{// 2009-03-11 by cmkwon, 관리자는 CS인증을 제외한다.
				return ERR_NO_ERROR;
			}

			if(NULL == i_pCRCAckMsg)
			{
				UINT32 uiRet = m_csAuth2forNProtect.GetAuthQuery();
				if(ERROR_SUCCESS != uiRet)
				{// 2009-03-09 by cmkwon, 초기화 에러이거나 응답을 받지 못한 상태에서 재요청시 에러 발생
					DWORD dwCur = timeGetTime();
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck# GetAuthQuery() error !! %s Ret(%d), TermTick(%d) = CurrentTick(%d) - BeforeTick(%d) \r\n"
						, GetCharacterString(this->GetCharacter(), string()), uiRet, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
					SendErrorMessage(T_FC_MOVE_NPROTECT_REQ_AUTH_DATA, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
					this->Close(0x14071, FALSE, 3000);
					return ERR_NO_ERROR;
				}
				INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_NPROTECT_REQ_AUTH_DATA, T_FC_MOVE_NPROTECT_REQ_AUTH_DATA, pSMsg, SendBuf);
				memcpy(pSMsg->reqAuthData, &m_csAuth2forNProtect.m_AuthQuery, sizeof(GG_AUTH_DATA));
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_NPROTECT_REQ_AUTH_DATA));

				m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();				// 2009-03-09 by cmkwon
			}
			else
			{
				MSG_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK	*pReqAuthDataOK = (MSG_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK*)i_pCRCAckMsg;
				memcpy(&m_csAuth2forNProtect.m_AuthAnswer, pReqAuthDataOK->resAuthData, sizeof(GG_AUTH_DATA));
				UINT32 uiRet = m_csAuth2forNProtect.CheckAuthAnswer();
				if(ERROR_SUCCESS != uiRet)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck# CheckAuthAnswer() error !! %s Ret(%d)\r\n"
						, GetCharacterString(this->GetCharacter(), string()), uiRet);
					
					CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
					SendErrorMessage(T_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
					this->Close(0x14072, FALSE, 3000);
					return ERR_NO_ERROR;
				}
			}
#endif
		}
		break;
	}

#if defined(SERVICE_TYPE_ARGENTINA_SERVER_1) || defined(SC_XTRAP_VTC_GAMEGUARD_BHSOHN_JHSEOL)	// 2013-10-09 by jhseol, X-Trap + VTC 게임가드		// 2012-02-09 by hskim, 베트남 X-Trap -> VTC 가드로 변경
	{
		if(FALSE == CFieldIOCPSocket::ms_XTrapUsingFlag)
		{
			return ERR_NO_ERROR;
		}
		if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
		{// 2009-10-08 by cmkwon, 관리자는 CS인증을 제외한다.
			return ERR_NO_ERROR;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - CFieldIOCPSocket::SecurityClientCheck# 처리
		if(NULL == i_pCRCAckMsg)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_XTRAP_REQ_STEP, T_FC_MOVE_XTRAP_REQ_STEP, pSMsg, SendBuf);
			DWORD dwRet = XTrap_CS_Step1(m_XTrapSessionBuf, pSMsg->reqCSStepData);
			if(0 != dwRet)
			{
				char szErrTxt[1024];
				DWORD dwCur = timeGetTime();
				sprintf(szErrTxt, "[Error] CFieldIOCPSocket::SecurityClientCheck# XTrap_CS_Step1# error !! %s dwRet(%d), TermTick(%d) = CurrentTick(%d) - BeforeTick(%d) \r\n"
					, GetCharacterString(this->GetCharacter(), string()), dwRet, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, szErrTxt);
				CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC, szErrTxt);
				SendErrorMessage(T_FC_MOVE_XTRAP_REQ_STEP, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
				this->Close(0x14073, FALSE, 3000);
				return ERR_NO_ERROR;
			}

			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_XTRAP_REQ_STEP));

			m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();
		}
		else
		{
			MSG_FC_MOVE_XTRAP_REQ_STEP_OK	*pResStep = (MSG_FC_MOVE_XTRAP_REQ_STEP_OK*)i_pCRCAckMsg;
			DWORD dwRet = XTrap_CS_Step3(m_XTrapSessionBuf, pResStep->resCSStepData);
			if(0 != dwRet)
			{
				// 2009-10-07 by cmkwon, 로그만 남기고 소켓 종료 처리는 하지 않는다.
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck# XTrap_CS_Step3# error !! %s dwRet(%d)\r\n", GetCharacterString(this->GetCharacter(), string()), dwRet);				
				CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
			}
		}
	}
#endif // END - #if defined(SERVICE_TYPE_VIETNAMESE_SERVER_1)


#if defined(SERVICE_TYPE_THAI_SERVER_1) || defined(SERVICE_TYPE_SINGAPORE_1) || defined(SERVICE_TYPE_INDONESIA_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientCheck#
	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::SecurityClientCheck#,
	{
		if(NULL == i_pCRCAckMsg)
		{
			return ERR_NO_ERROR;		// 2009-11-04 by cmkwon, 여기에서 전송하는 데이터는 없다, CFieldIOCPSocket::SecurityApexSendData# 함수에서 전송 처리됨
		}

		MSG_FC_MOVE_APEX_REQ_APEXDATA_OK	*pRApex = (MSG_FC_MOVE_APEX_REQ_APEXDATA_OK*)i_pCRCAckMsg;

//		// 2009-11-04 by cmkwon, 임시용
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 091104 CFieldIOCPSocket::SecurityClientCheck# %s ApexMsgTy(%d) ApexDataLen(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pRApex->cMsgType, pRApex->nApexDataLen);

		switch(pRApex->cMsgType)
		{
		case SECURITY_APEX_Cmd_ClientRet:
			{
				if(ms_pfRec4Apex)
				{
					ms_pfRec4Apex('R', GetCharacter()->ClientIndex, pRApex->szApexData, pRApex->nApexDataLen);
				}
			}
			break;
		case SECURITY_APEX_Cmd_ApexData:
			{
				if(ms_pfRec4Apex)
				{
					ms_pfRec4Apex('T', GetCharacter()->ClientIndex, pRApex->szApexData, pRApex->nApexDataLen);
				}
			}
			break;
		default:
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SecurityClientCheck# Apex invalid ApexMsgType !! %s ApexMsgType(%d) ApexDataLen(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pRApex->cMsgType, pRApex->nApexDataLen);
				CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
				SendErrorMessage(T_FC_MOVE_APEX_REQ_APEXDATA_OK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
				this->Close(0x14074, FALSE, 3000);
				return ERR_NO_ERROR;
			}
		}
	}
#endif	// END - #if defined(SERVICE_TYPE_THAI_SERVER_1)		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 

	return ERR_NO_ERROR;
}

Err_t CFieldIOCPSocket::SecurityClientCheck_GFNP(MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK *i_pCRCAckMsg/*=NULL*/, BOOL i_bCheckTerm/*=TRUE*/)
{
	if(FALSE == CFieldIOCPSocket::IsInitializedSecurityServer())
	{
		return ERR_NO_ERROR;
	}
	if(FALSE == this->GetInitSecurityClient())
	{
		return ERR_NO_ERROR;
	}
	if(NULL == i_pCRCAckMsg	&& i_bCheckTerm)
	{
		int nTermTick = timeGetTime() - m_dwReadyTickforSecurityCheck;
		if(50000 > nTermTick)
		{// 2009-03-10 by cmkwon, 50초 경과 체크
			return ERR_NO_ERROR;
		}
	}
	
	// 2012-06-25 by hskim, 라이브 디버깅 환경 구축 
	if( 0 == strncmp(MASANG_LIVE_PC_IP, this->GetPeerIP(), SIZE_MAX_IPADDRESS) )
	{
		return ERR_NO_ERROR;
	}
	// end 2012-06-25 by hskim, 라이브 디버깅 환경 구축 
	
	// 2008-04-25 by cmkwon, 지원 언어/서비스 추가시 꼭 추가 되어야 하는 사항 - [언어-옵션] 추가 언어시에 핵쉴드 일정 시간 마다 체크
	
	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_KOREAN: break;
	case LANGUAGE_TYPE_ENGLISH:
	case LANGUAGE_TYPE_GERMAN:
	case LANGUAGE_TYPE_TURKISH:
	case LANGUAGE_TYPE_ITALIAN:
	case LANGUAGE_TYPE_FRENCH:
	case LANGUAGE_TYPE_POLISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
	case LANGUAGE_TYPE_SPANISH:			// 2009-06-04 by cmkwon, 지원 서비스 추가(Gameforge4D 폴란드어, 스페인어) - 
#if defined(_DEFINED_GAMEFORGE4D_)		// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
		if(FALSE == CFieldIOCPSocket::ms_bUsingNProtect)
		{
			return ERR_NO_ERROR;
		}
		
		if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
		{
			return ERR_NO_ERROR;
		}
		
		if(NULL == i_pCRCAckMsg)
		{
			UINT32 uiRetPckSize = 0;
			UINT32 uiRet = m_csAuth3forNProtect.Get(&uiRetPckSize);
			if(ERROR_SUCCESS != uiRet)
			{
				DWORD dwCur = timeGetTime();
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck# GetAuthQuery() error !! %s Ret(%d), TermTick(%d) = CurrentTick(%d) - BeforeTick(%d) \r\n"
					, GetCharacterString(this->GetCharacter(), string()), uiRet, dwCur - m_dwSetTickSecurity_bSendCRCReqMsg, dwCur, m_dwSetTickSecurity_bSendCRCReqMsg);
				CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
				SendErrorMessage(T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
				this->Close(0x14071, FALSE, 3000);
				return ERR_NO_ERROR;
			}
			for(int i=0;i<11;i++){
				INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA, T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA, i_pCRCAckMsg, SendBuf);
				i_pCRCAckMsg->datasize = 0;
				memcpy(i_pCRCAckMsg->reqAuthData, &m_csAuth3forNProtect.packet + (i * SEGMENT_PACKET_SIZE_FOR_NPROTECT_NEW), SEGMENT_PACKET_SIZE_FOR_NPROTECT_NEW);
				if (uiRetPckSize < (i + 1) * SEGMENT_PACKET_SIZE_FOR_NPROTECT_NEW)
				{
					i_pCRCAckMsg->datasize = uiRetPckSize;
					this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA));
					break;
				} else {
					this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA));
				}
			}
			
			m_dwSetTickSecurity_bSendCRCReqMsg	= timeGetTime();
		}
		else
		{
			memcpy(&m_newNProtectPacket + (m_newNProtectPacketCnt * SEGMENT_PACKET_SIZE_FOR_NPROTECT_NEW),i_pCRCAckMsg->resAuthData,SEGMENT_PACKET_SIZE_FOR_NPROTECT_NEW);
			m_newNProtectPacketCnt++;
			
			if(0 == i_pCRCAckMsg->datasize){	
				break;
			}
			m_newNProtectPacketCnt=0;
			memcpy(&m_csAuth3forNProtect.packet, m_newNProtectPacket, i_pCRCAckMsg->datasize);
			UINT32 uiRecSize = i_pCRCAckMsg->datasize;
			UINT32 uiRet = m_csAuth3forNProtect.Check(uiRecSize);
			if(uiRecSize >= 3000){
				this->Close(0x14072, FALSE, 3000);
				return ERR_NO_ERROR;
			}
			if(ERROR_SUCCESS != uiRet)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::SecurityClientCheck# CheckAuthAnswer() error !! %s Ret(%d)\r\n"
					, GetCharacterString(this->GetCharacter(), string()), uiRet);
				
				CAtumLogSender::SendLogMessageHackingLog(this, ERR_SECURITY_HACKING_CRC);
				SendErrorMessage(T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK, ERR_SECURITY_HACKING_CRC, 0, 0, NULL, TRUE); 
				this->Close(0x14072, FALSE, 3000);
				return ERR_NO_ERROR;
			}
		}
#endif
	break;
	
	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case LANGUAGE_TYPE_TAIWANESE:
	case LANGUAGE_TYPE_CHINESE:	
	case LANGUAGE_TYPE_JAPANESE:
		break;
	}
	return ERR_NO_ERROR;
}


struct SFind_if_ActionInfo_BY_UnitIndex
{
	SFind_if_ActionInfo_BY_UnitIndex(int i_UnitIdx): m_nFindUnitIndex(i_UnitIdx){};
	bool operator()(const ActionInfo actionInfo)
	{
		return actionInfo.UnitIndex == m_nFindUnitIndex;
	}
	int m_nFindUnitIndex;
};

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::AddAggroList(ActionInfo *i_pActionInfoAggro)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-21 ~ 2006-07-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::AddAggroList(ActionInfo *i_pActionInfoAggro)
{
	if(NULL == m_pFieldParty)
	{
		return;
	}
	i_pActionInfoAggro->fSumAggro *= 2.0f;			// 2006-07-21 by cmkwon, 어그로량은 힐링값의 두배로 설정한다.

	mt_auto_lock mtA(&m_mtvectActionInfoAggroList);
	mtvectActionInfo::iterator itr = find_if(m_mtvectActionInfoAggroList.begin(), m_mtvectActionInfoAggroList.end()
		, SFind_if_ActionInfo_BY_UnitIndex(i_pActionInfoAggro->UnitIndex));
	if(itr != m_mtvectActionInfoAggroList.end())
	{
		itr->dwCurTick		= i_pActionInfoAggro->dwCurTick;
		itr->fSumAggro		+= i_pActionInfoAggro->fSumAggro;
		return;
	}
	
	m_mtvectActionInfoAggroList.push_back(*i_pActionInfoAggro);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GetAggroList(vectActionInfo *o_pvectActionInfo)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-21 ~ 2006-07-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetAggroList(vectActionInfo *o_pvectActionInfo)
{
	mt_auto_lock mtA(&m_mtvectActionInfoAggroList);
	if(m_mtvectActionInfoAggroList.empty())
	{
		return FALSE;
	}

	if(m_pFieldParty)
	{// 2006-07-21 by cmkwon, 파티 상태일때만 유효가 정보다
		*o_pvectActionInfo = this->m_mtvectActionInfoAggroList;
	}
	this->m_mtvectActionInfoAggroList.clear();
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::MakeMSG_FC_BAZAAR_INFO_OKW(MSG_FC_BAZAAR_INFO_OK *o_pBazaarInfoOK)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::MakeMSG_FC_BAZAAR_INFO_OKW(MSG_FC_BAZAAR_INFO_OK *o_pBazaarInfoOK)
{
	return m_bazaarManager.MakeMSG_FC_BAZAAR_INFO_OK(o_pBazaarInfoOK);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SendBazaarItemList(CFieldIOCPSocket *i_pFISock, BYTE i_byBazaarTy)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SendBazaarItemList(CFieldIOCPSocket *i_pFISock, BYTE i_byBazaarTy)
{
	if(FALSE == IsValidCharacter())
	{
		return FALSE;
	}

	mt_auto_lock igLock(&this->m_ItemManager.m_mapItemGeneral);
	mt_auto_lock bmLock(this->m_bazaarManager.GetBazaarItemListPtr());

	if(BAZAAR_STATE_ACTIVE != this->m_bazaarManager.GetBazaarState()
		|| i_byBazaarTy != this->m_bazaarManager.GetBazaarType())
	{		
		return FALSE;
	}

	if(this->m_bazaarManager.IsEmptyBazaar())
	{		
		return FALSE;
	}

	if(BAZAAR_TYPE_SELL == i_byBazaarTy)
	{
		vectUID64_t vectItemUIDListForEnchant;
		INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_SELL_REQUEST_ITEMLIST_OK, T_FC_BAZAAR_SELL_REQUEST_ITEMLIST_OK, pSItemListOK, SendBuf);
		pSItemListOK->clientIndex0		= GetCharacter()->ClientIndex;
		pSItemListOK->nItemListCnts0	= m_bazaarManager.MakeMSG_FC_BAZAAR_SELL_REQUEST_ITEMLIST_OK((SBAZAAR_SELL_ITEM*)(SendBuf+MSG_SIZE(MSG_FC_BAZAAR_SELL_REQUEST_ITEMLIST_OK)), &vectItemUIDListForEnchant);
		bmLock.auto_unlock_cancel();
		igLock.auto_unlock_cancel();

		if(0 >= pSItemListOK->nItemListCnts0)
		{
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 판매 리스트 전송
		i_pFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_REQUEST_ITEMLIST_OK)+pSItemListOK->nItemListCnts0*sizeof(SBAZAAR_SELL_ITEM));

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 판매상점에 들어옴을 알림
		INIT_MSG(MSG_FC_BAZAAR_CUSTOMER_INFO_OK, T_FC_BAZAAR_CUSTOMER_INFO_OK, pSCustomerInfo, SendBuf);
		pSCustomerInfo->clientIndex0	= i_pFISock->GetCharacter()->ClientIndex;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_CUSTOMER_INFO_OK));

		if(false == vectItemUIDListForEnchant.empty())
		{// 2006-07-26 by cmkwon, 판매 리스트의 인챈트 정보 전송

			this->SendEnchatItemNumList(i_pFISock, &vectItemUIDListForEnchant);
		}
	}
	else
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_BUY_REQUEST_ITEMLIST_OK, T_FC_BAZAAR_BUY_REQUEST_ITEMLIST_OK, pSItemListOK, SendBuf);
		pSItemListOK->clientIndex0		= GetCharacter()->ClientIndex;
		pSItemListOK->nItemListCnts0	= m_bazaarManager.MakeMSG_FC_BAZAAR_BUY_REQUEST_ITEMLIST_OK((SBAZAAR_BUY_ITEM*)(SendBuf+MSG_SIZE(MSG_FC_BAZAAR_BUY_REQUEST_ITEMLIST_OK)));
		bmLock.auto_unlock_cancel();
		igLock.auto_unlock_cancel();

		if(0 >= pSItemListOK->nItemListCnts0)
		{
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 구입 리스트 전송
		i_pFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_BUY_REQUEST_ITEMLIST_OK)+pSItemListOK->nItemListCnts0*sizeof(SBAZAAR_BUY_ITEM));

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 구입상점에 들어옴을 알림
		INIT_MSG(MSG_FC_BAZAAR_CUSTOMER_INFO_OK, T_FC_BAZAAR_CUSTOMER_INFO_OK, pSCustomerInfo, SendBuf);
		pSCustomerInfo->clientIndex0	= i_pFISock->GetCharacter()->ClientIndex;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_CUSTOMER_INFO_OK));

	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendEnchatItemNumList(CFieldIOCPSocket *i_pFISock, vectUID64_t *i_pItemUIDList)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendEnchatItemNumList(CFieldIOCPSocket *i_pFISock, vectUID64_t *i_pItemUIDList)
{
	if(i_pItemUIDList->empty())
	{
		return;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_SELL_ITEM_ENCHANTLIST_OK, T_FC_BAZAAR_SELL_ITEM_ENCHANTLIST_OK, pSEnchantOK, SendBuf);

	mt_auto_lock mtA(&m_mapEnchant);

	int nVectSize = i_pItemUIDList->size();
	for(int i=0; i < nVectSize; i++)
	{
		mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find((*i_pItemUIDList)[i]);
		if(itrEnchantList != m_mapEnchant.end())
		{
			pSEnchantOK->itemUID		= (*i_pItemUIDList)[i];
			pSEnchantOK->nEnchatCnts	= 0;
			int			*pEnchantItemNum = (int*)(SendBuf+MSG_SIZE(MSG_FC_BAZAAR_SELL_ITEM_ENCHANTLIST_OK));
			vectENCHANT *pvectEnchant = &itrEnchantList->second;
			for(int j=0; j < pvectEnchant->size(); j++)
			{
				if(SIZE_MAX_PACKET < MSG_SIZE(MSG_FC_BAZAAR_SELL_ITEM_ENCHANTLIST_OK) + sizeof(pSEnchantOK->nEnchatCnts + 1))
				{// 2008-02-18 by cmkwon, 체크 추가
					break;
				}
				pEnchantItemNum[pSEnchantOK->nEnchatCnts]	= (*pvectEnchant)[j].EnchantItemNum;
				pSEnchantOK->nEnchatCnts++;
			}

			i_pFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BAZAAR_SELL_ITEM_ENCHANTLIST_OK) + pSEnchantOK->nEnchatCnts * sizeof(int));
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::BazaarInsertItem(CFieldIOCPSocket *i_pFromFISock, ITEM_GENERAL *i_pInsertItemGen, int i_nItemCnts, BYTE i_nItemUpdateType/*=IUT_BAZAAR_SELL*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-27 ~ 2006-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::BazaarInsertItem(CFieldIOCPSocket *i_pFromFISock, ITEM_GENERAL *i_pInsertItemGen, int i_nItemCnts, BYTE i_nItemUpdateType/*=IUT_BAZAAR_SELL*/)
{
	if(FALSE == IS_COUNTABLE_ITEM(i_pInsertItemGen->Kind))
	{
		///////////////////////////////////////////////////////////////////////////////
		// 1. 주는 사람 Log 남기기
		ITEM_GENERAL tmpItemOnlyForLog = *i_pInsertItemGen;	// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
		tmpItemOnlyForLog.CurrentCount = 0;
		CAtumLogSender::SendLogMessageITEMBazaarSend(i_pFromFISock, &tmpItemOnlyForLog, 1, &this->m_character);	// 아이템 거래: 주기, non-countable

		///////////////////////////////////////////////////////////////////////////////
		// 2. 아이템 소유자의 인벤에서 삭제함 - DB에 업데이트 하지 않음, 메모리를 삭제하지 않음

		i_pFromFISock->m_ItemManager.RemoveTimerFixedTermShape(i_pInsertItemGen);		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

		i_pFromFISock->m_ItemManager.DeleteItemFromCharacterByUID(i_pInsertItemGen->UniqueNumber, i_nItemUpdateType, ITEM_IN_CHARACTER, FALSE, TRUE, FALSE);

		///////////////////////////////////////////////////////////////////////////////
		// 3. 내 인벤에 아이템 추가 - DB에 업데이트 하지 않음
		i_pInsertItemGen->Wear				= FALSE;
		i_pInsertItemGen->ItemWindowIndex	= POS_INVALID_POSITION;
		this->m_ItemManager.InsertItemGeneralByPointer(i_pInsertItemGen, i_nItemUpdateType, FALSE, ITEM_IN_CHARACTER, FALSE);

		this->m_ItemManager.RegisterTimerFixedTermShape(i_pInsertItemGen);		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

		///////////////////////////////////////////////////////////////////////////////
		// 4. 인챈트 처리
		vectENCHANT tmvectEnchant;
		if(i_pFromFISock->PopAllEnchantByItemUID(&tmvectEnchant, i_pInsertItemGen->UniqueNumber))
		{
			this->DeleteAllEnchantToItem(i_pInsertItemGen->UniqueNumber);		// 2006-05-11 by cmkwon, 만약을 위해 초기화
			this->InsertEnchantToItem(i_pInsertItemGen, &tmvectEnchant);
		}

		///////////////////////////////////////////////////////////////////////////////
		// 5. DB로 전송
		QPARAM_TRADE_MOVEITEM	*pMoveItem = new QPARAM_TRADE_MOVEITEM;
		pMoveItem->ToAccountUID		= GetCharacter()->AccountUniqueNumber;
		pMoveItem->ToCharacterUID	= GetCharacter()->CharacterUniqueNumber;
		pMoveItem->FromCharacterUID	= i_pFromFISock->GetCharacter()->CharacterUniqueNumber;
		pMoveItem->MoveItemUID		= i_pInsertItemGen->UniqueNumber;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_TradeMoveItem, this, m_character.AccountUniqueNumber, pMoveItem);

		///////////////////////////////////////////////////////////////////////////////
		// 6. 받는 사람 로그 남기기
		CAtumLogSender::SendLogMessageITEMBazaarRecv(this, i_pInsertItemGen, 1, &i_pFromFISock->m_character);	// 아이템 거래: 받기, non-countable
	}
	else
	{
		int nInsertItemNum = i_pInsertItemGen->ItemNum;

		///////////////////////////////////////////////////////////////////////////////
		// 1. 내 인벤토리에 아이템 추가함
		m_ItemManager.InsertItemGeneralByItemNum(i_pInsertItemGen->ItemNum, i_nItemCnts, i_nItemUpdateType, ITEM_IN_CHARACTER, TRUE, TRUE, i_pFromFISock->GetCharacter()->CharacterUniqueNumber);

		///////////////////////////////////////////////////////////////////////////////
		// 2. 받는 사람 로그 남기기
		ITEM_GENERAL *pMeItemG = m_ItemManager.GetFirstItemGeneralByItemNum(i_pInsertItemGen->ItemNum);
		if(NULL == pMeItemG)
		{// 2006-05-15 by cmkwon, 아이템이 추가되는 경우, DB에 추가중, 로그도 DB 추가 후 남긴다.
			char szSysLog[1024];
			wsprintf(szSysLog, "[Notify] CFieldIOCPSocket::BazaarInsertItem_ Insert to DB CharacterInfo(%s:%d), PeerCharacterInfo(%s:%d), ItemNum(%d), ItemCount(%d)\r\n"
				, m_character.CharacterName, m_character.CharacterUniqueNumber
				, i_pFromFISock->GetCharacter()->CharacterName, i_pFromFISock->GetCharacter()->CharacterUniqueNumber
				, i_pInsertItemGen->ItemNum, i_nItemCnts);
			DbgOut(szSysLog);
			g_pFieldGlobal->WriteSystemLog(szSysLog);
		}
		else
		{
			CAtumLogSender::SendLogMessageITEMBazaarRecv(this, pMeItemG, i_nItemCnts, &i_pFromFISock->m_character);
		}
		
		///////////////////////////////////////////////////////////////////////////////
		// 3. 주는 사람 인벤에서 아이템 개수 줄임 혹은 제거
		ITEM_GENERAL tmpItemOnlyForLog = *i_pInsertItemGen;	// 주의: only 로그용!
		i_pFromFISock->m_ItemManager.UpdateItemCountByPointer(i_pInsertItemGen, -i_nItemCnts, i_nItemUpdateType);

		///////////////////////////////////////////////////////////////////////////////
		// 4. 주는 사람 로그
		ITEM_GENERAL *pPeerItemG = i_pFromFISock->m_ItemManager.GetFirstItemGeneralByItemNum(nInsertItemNum);
		if(NULL == pPeerItemG)
		{
			tmpItemOnlyForLog.CurrentCount	= 0;
			CAtumLogSender::SendLogMessageITEMBazaarSend(i_pFromFISock, &tmpItemOnlyForLog, i_nItemCnts, &this->m_character);	// 아이템 거래: 주기
		}
		else
		{
			CAtumLogSender::SendLogMessageITEMBazaarSend(i_pFromFISock, pPeerItemG, i_nItemCnts, &this->m_character);	// 아이템 거래: 주기
		}
	}

	return TRUE;
}


CFieldCharacterQuest* CFieldIOCPSocket::GetCharacterQuestInProgress()
{
	mt_auto_lock mtA(&this->m_mapQuest);

	//////////////////////////////////////////////////////////////////////////
	// 퀘스트 진행이 하나만 가능하도록 하는 수정부분.
	//////////////////////////////////////////////////////////////////////////	
	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest = m_mapQuest.begin();
	for(; itrQuest != m_mapQuest.end(); itrQuest++)
	{
		CharacterQuest *pCharacterQuest = &itrQuest->second;
		if (m_character.CharacterUniqueNumber == pCharacterQuest->CharacterUniqueNumber 
			&& pCharacterQuest->QuestState == QUEST_STATE_IN_PROGRESS)
		{
			return &itrQuest->second;
		}
	}

	return NULL;	
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GalaNetSetAccountIDNum(int i_nAccountIDNum)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-01 ~ 2006-06-01
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GalaNetSetAccountIDNum(int i_nAccountIDNum)
{
	m_GalaNetAccountIDNum		= i_nAccountIDNum;
}

// 2014-12-08 by bckim, 고급고급무기 이펙트 장탄수 확장 기능추가
BOOL CFieldIOCPSocket::IsEffectInWingout()
{
#ifdef SC_INCREASE_BULLETS_OF_ADVANCED_WEAPONS_BY_EFFECT	
	ITEM_GENERAL *pWeaponItemGen	= NULL;
	pWeaponItemGen	= (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
	
	if(  NULL != pWeaponItemGen && pWeaponItemGen->ColorCode )
	{
		return TRUE;
	}
#endif

	return FALSE;
}
// End. 2014-12-08 by bckim, 고급고급무기 이펙트 장탄수 확장 기능추가

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckCharacterUIDFormAccount(UID32_t i_CharactUID)
/// \brief		
/// \author		dhjin
/// \date		2006-09-15 ~ 2006-09-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckCharacterUIDFormAccount(UID32_t i_CharactUID)
{
	mt_auto_lock mta(&m_mtvectAllCharacterInfo);

	if(NULL == GetFC_CONNECT_LOGIN_INFONoLock(i_CharactUID))
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::DeleteCharacterUIDFormAccount(UID32_t i_CharactUID)
/// \brief		
/// \author		dhjin
/// \date		2006-09-15 ~ 2006-09-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::DeleteCharacterUIDFormAccount(UID32_t i_CharactUID)
{
	mt_auto_lock mta(&m_mtvectAllCharacterInfo);

	vector<FC_CONNECT_LOGIN_INFO>::iterator itr = m_mtvectAllCharacterInfo.begin();
	for (; itr != m_mtvectAllCharacterInfo.end(); itr++)
	{
		if(itr->CharacterUniqueNumber == i_CharactUID)
		{
			m_mtvectAllCharacterInfo.erase(itr);
			return TRUE;
		}
	}

	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			FC_CONNECT_LOGIN_INFO * CFieldIOCPSocket::GetFC_CONNECT_LOGIN_INFONoLock(UID32_t i_CharactUID)
/// \brief		
/// \author		cmkwon
/// \date		2006-10-18 ~ 2006-10-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
FC_CONNECT_LOGIN_INFO * CFieldIOCPSocket::GetFC_CONNECT_LOGIN_INFONoLock(UID32_t i_CharactUID)
{
	vector<FC_CONNECT_LOGIN_INFO>::iterator itr = m_mtvectAllCharacterInfo.begin();
	for (; itr != m_mtvectAllCharacterInfo.end(); itr++)
	{
		if(itr->CharacterUniqueNumber == i_CharactUID)
		{			
			return itr;
		}
	}

	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
/// \author		cmkwon
/// \date		2009-11-03 ~ 2009-11-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BYTE CFieldIOCPSocket::GetAddedPermanentInventoryCountOfOthersCharacter(UID32_t i_CharactUID)
{
	mt_auto_lock AllCharLock(&m_mtvectAllCharacterInfo);
	FC_CONNECT_LOGIN_INFO * pLoginInfo = GetFC_CONNECT_LOGIN_INFONoLock(i_CharactUID);
	
	if (NULL == pLoginInfo)
	{		
		return 0;
	}

	CHARACTER tmCharac;
	MEMSET_ZERO(&tmCharac, sizeof(tmCharac));

	tmCharac.RacingPoint	= pLoginInfo->RacingPoint;
	return tmCharac.GetAddedPermanentInventoryCount(ITEM_IN_STORE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
/// \author		cmkwon
/// \date		2009-11-03 ~ 2009-11-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetAddedPermanentInventoryCountOfOthersCharacter(UID32_t i_CharactUID, int i_nRacingPoint)
{
	mt_auto_lock AllCharLock(&m_mtvectAllCharacterInfo);
	FC_CONNECT_LOGIN_INFO * pLoginInfo = GetFC_CONNECT_LOGIN_INFONoLock(i_CharactUID);	
	if (NULL == pLoginInfo)
	{
		return FALSE;
	}
	pLoginInfo->RacingPoint		= i_nRacingPoint;
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ObserverTargetCharacterCheck(CFieldIOCPSocket *i_pOTFISock)
/// \brief		
/// \author		dhjin
/// \date		2007-03-28 ~ 2007-03-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ObserverTargetCharacterCheck(CFieldIOCPSocket *i_pOTFISock)
{
	if(NULL == i_pOTFISock
		|| FALSE == i_pOTFISock->IsValidCharacter(FALSE))
	{
		return FALSE;
	}

	if(COMPARE_BODYCON_BIT(this->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
		|| COMPARE_BODYCON_BIT(i_pOTFISock->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
	{
		return FALSE;
	}

	if(this->GetCurrentFieldMapChannel() != i_pOTFISock->GetCurrentFieldMapChannel())
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::WatchTargetCharacterCheck(CFieldIOCPSocket *i_pOTFISock)
/// \brief		
/// \author		dhjin
/// \date		2007-06-19 ~ 2007-06-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::WatchTargetCharacterCheck(CFieldIOCPSocket *i_pOTFISock)
{
	if(NULL == i_pOTFISock
		|| FALSE == i_pOTFISock->IsValidCharacter(FALSE))
	{
		return FALSE;
	}

	if(COMPARE_BODYCON_BIT(this->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
		|| COMPARE_BODYCON_BIT(i_pOTFISock->m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
	{
		return FALSE;
	}

	if(this->GetCurrentFieldMapChannel() != i_pOTFISock->GetCurrentFieldMapChannel())
	{
		return FALSE;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-06-19 by dhjin, 관전 모드가 아니면 삭제
	if(FALSE == i_pOTFISock->m_ArenaInfo.WatchState)
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertArenaItem(int i_itemNum, int i_nCnts, BYTE i_nItemUpdateType /*= IUT_ARENA_ITEM*/)
/// \brief		아레나 전용 아이템 지급
/// \author		dhjin
/// \date		2007-06-04 ~ 2007-06-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertArenaItem(int i_itemNum, int i_nCnts, BYTE i_nItemUpdateType/* = IUT_ARENA_ITEM*/)
{
	mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);
	if(FALSE == IsValidCharacter(FALSE))
	{
		return FALSE;
	}

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(i_itemNum);
	if(NULL == pItemInfo)
	{
		return FALSE;
	}

	if(MONEY_ITEM_NUMBER != i_itemNum											// 2008-04-28 by dhjin, 아레나 통합 - SPI는 ITEM_ATTR_ARENA_ITEM 상관없이 추가,
		&& !COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_ARENA_ITEM)
		)
	{
		return FALSE;
	}
		
	return m_ItemManager.InsertItemBaseByItemNum(i_itemNum, i_nCnts, i_nItemUpdateType);	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::APInsertAttackParameter(SATTACK_PARAMETER *i_pAttParam)
/// \brief		
/// \author		cmkwon
/// \date		2007-06-08 ~ 2007-06-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::APInsertAttackParameter(SATTACK_PARAMETER *i_pAttParam)
{
	mt_auto_lock mtA(&m_mtvectSAttackParameterList);

	if(APFindAttackParameterNoLock(i_pAttParam->WeaponIndex))
	{
		return FALSE;
	}

	m_mtvectSAttackParameterList.push_back(*i_pAttParam);
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			SATTACK_PARAMETER *CFieldIOCPSocket::APFindAttackParameterNoLock(UID16_t i_WeaponIndex)
/// \brief		
/// \author		cmkwon
/// \date		2007-06-08 ~ 2007-06-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
SATTACK_PARAMETER *CFieldIOCPSocket::APFindAttackParameterNoLock(UID16_t i_WeaponIndex)
{
	mtvectSATTACK_PARAMETER::iterator itr(m_mtvectSAttackParameterList.begin());
	for(; itr != m_mtvectSAttackParameterList.end(); itr++)
	{
		if(itr->WeaponIndex == i_WeaponIndex)
		{
			return itr;
		}
	}

	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::APPopAttackParameter(SATTACK_PARAMETER *o_pAttParam, UID16_t i_WeaponIndex)
/// \brief		
/// \author		cmkwon
/// \date		2007-06-08 ~ 2007-06-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::APPopAttackParameter(SATTACK_PARAMETER *o_pAttParam, UID16_t i_WeaponIndex)
{
	mt_auto_lock mtA(&m_mtvectSAttackParameterList);

	DWORD dwCurTick = timeGetTime();
	mtvectSATTACK_PARAMETER::iterator itr(m_mtvectSAttackParameterList.begin());
	while(itr != m_mtvectSAttackParameterList.end())
	{
		// start 2011-06-04 by hskim, 인피니티 3차 - 주포용 긴 시간 2형 탄두 무기
		DWORD dwLifeTime = TICKGAP_WARHEAD_LIFETIME;	// 2011-06-04 by hskim, 인피니티 3차 - 주포용 긴 시간 2형 탄두 무기

		if( itr->pWeaponItemInfo->Kind == ITEMKIND_FOR_MON_MAIN_ARMAMENT  )
		{
			dwLifeTime = TICKGAP_WARHEAD_LIFETIME_LONG;;
		}
		// end 2011-06-04 by hskim, 인피니티 3차 - 주포용 긴 시간 2형 탄두 무기				

		if(dwCurTick - itr->dwShotTick > dwLifeTime)		// 2011-06-04 by hskim, 인피니티 3차 - 주포용 긴 시간 2형 탄두 무기 - 적용 수정
		{
			itr = m_mtvectSAttackParameterList.erase(itr);
			continue;
		}
		else if(itr->WeaponIndex == i_WeaponIndex)
		{
			*o_pAttParam = *itr;
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(g_pFieldGlobal->IsArenaServer()
				// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
				// 기존
				//&& INFINITY_STATE_PLAYING == this->m_InfinityPlayingInfo.InfinityState) {
				// 수정
				&& TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState) )	{
				// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
				
				// 아레나 서버에서 인피니티 중이라면 기본무기 최소 공격력 보정
				if(o_pAttParam->fAttack < this->m_InfinityPlayingInfo.RevisionAdvancedWeapon) {
					o_pAttParam->fAttack = this->m_InfinityPlayingInfo.RevisionAdvancedWeapon;
				}
				if(o_pAttParam->fMaxAttack < this->m_InfinityPlayingInfo.RevisionAdvancedWeapon) {
					o_pAttParam->fMaxAttack = this->m_InfinityPlayingInfo.RevisionAdvancedWeapon;
				}
			}
			itr = m_mtvectSAttackParameterList.erase(itr);
			return TRUE;
		}

		itr++;
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::APCalcAttckParameter(SATTACK_PARAMETER *o_pAttParam, ITEM *i_pWeaponItemInfo, UID16_t i_WeaponIndex)
/// \brief		
/// \author		cmkwon
/// \date		2007-06-08 ~ 2007-06-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::APCalcAttckParameter(SATTACK_PARAMETER *o_pAttParam, ITEM *i_pWeaponItemInfo, UID16_t i_WeaponIndex, enumAttackToTarget eAttackToTarget, float i_PvPBuffPercent)	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - i_PvPBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
{
	BOOL			bIsPrimaryAttack	= FALSE;
	CParamFactor	*pAttParamFactor	= this->GetParamFactor();
	CHARACTER		*pCharacter			= &this->m_character;
	Stat_t			statAttackPart		= pCharacter->TotalGearStat.AttackPart; 
	if(IS_PRIMARY_WEAPON(i_pWeaponItemInfo->Kind))
	{
		o_pAttParam->dwShotTick				= 0;
		bIsPrimaryAttack					= TRUE;
	}
	else
	{// 2007-06-08 by cmkwon, 2형 탄두만 처리
		o_pAttParam->dwShotTick				= timeGetTime();
		bIsPrimaryAttack					= FALSE;
	}
	o_pAttParam->WeaponIndex				= i_WeaponIndex;
	o_pAttParam->pWeaponItemInfo			= i_pWeaponItemInfo;
	o_pAttParam->fAttackProbability			= CAtumSJ::GetAttackProbabilityC(i_pWeaponItemInfo, pAttParamFactor, bIsPrimaryAttack, statAttackPart, pCharacter->Level, eAttackToTarget, i_PvPBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - i_PvPBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선 - // 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	o_pAttParam->fPierceAttackProbability	= CAtumSJ::GetAttackC_PierceAttackProbability(statAttackPart, i_pWeaponItemInfo, pAttParamFactor, bIsPrimaryAttack, pCharacter->Level, eAttackToTarget, i_PvPBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - i_PvPBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선 - // 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)// 2008-09-22 by dhjin, 신규 인첸트
	o_pAttParam->fAttack					= CAtumSJ::GetAttackC(pCharacter, i_pWeaponItemInfo, pAttParamFactor, bIsPrimaryAttack, eAttackToTarget, i_PvPBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - i_PvPBuffPercent 추가		// 2013-05-09 by hskim, 세력 포인트 개선
	o_pAttParam->fMaxAttack					= CAtumSJ::GetMaxAttackC(pCharacter, i_pWeaponItemInfo, pAttParamFactor, bIsPrimaryAttack, eAttackToTarget, i_PvPBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - i_PvPBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	if(g_pFieldGlobal->IsArenaServer()

		// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		// 기존
		//&& INFINITY_STATE_PLAYING == this->m_InfinityPlayingInfo.InfinityState) {

		// 수정
		&& TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState) ) {
		// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		
		// 아레나 서버에서 인피니티 중이라면 기본무기 최소 공격력 보정
		if(o_pAttParam->fAttack < this->m_InfinityPlayingInfo.RevisionStandardWeapon) {
			o_pAttParam->fAttack = this->m_InfinityPlayingInfo.RevisionStandardWeapon;
		}
		if(o_pAttParam->fMaxAttack < this->m_InfinityPlayingInfo.RevisionStandardWeapon) {
			o_pAttParam->fMaxAttack = this->m_InfinityPlayingInfo.RevisionStandardWeapon;
		}
	}

	m_CurrentAttackItemNum	= i_pWeaponItemInfo->ItemNum;					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnDoMinutelyWorkByTimerManager(void)
/// \brief		
/// \author		cmkwon
/// \date		2007-06-13 ~ 2007-06-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnDoMinutelyWorkByTimerManager(void)
{
	int nLangTy = g_pFieldGlobal->GetLanguageType();

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-13 by cmkwon, 예당 7월 PC방 프로모션(콩이벤트 구현) - 콩아이템지급
	if(LANGUAGE_TYPE_KOREAN == nLangTy
		&& this->m_bIsPCBangClient)
	{
		int nCurCnts = this->GetPCBangTotalPlayTimeInSeconds()/TERM_30MINUTES_BY_SECOND;		// 2007-06-28 by cmkwon, 예당 7월 PC방 콩이벤트 지급 시간 수정 - 1시간에서 30분으로 수정
		if(nCurCnts > this->m_nInsertPCBangEventItemLastCounts)
		{// 콩 이벤트 아이템 지급

			this->m_nInsertPCBangEventItemLastCounts = nCurCnts;		// 2007-06-28 by cmkwon, 예당 7월 PC방 콩이벤트 지급 시간 수정

			// 2007-06-19 by cmkwon, 콩아이템으로 변경, 
// 2007-10-09 by dhjin, 콩 이벤트 종료  2007-06-19 by cmkwon, 7월5일 정기 점검때 업데이트예정
//			m_ItemManager.InsertItemBaseByItemNum(7004560, 1, IUT_GIVEEVENTITEM);
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-28 by cmkwon, 중국 방심취관련(게임 시간 알림 구현) - 미성년만 체크
	if(LANGUAGE_TYPE_CHINESE == nLangTy
		&& FALSE == this->IsAdultsUser())
	{
		DWORD dwCurTick = timeGetTime();
		if(TERM_10MINUTES_BY_MILLISECOND < dwCurTick-m_dwSendPlayTimeInfoLastTick)
		{
			int nGameContinueMinutesOfToday = this->GetCurGameContinueTimeInSecondOfToday()/60;
			if(30 > nGameContinueMinutesOfToday)
			{// 30분미만 - 아무런 처리 없음
			}
			else if(TERM_GAME_PLAYTIME_LIMIT_FIRST_SEC/60+1 >= nGameContinueMinutesOfToday)
			{// 181분 이하
				
				// 1시간에 1번씩 경고 - 1:00, 2:00, 3:00
				if(TERM_GAME_PLAYTIME_LIMIT_FIRST_SEC/60 <= nGameContinueMinutesOfToday)
				{
					m_dwSendPlayTimeInfoLastTick		= dwCurTick;
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_070628_0001, nGameContinueMinutesOfToday/60);
				}
				else if(1 >= nGameContinueMinutesOfToday%60)
				{
					m_dwSendPlayTimeInfoLastTick		= dwCurTick;
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_070628_0000, nGameContinueMinutesOfToday/60);
				}
			}
			else if(TERM_GAME_PLAYTIME_LIMIT_LAST_SEC/60 > nGameContinueMinutesOfToday)
			{// 300분 미만
				
				// 30분에 1번씩 경고 - 3:30, 4:00, 4:30
				if(1 >= nGameContinueMinutesOfToday%30)
				{
					m_dwSendPlayTimeInfoLastTick		= dwCurTick;
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_070628_0002);
				}
			}
			else
			{// 300분 이상

				// 15분에 1번씩 경고 - 5:00, 5:15, 5:30, 5:45, ...
				if(1 >= nGameContinueMinutesOfToday%15)
				{
					m_dwSendPlayTimeInfoLastTick		= dwCurTick;
					this->SendString128(STRING_128_USER_NOTICE, STRMSG_070628_0003);
				}
			}
		}
	}

	// 2007-12-06 by cmkwon, 시간제한 퀘스트 서버에서 시간 체크하게 수정 -
	this->CheckSuccessProgressQuestByTimeLimited();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::WPAddWarPoint(INT i_nAddWarPoint, INT i_bEventBonus, BOOL i_bSend2Client/*=TRUE*/, BYTE i_byWPUpdateTy/*=WPUT_GENERAL*/)
/// \brief		// 2007-06-14 by cmkwon, 세력전 보상 수정 -
///				// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldIOCPSocket::WPAddWarPoint()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
/// \author		cmkwon
/// \date		2007-06-14 ~ 2007-06-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::WPAddWarPoint(INT i_nAddWarPoint, INT i_bEventBonus, BOOL i_bSend2Client/*=TRUE*/, BYTE i_byWPUpdateTy/*=WPUT_GENERAL*/)
{
	//////////////////////////////////////////////////////////////////////////
	// 2007-09-14 by dhjin, WarPoint 값 계산 함수 추가
	// 2013-11-25 by jhseol&bckim, 거래소 - 거래소에서 획득하는 아닌경우가 아닐때만 WP획득량 증가 이벤트 확인
	if ( WPUT_MARKET != i_byWPUpdateTy )
	{
		i_nAddWarPoint = this->CalcWarPoint(i_nAddWarPoint, i_bEventBonus);
	}
	// end 2013-11-25 by jhseol&bckim, 거래소 - 거래소에서 획득하는 아닌경우가 아닐때만 WP획득량 증가 이벤트 확인

	this->m_character.WarPoint				+= i_nAddWarPoint;
	this->m_character.CumulativeWarPoint	+= i_nAddWarPoint;
	
	// start 2012-01-16 by hskim, 통계 - 화패
	if( NULL != ms_pFieldIOCP->m_pStatisticsManager )
	{
		ms_pFieldIOCP->m_pStatisticsManager->Add(STATISTICS_WAR_POINT, i_nAddWarPoint);
	}
	// end 2012-01-16 by hskim, 통계 - 화패

	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CAtumLogSender::SendLogMessageGetWarPoint()에 인자(, BYTE i_byWPUpdateTy) 추가
	CAtumLogSender::SendLogMessageGetWarPoint(this, i_nAddWarPoint, this->m_character.WarPoint, this->m_character.CumulativeWarPoint, i_byWPUpdateTy);
	// 2007-05-16 by dhjin, DB에 업데이트
	QPARAM_UPDATE_WARPOINT *pQparam = new QPARAM_UPDATE_WARPOINT;
	pQparam->CharacterUID		= this->m_character.CharacterUniqueNumber;
	pQparam->AccountUID			= this->m_character.AccountUniqueNumber;
	pQparam->TotalWarPoint		= this->m_character.WarPoint;
	pQparam->CumulativeWarPoint	= this->m_character.CumulativeWarPoint;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateWarPoint, this, this->m_character.AccountUniqueNumber, pQparam);

	if(i_bSend2Client)
	{
		// 2007-05-16 by dhjin, 클라이언트에게 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_PAY_WARPOINT, T_FC_CHARACTER_PAY_WARPOINT, pMsg, SendBuf);
		pMsg->WarPoint				= i_nAddWarPoint;
		pMsg->TotalWarPoint			= this->m_character.WarPoint;
		pMsg->CumulativeWarPoint	= this->m_character.CumulativeWarPoint;
		pMsg->UseItemFlag			= FALSE;		// 2010-08-27 by shcho&&jskim, WARPOINT 증가 아이템 구현 - 아이템 사용 구분자
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_PAY_WARPOINT));
	}
	
	// 2014-03-20 by jekim, GLog 워포통계
#if defined(TEST140)
	if(1)
#else
	if(!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
#endif
	{
		MSG_FL_LOG_ITEM LogItemParameter;
		MEMSET_ZERO(&LogItemParameter, sizeof(LogItemParameter));
		LogItemParameter.LogType			= GLOG_IL_LT_WARPOINT_ADD; 
		LogItemParameter.Count1				= (UID64_t)i_nAddWarPoint;
		LogItemParameter.Count2				= (UID64_t)this->m_character.WarPoint;
		LogItemParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
		LogItemParameter.CharLv				= (int)m_character.Level;
		LogItemParameter.GameServerID		= g_pFieldGlobal->GetMGameServerID();
		CAtumLogSender::SendLogItem(&LogItemParameter);
	}
	// end 2014-03-20 by jekim, GLog 워포통계
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::WatchReady()
/// \brief		관전 시작 전에 준비 사항.
/// \author		dhjin
/// \date		2007-06-15 ~ 2007-06-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::WatchReady()
{
	// 2007-06-15 by dhjin, 아레나 방 관전 리스트에 추가 한다.
	if(FALSE == this->ms_pFieldIOCP->m_ArenaManager.InsertWatchUserListW(this, this->m_pCurrentFieldMapChannel->GetMapChannelIndex()))
	{
		SendString128(STRING_128_ADMIN_CMD, STRMSG_070615_0001);
		return;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_WATCH_READY, T_FC_ARENA_WATCH_READY, pMsg, SendBuf);
	pMsg->ArenaState		= this->m_ArenaInfo.State;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_ARENA_WATCH_READY));

	// 2007-06-15 by dhjin, 아레나 방이 게임을 시작한 상태이면 아레나 방의 모든 유저들의 정보를 전송한다.
	if(TRUE == this->m_ArenaInfo.WatchState
		&& ARENA_STATE_FIGHTING_WARING == this->m_ArenaInfo.State)
	{
		this->ms_pFieldIOCP->m_ArenaManager.SendWatchUserATRoomInfo(this, this->m_pCurrentFieldMapChannel->GetMapChannelIndex());
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::WatchEnd()
/// \brief		관전 종료 명령어 입력.
/// \author		dhjin
/// \date		2007-06-19 ~ 2007-06-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::WatchEnd()
{
	// 2007-06-19 by dhjin, 아레나 방 관전 리스트에서 삭제
	this->ms_pFieldIOCP->m_ArenaManager.DeleteWatchUserListW(this);

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InitTutorial(vectTutorial * i_pvectSTutorialCompleteInfo)
/// \brief		Tutorial 완료 정보를 셋팅한다.
/// \author		dhjin
/// \date		2007-07-06 ~ 2007-07-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InitTutorial(vectTutorial * i_pvectSTutorialCompleteInfo)
{
	mt_auto_lock mta(&m_mtvectTutorialList);

	m_mtvectTutorialList.clear();
	STUTORIAL_LIST_INFO		tmTutorialListInfo;
	MEMSET_ZERO(&tmTutorialListInfo, sizeof(STUTORIAL_LIST_INFO));

	// 2007-07-06 by dhjin, Tutorial 정보를 DB정보 크기 만큼 만들면서 초기화 시킨다.
	vectSTutorialInfo::iterator itr(this->ms_pFieldIOCP->m_vectTutorial.begin());
	for(; itr != this->ms_pFieldIOCP->m_vectTutorial.end(); itr++)
	{
		tmTutorialListInfo.TutorialNum		= itr->TutorialUID;
		tmTutorialListInfo.TutorialComplete = FALSE;
		m_mtvectTutorialList.push_back(tmTutorialListInfo);
		MEMSET_ZERO(&tmTutorialListInfo, sizeof(STUTORIAL_LIST_INFO));
	}

	// 2007-07-06 by dhjin, Tutorial 완료 정보를 설정한다.
	mtvectTutorialList::iterator itrC(m_mtvectTutorialList.begin());
	for(; itrC != m_mtvectTutorialList.end(); itrC++)
	{
		vectTutorial::iterator itrF = find(i_pvectSTutorialCompleteInfo->begin(), i_pvectSTutorialCompleteInfo->end(), itrC->TutorialNum);
		if(itrF != i_pvectSTutorialCompleteInfo->end())
		{
			itrC->TutorialComplete = TRUE;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ITEM* CFieldIOCPSocket::GetTutorialWeaponInfo(BYTE i_byAttackType)
/// \brief		각 기어 튜토리얼 무기 셋팅
/// \author		dhjin
/// \date		2007-07-16 ~ 2007-07-16
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM* CFieldIOCPSocket::GetTutorialWeaponInfo(BYTE i_byAttackType)
{
	if (IS_AGEAR(m_character.UnitKind) 
		&& IS_PRIMARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(FIRST_WEAPON_AGEAR);
	}
	else if (IS_AGEAR(m_character.UnitKind) 
			&& IS_SECONDARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(SECOND_WEAPON_AGEAR);
	}
	if (IS_BGEAR(m_character.UnitKind) 
		&& IS_PRIMARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(FIRST_WEAPON_BGEAR);
	}
	else if (IS_BGEAR(m_character.UnitKind) 
			&& IS_SECONDARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(SECOND_WEAPON_BGEAR);
	}
	if (IS_MGEAR(m_character.UnitKind) 
		&& IS_PRIMARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(FIRST_WEAPON_MGEAR);
	}
	else if (IS_MGEAR(m_character.UnitKind) 
			&& IS_SECONDARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(SECOND_WEAPON_MGEAR);
	}
	if (IS_IGEAR(m_character.UnitKind) 
		&& IS_PRIMARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(FIRST_WEAPON_IGEAR);
	}
	else if (IS_IGEAR(m_character.UnitKind) 
			&& IS_SECONDARY_ATT_TYPE(i_byAttackType))
	{
		return this->ms_pFieldIOCP->GetItemInfo(SECOND_WEAPON_IGEAR);		
	}

	return	FALSE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			STUTORIAL_LIST_INFO *CFieldIOCPSocket::GetTutorialDataNoLock(INT i_nTutorialNum)
/// \brief		
/// \author		cmkwon
/// \date		2007-07-23 ~ 2007-07-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
STUTORIAL_LIST_INFO *CFieldIOCPSocket::GetTutorialDataNoLock(INT i_nTutorialNum)
{
	mtvectTutorialList::iterator itr(m_mtvectTutorialList.begin());
	for(; itr != m_mtvectTutorialList.end(); itr++)
	{
		if(i_nTutorialNum == itr->TutorialNum)
		{
			return itr;
		}
	}	
	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetExpediencyFundW(BYTE i_byInfluence, INT i_nSPICount)
/// \brief		판공비 업데이트 함수
/// \author		dhjin
/// \date		2007-08-27 ~ 2007-08-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetExpediencyFundW(BYTE i_byInfluence, INT i_nSPICount)
{
	ms_pFieldIOCP->m_CityLeader.SetExpediencyfund(i_byInfluence, i_nSPICount);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetSecondaryPassword(char *i_pSecPass)
/// \brief		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - CFieldIOCPSocket::SetSecondaryPassword() 함수 추가
/// \author		cmkwon
/// \date		2007-09-12 ~ 2007-09-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetSecondaryPassword(char *i_szSecPass)
{
	STRNCPY_MEMSET(m_szSecondaryPassword, i_szSecPass, SIZE_MAX_PASSWORD_MD5_STRING);
	if(FALSE == IsSettingSecondaryPassword())
	{// 2007-09-28 by cmkwon, NULL일경우 2차 패스워드 해제임
		m_bUnlockSecondaryPassword			= FALSE;
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsSettingSecondaryPassword(void)
/// \brief		// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 -
/// \author		cmkwon
/// \date		2007-09-13 ~ 2007-09-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsSettingSecondaryPassword(void)
{
	if(0 == strnicmp(m_szSecondaryPassword, "", SIZE_MAX_PASSWORD_MD5_STRING))
	{// 2007-09-13 by cmkwon, 패스워드가 설정되어 있지 않으면 FALSE를 리턴
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CompareSecondaryPassword(char *i_szSecPass)
/// \brief		
/// \author		cmkwon
/// \date		2007-09-13 ~ 2007-09-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CompareSecondaryPassword(char *i_szSecPass)
{
	if(FALSE == IsSettingSecondaryPassword())
	{// 2007-09-13 by cmkwon, 패스워드가 설정되어 있지 않으면 FALSE를 리턴
		return FALSE;
	}

	if(0 == strnicmp(m_szSecondaryPassword, i_szSecPass, SIZE_MAX_PASSWORD_MD5_STRING))
	{// 2007-09-13 by cmkwon, 2차패스워드가 동일하다
		return TRUE;
	}

	if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
	{// 2007-09-13 by cmkwon, 관리자/운영자가 아니면 FALSE를 리턴
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 관리자/운영자는 한가지 체크를 더 한다.
	char szEncodedString[SIZE_MAX_PASSWORD_MD5_STRING];		MEMSET_ZERO(szEncodedString, SIZE_MAX_PASSWORD_MD5_STRING);
	BYTE byPass[SIZE_MAX_PASSWORD_MD5];
	MD5 md5_instance;

	md5_instance.MD5Encode(m_szSecondaryPassword, byPass);
	MD5::MD5Binary2String(byPass, szEncodedString);

	if(0 == strnicmp(szEncodedString, i_szSecPass, SIZE_MAX_PASSWORD_MD5_STRING))
	{// 2007-09-13 by cmkwon, 2차패스워드가 동일하다
		return TRUE;
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckSecondaryPasswordLock(void)
/// \brief		// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 -
/// \author		cmkwon
/// \date		2007-09-13 ~ 2007-09-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckSecondaryPasswordLock(void)
{
	if(FALSE == g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag())
	{// 2007-09-13 by cmkwon, 시스템이 사용중이 아니면 항상 TRUE를 리턴
		return TRUE;
	}

	if(FALSE == this->IsSettingSecondaryPassword())
	{// 2007-09-13 by cmkwon, 2차패스워드가 설정되어 있지 않으면 항사 TRUE를 리턴
		return TRUE;
	}

	if(m_bUnlockSecondaryPassword)
	{// 2007-09-13 by cmkwon, 2차패스워드가 Unlock 상태이므로 TRUE를 리턴
		return TRUE;
	}

	// 2007-09-13 by cmkwon, 2차패스워드가 Lock 상태
	return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
/// \fn			INT	CFieldIOCPSocket::CalcWarPoint(INT i_nWarPoint, BOOL i_bEventBonus)
/// \brief		WarPoint 이벤트 적용 계산
/// \author		dhjin
/// \date		2007-09-14 ~ 2007-09-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
INT	CFieldIOCPSocket::CalcWarPoint(INT i_nWarPoint, BOOL i_bEventBonus)
{
	float fWarPointRate = 1.0f;
// 2010-04-01 by cmkwon, 해피아워이벤트의 WarPointEvnet를 모든상황에 적용 - 
// 	if(i_bEventBonus)
// 	{
// 		fWarPointRate = GetPlusWarPointRate();
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-01 by cmkwon, 해피아워이벤트의 WarPointEvnet를 모든상황에 적용 - 모든 상황에 이벤트 수치 적용(플래스 사용하지 않음)
	fWarPointRate = GetPlusWarPointRate();

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-17 by cmkwon, 멤버쉽 서비스 혜택 수정 - 워포인트(WarPoint) 두배
	if(this->m_ItemManager.IsExistPremiumCard())
	{
		fWarPointRate += 1.0f;
	}
	return (int)(i_nWarPoint*(int)(fWarPointRate*10000 + 1))/10000;				// 2014-08-27 by bckim, 세부오차 수정 

// 2007-11-02 by cmkwon, 워포인트 멤버쉬 유저 관련 버그 수정
//	if(i_bEventBonus)
//	{
//		i_nWarPoint = (INT)(i_nWarPoint * GetPlusWarPointRate());
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2007-09-17 by cmkwon, 멤버쉽 서비스 혜택 수정 - 워포인트(WarPoint) 두배
//	if(this->m_ItemManager.IsExistPremiumCard())
//	{
//		return 2*i_nWarPoint;
//	}
//
//	return i_nWarPoint;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GetPreServerAuthenticated(void)
/// \brief		// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - CFieldIOCPSocket::GetPreServerAuthenticated() 추가 함
/// \author		cmkwon
/// \date		2007-11-06 ~ 2007-11-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetPreServerAuthenticated(void)
{
	return m_bPreServerAuthenticated;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetPreServerAuthenticated(BOOL i_bFlag, BOOL i_bUpdateDB/*=FALSE*/)
/// \brief		// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - CFieldIOCPSocket::SetPreServerAuthenticated() 추가 함
/// \author		cmkwon
/// \date		2007-11-06 ~ 2007-11-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetPreServerAuthenticated(BOOL i_bFlag, BOOL i_bUpdateDB/*=FALSE*/)
{
	m_bPreServerAuthenticated = i_bFlag;

	if(FALSE == i_bUpdateDB
		|| FALSE == IS_VALID_UNIQUE_NUMBER(m_character.AccountUniqueNumber))
	{// 2007-11-06 by cmkwon, DB Update가 FALSE이면 여기에서 return
		return;
	}

	QPARAM_UPDATE_ConnectingServerGroupID *pQParam = new QPARAM_UPDATE_ConnectingServerGroupID;
	pQParam->AccountUID		= m_character.AccountUniqueNumber;
	pQParam->ServerGroupID	= 0;
	if(i_bFlag)
	{
		pQParam->ServerGroupID	= g_pFieldGlobal->GetMGameServerID();
	}

	// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - td_account 테이블에 Update 한다
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UPDATE_ConnectingServerGroupID, this, m_character.AccountUniqueNumber, pQParam);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnCheckGiveTarget(SGIVE_TARGET_CHARACTER *i_pGiveTargetCharacter)
/// \brief		// 2007-11-13 by cmkwon, 선물하기 기능 추가 - CFieldIOCPSocket::OnCheckGiveTarget() 추가
/// \author		cmkwon
/// \date		2007-11-13 ~ 2007-11-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnCheckGiveTarget(SGIVE_TARGET_CHARACTER *i_pGiveTargetCharacter)
{
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return;
	}

	if(m_character.InfluenceType != i_pGiveTargetCharacter->InfluenceType0)
	{
		this->SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, 300);
		return;
	}

	ITEM *pGiftItem = ms_pFieldIOCP->GetItemInfo(i_pGiveTargetCharacter->BuyItemNum);
	if(NULL == pGiftItem
		|| FALSE == COMPARE_BIT_FLAG(pGiftItem->ItemAttribute, ITEM_ATTR_CASH_ITEM))
	{// 2007-11-14 by cmkwon, 선물하기는 유료아이템만 가능하다
		this->SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_PROTOCOL_NO_SUCH_ITEM, 301, i_pGiveTargetCharacter->BuyItemNum);
		return;
	}

	if(ITEMKIND_COLOR_ITEM == pGiftItem->Kind
		|| CASH_ITEMKIND_COLOR_ITEM == pGiftItem->SummonMonster
// 2008-10-20 by cmkwon, 멥버쉽 아이템 체크 ItemAttribute 로 처리 - 
//		|| CASH_ITEMKIND_PREMIUM_CARD == pGiftItem->SummonMonster)
		|| COMPARE_BIT_FLAG(pGiftItem->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
	{// 2007-11-14 by cmkwon, 아머컬러아이템,멤버쉽은 선물하기 불가
		this->SendErrorMessage(T_FC_SHOP_CHECK_GIVE_TARGET, ERR_CANNOT_PUT_ITEM, 302, i_pGiveTargetCharacter->BuyItemNum);
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-14 by cmkwon, 멤버 변수에 할당 한다
	m_giveTargetCharacter = *i_pGiveTargetCharacter;	

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-14 by cmkwon, 검색된 결과를 유저에게 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FC_SHOP_CHECK_GIVE_TARGET_OK, T_FC_SHOP_CHECK_GIVE_TARGET_OK, pSMsg, SendBuf);
	STRNCPY_MEMSET(pSMsg->GiveTargetCharName, i_pGiveTargetCharacter->CharacterName0, SIZE_MAX_CHARACTER_NAME);
	pSMsg->GiveTargetCharUID	= i_pGiveTargetCharacter->CharacterUID0;
	STRNCPY_MEMSET(pSMsg->GiveTargetGuildName, i_pGiveTargetCharacter->GuildName0, SIZE_MAX_GUILD_NAME);
	pSMsg->GiveTargetLevel		= i_pGiveTargetCharacter->Level0;
	pSMsg->GiveTargetUnitKind	= i_pGiveTargetCharacter->UnitKind0;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_SHOP_CHECK_GIVE_TARGET_OK));
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::GiveItem(ITEM *i_pItem, int i_nCnts, BYTE i_nItemUpdateType)
/// \brief		// 2007-11-13 by cmkwon, 선물하기 기능 추가 - CFieldIOCPSocket::GivePremiumCard() 추가
/// \author		cmkwon
/// \date		2007-11-14 ~ 2007-11-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::GiveItem(ITEM *i_pItem, int i_nCnts, BYTE i_nItemUpdateType)
{
	if (FALSE == IS_GENERAL_ITEM(i_pItem->Kind))
	{
		return ERR_PROTOCOL_GENERAL_ITEM_ERROR;
	}

	if(IS_COUNTABLE_ITEM(i_pItem->Kind))
	{

// 2007-11-27 by cmkwon, 선물하기 로그 수정 - 아래와 같이 수정함
//		ITEM_GENERAL *pItemGeneral = (ITEM_GENERAL*)m_ItemManager.MakeNewItem(i_pItem->ItemNum, ITEM_IN_STORE, i_pItem);
//		pItemGeneral->AccountUniqueNumber	= m_giveTargetCharacter.AccountUID0;
//		pItemGeneral->Possess				= m_giveTargetCharacter.CharacterUID0;
//		pItemGeneral->ItemStorage			= ITEM_IN_STORE;
//		pItemGeneral->CurrentCount			= i_nCnts;
//
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GiveStoreItem, this, m_character.AccountUniqueNumber, pItemGeneral, NULL, i_nItemUpdateType);
		QPARAM_GiveStoreItem *pQParam = new QPARAM_GiveStoreItem;
		pQParam->SenderCharUID				= m_character.CharacterUniqueNumber;
		STRNCPY_MEMSET(pQParam->SenderCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		pQParam->itemG.AccountUniqueNumber	= m_giveTargetCharacter.AccountUID0;
		pQParam->itemG.Possess				= m_giveTargetCharacter.CharacterUID0;
		pQParam->itemG.ItemInfo				= i_pItem;
		pQParam->itemG.ItemNum				= i_pItem->ItemNum;
		pQParam->itemG.Kind					= i_pItem->Kind;
		pQParam->itemG.ItemStorage			= ITEM_IN_STORE;
		pQParam->itemG.CurrentCount			= i_nCnts;
		pQParam->itemG.ItemWindowIndex		= POS_INVALID_POSITION;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GiveStoreItem, this, m_character.AccountUniqueNumber, pQParam, NULL, i_nItemUpdateType);
	}
	else
	{
		for(int i=0; i < i_nCnts; i++)
		{
// 2007-11-27 by cmkwon, 선물하기 로그 수정 - 아래와 같이 수정함			
//			ITEM_GENERAL *pItemGeneral = (ITEM_GENERAL*)m_ItemManager.MakeNewItem(i_pItem->ItemNum, ITEM_IN_STORE, i_pItem);
//			pItemGeneral->AccountUniqueNumber	= m_giveTargetCharacter.AccountUID0;
//			pItemGeneral->Possess				= m_giveTargetCharacter.CharacterUID0;
//			pItemGeneral->ItemStorage			= ITEM_IN_STORE;
//			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GiveStoreItem, this, m_character.AccountUniqueNumber, pItemGeneral, NULL, i_nItemUpdateType);
			QPARAM_GiveStoreItem *pQParam = new QPARAM_GiveStoreItem;
			pQParam->SenderCharUID				= m_character.CharacterUniqueNumber;
			STRNCPY_MEMSET(pQParam->SenderCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
			pQParam->itemG.AccountUniqueNumber	= m_giveTargetCharacter.AccountUID0;
			pQParam->itemG.Possess				= m_giveTargetCharacter.CharacterUID0;
			pQParam->itemG.ItemInfo				= i_pItem;
			pQParam->itemG.ItemNum				= i_pItem->ItemNum;
			pQParam->itemG.Kind					= i_pItem->Kind;
			pQParam->itemG.ItemStorage			= ITEM_IN_STORE;
			pQParam->itemG.CurrentCount			= (IS_CHARGABLE_ITEM(i_pItem->Kind)) ? i_pItem->Charging : 1;
			pQParam->itemG.ItemWindowIndex		= POS_INVALID_POSITION;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GiveStoreItem, this, m_character.AccountUniqueNumber, pQParam, NULL, i_nItemUpdateType);
		}
	}

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnLoadNotifyMsg(mtvectSNOTIFY_MSG *i_pmtvectNotifyMsgList)
/// \brief		// 2007-11-28 by cmkwon, 통지시스템 구현 - CFieldIOCPSocket::OnLoadNotifyMsg() 추가
/// \author		cmkwon
/// \date		2007-11-28 ~ 2007-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnLoadNotifyMsg(mtvectSNOTIFY_MSG *i_pmtvectNotifyMsgList)
{
	if(i_pmtvectNotifyMsgList->empty()
		|| FALSE == this->IsValidCharacter(FALSE))
	{
		return;
	}

	mt_auto_lock mtA(&m_mtvectNotifyMsgList);
	m_mtvectNotifyMsgList.clearLock();

	m_mtvectNotifyMsgList.insert(m_mtvectNotifyMsgList.begin(), i_pmtvectNotifyMsgList->begin(), i_pmtvectNotifyMsgList->end());
	mtA.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-28 by cmkwon, Client 로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_NOTIFY_MSG_GET_OK, T_FC_EVENT_NOTIFY_MSG_GET_OK, pSMsg, SendBuf);
	for(int i=0; i < i_pmtvectNotifyMsgList->size(); i++)
	{
		SNOTIFY_MSG *pNotifyMsg = &((*i_pmtvectNotifyMsgList)[i]);
		pSMsg->NotifyMsgUID		= pNotifyMsg->NotifyMsgUID;
		pSMsg->CharacterUID		= pNotifyMsg->CharacterUID;
		pSMsg->NotifyMsgType	= pNotifyMsg->NotifyMsgType;
		STRNCPY_MEMSET(pSMsg->NotifyMsgString, pNotifyMsg->NotifyMsgString, SIZE_MAX_NOTIFY_MSG_STRING);

		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_NOTIFY_MSG_GET_OK));
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckDeleteNotifyMsg(SNOTIFY_MSG *o_pNotifyMsg, UID64_t i_notifyMsgUID)
/// \brief		// 2007-11-28 by cmkwon, 통지시스템 구현 -
/// \author		cmkwon
/// \date		2007-11-28 ~ 2007-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckDeleteNotifyMsg(SNOTIFY_MSG *o_pNotifyMsg, UID64_t i_notifyMsgUID)
{
	if(m_mtvectNotifyMsgList.empty())
	{
		return FALSE;
	}

	mt_auto_lock mtA(&m_mtvectNotifyMsgList);
	for(int i=0; i < m_mtvectNotifyMsgList.size(); i++)
	{
		if(i_notifyMsgUID == m_mtvectNotifyMsgList[i].NotifyMsgUID
			&& 0 != m_mtvectNotifyMsgList[i].CharacterUID)
		{
			*o_pNotifyMsg	= m_mtvectNotifyMsgList[i];
			return TRUE;
		}
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InsertNotifyMsg(SNOTIFY_MSG *o_pNotifyMsg)
/// \brief		// 2007-12-20 by cmkwon, 통지시스템 버그 수정 - 자신의 통지리스트에 통지 추가
/// \author		cmkwon
/// \date		2007-12-20 ~ 2007-12-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InsertNotifyMsg(SNOTIFY_MSG *o_pNotifyMsg)
{
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return;
	}

	mt_auto_lock mtA(&m_mtvectNotifyMsgList);
	
	m_mtvectNotifyMsgList.push_back(*o_pNotifyMsg);
	mtA.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_NOTIFY_MSG_GET_OK, T_FC_EVENT_NOTIFY_MSG_GET_OK, pSMsg, SendBuf);
	pSMsg->NotifyMsgUID		= o_pNotifyMsg->NotifyMsgUID;
	pSMsg->CharacterUID		= o_pNotifyMsg->CharacterUID;
	pSMsg->NotifyMsgType	= o_pNotifyMsg->NotifyMsgType;
	STRNCPY_MEMSET(pSMsg->NotifyMsgString, o_pNotifyMsg->NotifyMsgString, SIZE_MAX_NOTIFY_MSG_STRING);
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_NOTIFY_MSG_GET_OK));
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertNotifyMsg2Anyone(SNOTIFY_MSG *i_pNotifyMsg, CFieldIOCPSocket *i_pDoerFISoc)
/// \brief		
///				// 2007-12-20 by cmkwon, 통지시스템 버그 수정 - CFieldIOCPSocket::InsertNotifyMsg() 함수명 변경
/// \author		cmkwon
/// \date		2007-11-28 ~ 2007-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertNotifyMsg2Anyone(SNOTIFY_MSG *i_pNotifyMsg, CFieldIOCPSocket *i_pDoerFISoc)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-28 by cmkwon, 모든 통보메시지는 DB 에 저장한다.
	UID32_t accUID = 0;
	if(i_pDoerFISoc
		&& i_pDoerFISoc->IsValidCharacter(FALSE))
	{
		accUID = i_pDoerFISoc->GetCharacter()->AccountUniqueNumber;
	}
	SNOTIFY_MSG *pQParam = new SNOTIFY_MSG;
	*pQParam = *i_pNotifyMsg;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertNotifyMsg, i_pDoerFISoc, accUID, pQParam);
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::FindCouponEvent(int i_nItemEventUID)
/// \brief		// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - CFieldIOCPSocket::FindCouponEvent() 추가
/// \author		cmkwon
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::FindCouponEvent(int i_nItemEventUID)
{
	mt_auto_lock mtA(&m_mtvectCouponEventList);
	if(m_mtvectCouponEventList.empty())
	{
		return FALSE;
	}
	mtvectQPARAM_CHECK_EVENTITEM::iterator itr = m_mtvectCouponEventList.begin();
	for(; itr != m_mtvectCouponEventList.end(); itr++)
	{
		QPARAM_CHECK_EVENTITEM *pCouponEv = itr;
		if(pCouponEv->ItemEventUID == i_nItemEventUID)
		{
			return TRUE;
		}
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::PopCouponEvent(QPARAM_CHECK_EVENTITEM *o_pCouponEventInfo, int i_nItemEventUID)
/// \brief		// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - CFieldIOCPSocket::PopCouponEvent() 추가
/// \author		cmkwon
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::PopCouponEvent(QPARAM_CHECK_EVENTITEM *o_pCouponEventInfo, int i_nItemEventUID)
{
	mt_auto_lock mtA(&m_mtvectCouponEventList);
	if(m_mtvectCouponEventList.empty())
	{
		return FALSE;
	}
	mtvectQPARAM_CHECK_EVENTITEM::iterator itr = m_mtvectCouponEventList.begin();
	for(; itr != m_mtvectCouponEventList.end(); itr++)
	{
		QPARAM_CHECK_EVENTITEM *pCouponEv = itr;
		if(pCouponEv->ItemEventUID == i_nItemEventUID)
		{
			if(o_pCouponEventInfo)
			{
				*o_pCouponEventInfo = *pCouponEv;
			}
			itr = m_mtvectCouponEventList.erase(itr);	// 2008-01-10 by cmkwon, 제거한다.
			return TRUE;
		}
	}
	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::AddCouponEvent(QPARAM_CHECK_EVENTITEM *i_pCouponEventInfo)
/// \brief		// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - CFieldIOCPSocket::AddCouponEvent() 추가
/// \author		cmkwon
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::AddCouponEvent(QPARAM_CHECK_EVENTITEM *i_pCouponEventInfo)
{
	if(FALSE == this->IsValidCharacter(FALSE)){					return FALSE;}

	mt_auto_lock mtA(&m_mtvectCouponEventList);

	if(this->FindCouponEvent(i_pCouponEventInfo->ItemEventUID))
	{// 2008-01-10 by cmkwon, ItemEventUID 가 중복인지 체크
		return FALSE;
	}

	m_mtvectCouponEventList.push_back(*i_pCouponEventInfo);	// 2008-01-10 by cmkwon, 가능한 쿠폰 이벤트 리스트에 추가

	mtA.auto_unlock_cancel();				// 2008-01-10 by cmkwon, Lock 해제

	// 2008-01-10 by cmkwon, 클라이언트로 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_COUPON_EVENT_INFO, T_FC_EVENT_COUPON_EVENT_INFO, pSCouponEv, SendBuf);
	pSCouponEv->ItemEventUID		= i_pCouponEventInfo->ItemEventUID;
	pSCouponEv->ItemEventType		= i_pCouponEventInfo->ItemEventType;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_COUPON_EVENT_INFO));
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendCouponEvent()
/// \brief		아레나 통합 - 쿠폰 정보 전송 
/// \author		dhjin
/// \date		2008-04-28 ~ 2008-04-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendCouponEvent()
{
	if(FALSE == this->IsValidCharacter(FALSE)){					return;}

	mt_auto_lock mtA(&m_mtvectCouponEventList);
	
	mtvectQPARAM_CHECK_EVENTITEM::iterator itr = m_mtvectCouponEventList.begin();
	for(; itr != m_mtvectCouponEventList.end(); itr++)
	{
		// 2008-01-10 by cmkwon, 클라이언트로 정보 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_COUPON_EVENT_INFO, T_FC_EVENT_COUPON_EVENT_INFO, pSCouponEv, SendBuf);
		pSCouponEv->ItemEventUID		= itr->ItemEventUID;
		pSCouponEv->ItemEventType		= itr->ItemEventType;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_COUPON_EVENT_INFO));
	}

}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 2007-12-27 by dhjin, 아레나 통합 -

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SendMFSArenaStateChange(BYTE i_byArenaState)
/// \brief		아레나 통합 - 필드서버에 아레나 상태값 변경, 아레나 서버에서 호출
/// \author		dhjin
/// \date		2008-01-03 ~ 2008-01-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SendMFSArenaStateChange(BYTE i_byArenaState)
{
	INIT_MSG_WITH_BUFFER(MSG_FtoA_ARENA_STATE_CHANGE, T_FtoA_ARENA_STATE_CHANGE, pSendMsg, SendBuf);;
	pSendMsg->MFSClientIndex	= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pSendMsg->MFSCharacterUID	= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pSendMsg->AccountUID		= this->m_character.AccountUniqueNumber;
	pSendMsg->AFSClientIndex	= this->m_character.ClientIndex;
	pSendMsg->AFSArenaState		= i_byArenaState;

	CIOCPSocket	*	MFSSock;
	MFSSock = ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == MFSSock)
	{// 2007-12-28 by dhjin, 필드 서버에 대한 정보가 없으면 오류
		SendErrorMessage(T_FC_CONNECT_ARENASERVER_LOGIN, ERR_NO_SUCH_FIELDSERVER);
		return FALSE;
	}
	
	MFSSock->SendAddData(SendBuf, MSG_SIZE(MSG_FtoA_ARENA_STATE_CHANGE));
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::JobBeforeArenaPlay()
/// \brief		아레나 통합 - 아레나 대전을 위해 필드서버에서 해야되는 일, 메인 서버에서 호출 
/// \author		dhjin
/// \date		2008-01-04 ~ 2008-01-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::JobBeforeArenaPlay()
{
	BYTE						SendBuf[SIZE_MAX_PACKET];
	MSG_FN_CLIENT_GAMEEND_OK	*pSendClientGameEndOK = NULL;	

	// PK중이었다면, PK Reset 처리
	if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
		OnP2PPKEnd(pPeerPKSocket, this);
	}

	// 파티전 결과 처리
	if (this->IsPartyBattleState())
	{
		OnPartyBattleMemberDead(TRUE);
	}

	if (COMPARE_BODYCON_BIT(this->m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		this->CharacterDeadGameStartRoutine(TRUE, this->m_character.HP, this->m_character.DP);	
		QPARAM_CHARACTER_CHANGE_BODYCONDITION *pQBodyCondition = new QPARAM_CHARACTER_CHANGE_BODYCONDITION;
		pQBodyCondition->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQBodyCondition->BodyCondition			= m_character.BodyCondition;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeBodyCondition, this, m_character.AccountUniqueNumber, pQBodyCondition);
	}

	// 파티원이면 파티원 리스트에서 삭제
	CFieldParty *ptmFParty = m_pFieldParty;
	if ( NULL != ptmFParty)
	{		
		mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);
		mt_auto_lock pmlock(&ptmFParty->m_ListPartyMember);		// lock m_ListPartyMember
			
		// 파티원들에게 GAMEEND 전송
//		ptmFParty->SendMsgToMembersMap(pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK), m_pCurrentFieldMapChannel, m_character.CharacterUniqueNumber);
			
		FieldPartyMember tmpMember;
		if (ptmFParty->DeleteByCharacterUniqueNumber(m_character.CharacterUniqueNumber, tmpMember))
		{
			// 성공적으로 지워진 경우
// 2007-09-14 by cmkwon, 필요 없어서 주석 처리함
//			assert(this == tmpMember.PM_CharacterSocket);
		}
		else
		{
			// 이러면 안 되는데...
			g_pFieldGlobal->WriteSystemLogEX(TRUE, STRMSG_S_F2NOTIFY_0132, GetCharacterString(&m_character, string()));
		}
		
		// 파티원이 없어지면 삭제
		if (ptmFParty->empty())
		{
			ms_pFieldIOCP->m_MapParties.deleteLock(ptmFParty->m_PartyID);
			pmlock.auto_unlock_cancel();
			ms_pFieldIOCP->DeleteFieldParty(ptmFParty);			
		}
	}
	m_pFieldParty = NULL;

	///////////////////////////////////////////////////////////////////////////
	// 거래 reset하기
	if (m_peerTraderCharacterUniqueNumber != INVALID_UNIQUE_NUMBER)
	{
		CFieldIOCPSocket *pPeerTraderSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
		if (NULL != pPeerTraderSocket)
		{
			INIT_MSG(MSG_FC_TRADE_CANCEL_TRADE_OK, T_FC_TRADE_CANCEL_TRADE_OK, msgCancelTradeOK, SendBuf);
			msgCancelTradeOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			pPeerTraderSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_TRADE_CANCEL_TRADE_OK));

			pPeerTraderSocket->m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
			pPeerTraderSocket->m_bOKTradeChecked = FALSE;
			pPeerTraderSocket->m_mapTradeItem.clearLock();
		}
		m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
		m_bOKTradeChecked = FALSE;
		m_mapTradeItem.clearLock();
	}

	// 뿌려놓은 마인 지우기
	ClearAllCharacterMines();

	if (m_pCurrentFieldMapChannel != NULL)
	{
		///////////////////////////////////////////////////////////////////////////
		// NPC Server에 GameEndOK 메세지를 전송한다.
		INIT_MSG(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, SendBuf);
		pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));
	}

	///////////////////////////////////////////////////////////////////////////
	// 자신과 주위의 캐릭터에게 GameEndOK 메세지를 전송한다.
//	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(this->GetClientArrayIndex(), pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK)
//		, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

	///////////////////////////////////////////////////////////////////////////
	// 자신의 정보를 맵 Block에서 삭제 한다.
	if (m_pCurrentFieldMapChannel != NULL)
	{
		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
		{
			char szTemp[256];
			sprintf(szTemp, "[Error] DeleteBlockPosition_3 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f) \r\n"
				, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
				, m_character.PositionVector.x, m_character.PositionVector.z);
			DBGOUT(szTemp);
			g_pFieldGlobal->WriteSystemLog(szTemp);
		}
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다
	this->DeleteMeFromMonsterAttackedList();
	
	this->m_ItemManager.AllDetachTimeLimitItem();
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리, 아레나 서버로 가기전에 유저 정보 DB저장한다. CharacterSaveCriticalData()에서 StoreTimeStampUsingTimeLimitedIteList()호출 하므로 주석처리한다.
//	this->m_ItemManager.StoreTimeStampUsingTimeLimitedIteList();
	CharacterSaveCriticalData();

	this->ResetAllSkill();
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	this->m_SkillManager.ResetDebuffSkill();
	this->m_SkillManager.ResetDotSkill();
	
	this->GameEndAllInvokingEquipItem();									// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템

	// 2008-09-08 by dhjin, 아레나 통합 - 타이머 종료
	m_TimerManager.ResetTimerData();

	this->m_bMissionMaster = FALSE;		// 2008-12-16 by dhjin, 미션마스터

	this->SetClientState(CS_ARENASERVER_PLAYING);		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - CS_ARENA_PLAYING => CS_ARENASERVER_PLAYING 변경

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENACHECK] JobBeforeArenaPlay ArenaCUID = %d, CUID = %d, AUID = %d\r\n"
//		, 0, this->m_character.CharacterUniqueNumber, this->m_character.AccountUniqueNumber);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SetDataReadyArenaGameStart()
/// \brief		아레나 통합 - 아레나 시작 전 CFieldIOCPSocket에 설정 해야되는 값 처리, 클라이언트 시작 도와줌 , 아레나 서버에서 호출
/// \author		dhjin
/// \date		2008-01-31 ~ 2008-01-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetDataReadyArenaGameStart()
{
	CMTAutoCriticalSection mtAuto(m_mtCritSecForGameEndRoutine.GetCriticalSectionPtr());

	// 각종 flag 및 변수 초기화
	m_bFlagDBStore				= TRUE;
	m_bFieldServerChangeFlag	= FALSE;
	m_dwLastTickSpeedHackCheck = timeGetTime();

	// 2008-01-16 by dhjin, 유저의 세력을 아레나 시합동안 임의로 변경한다.
	if(FALSE == this->m_ArenaInfo.Command)
	{
		m_character.InfluenceType	= this->ms_pFieldIOCP->m_ArenaManager.GetTeamArenaInflW(this->m_ArenaInfo.TeamNum);
		// 2008-12-04 by dhjin, ArenaIMServer로 임시세력 전송 안되던 버그 수정.
		INIT_MSG_WITH_BUFFER(MSG_FI_CHARACTER_CHANGE_INFLUENCE_TYPE, T_FI_CHARACTER_CHANGE_INFLUENCE_TYPE, pS2IInfluence, SendBuf);
		pS2IInfluence->CharacterUID		= m_character.CharacterUniqueNumber;
		pS2IInfluence->InfluenceType0	= m_character.InfluenceType;
		ms_pFieldIOCP->Send2IMServer(SendBuf, MSG_SIZE(MSG_FI_CHARACTER_CHANGE_INFLUENCE_TYPE));
	}
	
	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 여기에서 초기화를 한다.
	m_WeaponIndexGenerator.Reset();			

	if(COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
	{// 관리자/운영자는 투명상태, 스텔스모드, 무적상태로 시작됨
		m_bIsInvisibleCharacter	= TRUE;
		m_bStealthState			= TRUE;
		m_bNoDamage				= TRUE;
	}
	else
	{// 2008-04-16 by dhjin, 일반 유저 무적되는 버그 수정
		m_bIsInvisibleCharacter	= FALSE;
		m_bStealthState			= FALSE;
		m_bNoDamage				= FALSE;
	}

	// 스트링128 출력 level 결정
	if (COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR))
	{
		m_STRING_128_print_level = STRING_128_ADMIN_CMD;
	}
	
	// m_pCurrentFieldMapChannel 할당
	if(this->m_ArenaInfo.Command)
	{
		// 2008-01-11 by dhjin, 맵 할당
		CFieldMapChannel *pFMChann = this->GetCityFieldMapChannelPtr();
		if(NULL == pFMChann)
		{
			return FALSE;
		}
		m_character.MapChannelIndex	= pFMChann->GetMapChannelIndex();
		m_character.PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
		
		// 2008-01-11 by dhjin, 맵채널에 케릭터 추가
		// m_pCurrentFieldMapChannel 할당
		SetCurrentFieldMapChannel(GetFieldMapChannel(&m_character.MapChannelIndex, TRUE, TRUE));
		if (m_pCurrentFieldMapChannel == NULL)
		{
			// ERROR! All Channels Not Available
			DBGOUT("[%d] All Channel Unavailable: [%04d]\n", m_character.ClientIndex, m_character.MapChannelIndex.MapIndex);
			Close(0x1405D);
			return FALSE;
		}
	}
	else
	{
		MAP_CHANNEL_INDEX *	ArenaMapIndex = ms_pFieldIOCP->m_ArenaManager.GetArenaDeathMatchRoomMapInfo(this->m_ArenaInfo.DeathMatchRoomNum);
		SetCurrentFieldMapChannel(GetFieldMapChannel(ArenaMapIndex, TRUE, TRUE));
		if (m_pCurrentFieldMapChannel == NULL)
		{
			// ERROR! All Channels Not Available
			DBGOUT("[%d] All Channel Unavailable: [%04d]\n", m_character.ClientIndex, m_character.MapChannelIndex.MapIndex);
			Close(0x1405D);
			return FALSE;
		}
		int	nWarpObjectIndex	= this->GetFieldMapChannel(ArenaMapIndex)->GetWarpObjectIndexW(this->m_character.InfluenceType);
 		D3DXVECTOR3 v3 = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetRandomWarpPoint(nWarpObjectIndex);
		m_character.PositionVector	=	v3;

		// 2008-03-06 by dhjin, IM서버로 맵 정보를 전송한다.
		INIT_MSG_WITH_BUFFER(MSG_FI_EVENT_NOTIFY_WARP, T_FI_EVENT_NOTIFY_WARP, pNotifyWarp, pNotifyWarpBuf);
		pNotifyWarp->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pNotifyWarp->MapChannelIndex		= m_character.MapChannelIndex;
		pNotifyWarp->nNumOfTimer			= 0;
		ms_pFieldIOCP->m_pIMWinSocket->Write((char*)pNotifyWarpBuf, MSG_SIZE(MSG_FI_EVENT_NOTIFY_WARP));
	}

	
	// 시간을 전송
	time_t ltime;
	struct tm *today = NULL;
	time(&ltime);
	today = localtime(&ltime);
	INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_SYNC_TIME, T_FC_CONNECT_SYNC_TIME, pSyncTime, pSyncTimeBuf);
	pSyncTime->CurrentTime = (today->tm_hour%4)*3600 + today->tm_min*60 + today->tm_sec;	// 4시간 기준으로 지난 초
	SendAddData(pSyncTimeBuf, MSG_SIZE(MSG_FC_CONNECT_SYNC_TIME));

	m_character.CurrentHP = m_character.HP;
	m_character.CurrentDP = m_character.DP;
	m_character.CurrentSP = m_character.SP;
	m_character.CurrentEP = m_character.EP;

	///////////////////////////////////////////////////////////////////////////////////////////////////
	// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 업데이트
	/////////////////////////////////////////////////////////////////////
	/// 필요한 변수 생성
	ATUM_DATE_TIME	CurTime;		/// 현재 시간을 저장할 변수
	
	/////////////////////////////////////////////////////////////////////
	/// 변수 초기화
	MEMSET_ZERO(&CurTime, sizeof(ATUM_DATE_TIME));
	
	/////////////////////////////////////////////////////////////////////
	/// 서버기준으로 현재시간 설정
	CurTime.SetCurrentDateTime();

	/////////////////////////////////////////////////////////////////////
	/// 초기화 시간이 지났는지 확인
	if(m_character.ArenaPlayInfo.atimeLastPlayTime < m_character.ArenaPlayInfo.atimeResetTime)
	{
		m_character.ArenaPlayInfo.nPlayCount			= 1;
	}
	else
	{
		m_character.ArenaPlayInfo.nPlayCount++;
	}
	m_character.ArenaPlayInfo.atimeLastPlayTime = CurTime;
	// end 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 업데이트
	
	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_POSSIBLE_GAMESTART, T_FC_ARENA_POSSIBLE_GAMESTART, pCharacterSendMsg, CharacterSendBuf);
	memcpy(&pCharacterSendMsg->AFSCharacter, &this->m_character, sizeof(CHARACTER));	// set character	
	pCharacterSendMsg->MapWeather		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_Weather;
	STRNCPY_MEMSET(pCharacterSendMsg->ServerGroupName0, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);			
	STRNCPY_MEMSET(pCharacterSendMsg->MainORTestServerName, g_pFieldGlobal->GetMainORTestServerName(), SIZE_MAX_SERVER_NAME);	
	STRNCPY_MEMSET(pCharacterSendMsg->GamePublisher, g_pFieldGlobal->GetGamePublisherName(), SIZE_MAX_GAME_PUBLISHER_NAME);	
	pCharacterSendMsg->IsPCBangUser		= this->m_bIsPCBangClient;			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	this->SendAddData(CharacterSendBuf, MSG_SIZE(MSG_FC_ARENA_POSSIBLE_GAMESTART));

	this->ArenaPlayInfoUpdataToMF();	// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 업데이트 내용을 메인 필드서버에게 전달하기

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			인피 시작 전 CFieldIOCPSocket에 설정 해야되는 값 처리, 클라이언트 시작 도와줌
/// \brief		인피니티 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetDataReadyInfinityGameStart()
{
	CMTAutoCriticalSection mtAuto(m_mtCritSecForGameEndRoutine.GetCriticalSectionPtr());

	// 각종 flag 및 변수 초기화
	m_bFlagDBStore				= TRUE;
	m_bFieldServerChangeFlag	= FALSE;
	m_dwLastTickSpeedHackCheck = timeGetTime();

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 여기에서 초기화를 한다.
	m_WeaponIndexGenerator.Reset();			

	if(COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
	{// 관리자/운영자는 투명상태, 스텔스모드, 무적상태로 시작됨
		m_bIsInvisibleCharacter	= TRUE;
		m_bStealthState			= TRUE;
		m_bNoDamage				= TRUE;
	}
	else
	{// 2008-04-16 by dhjin, 일반 유저 무적되는 버그 수정
		m_bIsInvisibleCharacter	= FALSE;
		m_bStealthState			= FALSE;
		m_bNoDamage				= FALSE;
	}

	// 스트링128 출력 level 결정
	if (COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR))
	{
		m_STRING_128_print_level = STRING_128_ADMIN_CMD;
	}
	
	// 시간을 전송
	time_t ltime;
	struct tm *today = NULL;
	time(&ltime);
	today = localtime(&ltime);
	INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_SYNC_TIME, T_FC_CONNECT_SYNC_TIME, pSyncTime, pSyncTimeBuf);
	pSyncTime->CurrentTime = (today->tm_hour%4)*3600 + today->tm_min*60 + today->tm_sec;	// 4시간 기준으로 지난 초
	SendAddData(pSyncTimeBuf, MSG_SIZE(MSG_FC_CONNECT_SYNC_TIME));

	// 레벨 보정 처리 구현 해야됨 
	REVISIONINFO RevisionInfo;
	MEMSET_ZERO(&RevisionInfo, sizeof(REVISIONINFO));
	if(this->ms_pFieldIOCP->m_InfinityManager.GetRevisionInfoW(&RevisionInfo, this->m_InfinityPlayingInfo.InfinityModeUID, this->m_character.UnitKind)) {
		if(RevisionInfo.RevisionLevel >= this->m_character.Level) {
			this->m_InfinityPlayingInfo.RevisionLevel			= RevisionInfo.RevisionLevel;
			if(this->m_character.HP < RevisionInfo.RevisionHP) {
				this->m_character.HP							= RevisionInfo.RevisionHP;
			}
			if(this->m_character.DP < RevisionInfo.RevisionDP) {
				this->m_character.DP							= RevisionInfo.RevisionDP;
			}
			this->m_InfinityPlayingInfo.RevisionHP				= RevisionInfo.RevisionHP;
			this->m_InfinityPlayingInfo.RevisionDP				= RevisionInfo.RevisionDP;
			this->m_InfinityPlayingInfo.RevisionStandardWeapon	= RevisionInfo.RevisionStandardWeapon;
			this->m_InfinityPlayingInfo.RevisionAdvancedWeapon	= RevisionInfo.RevisionAdvancedWeapon;
		}
	}

	m_character.CurrentHP = m_character.HP;
	m_character.CurrentDP = m_character.DP;
	m_character.CurrentSP = m_character.SP;
	m_character.CurrentEP = m_character.EP;

	m_character.MapChannelIndex.MapIndex	= this->m_InfinityPlayingInfo.MapIdx;
	//m_character.MapChannelIndex				= this->m_pCurrentFieldMapChannel->m_MapChannelIndex;	// 2013-05-23 by jhseol, 인피니티 입장 시 채널정보 누락 수정

	INIT_MSG_WITH_BUFFER(MSG_FC_ARENA_POSSIBLE_GAMESTART, T_FC_ARENA_POSSIBLE_GAMESTART, pCharacterSendMsg, CharacterSendBuf);
	memcpy(&pCharacterSendMsg->AFSCharacter, &this->m_character, sizeof(CHARACTER));	// set character	
	pCharacterSendMsg->MapWeather		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_Weather;
	STRNCPY_MEMSET(pCharacterSendMsg->ServerGroupName0, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);			
	STRNCPY_MEMSET(pCharacterSendMsg->MainORTestServerName, g_pFieldGlobal->GetMainORTestServerName(), SIZE_MAX_SERVER_NAME);	
	STRNCPY_MEMSET(pCharacterSendMsg->GamePublisher, g_pFieldGlobal->GetGamePublisherName(), SIZE_MAX_GAME_PUBLISHER_NAME);	
	pCharacterSendMsg->IsPCBangUser		= this->m_bIsPCBangClient;			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
	this->SendAddData(CharacterSendBuf, MSG_SIZE(MSG_FC_ARENA_POSSIBLE_GAMESTART));

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::SetDataReadyInfinityGameStart# ! %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()));

	return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SetDataArenaGameStart()
/// \brief		아레나 통합 - 아레나 시작 전 CFieldIOCPSocket에 설정 해야되는 값 처리 , 아레나 서버에서 호출
/// \author		dhjin
/// \date		2008-01-09 ~ 2008-01-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetDataArenaGameStart()
{
	BYTE SendBuf[SIZE_MAX_PACKET];
	MessageType_t msgType		= T_NA;
	
	// Set Initial Position
	if(FALSE == m_pCurrentFieldMapChannel->SetInitialPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
	{
		char szTemp[256];
		sprintf(szTemp, "[Error] SetInitialPosition_2 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f)\n"
			, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
			, m_character.PositionVector.x, m_character.PositionVector.z);
		DBGOUT(szTemp);
		g_pGlobal->WriteSystemLog(szTemp);
	}
	m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.insertLock(m_character.CharacterUniqueNumber, this);

	// start 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
	if( TRUE == m_pCurrentFieldMapChannel->IsEnableTriggerMapBuff() )
	{
		m_pCurrentFieldMapChannel->GetTriggerMapBuffManager()->SetMapBuff(m_character.CharacterUniqueNumber, this);
	}
	// end 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	m_character.CharacterMode	= FALSE;

	// NPC Server에 Character 의 GameStart 메세지를 전송한다.
	INIT_MSG(MSG_FN_CLIENT_GAMESTART_OK, T_FN_CLIENT_GAMESTART_OK, pSendClientGameStartOK, SendBuf);
	pSendClientGameStartOK->ChannelIndex			= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSendClientGameStartOK->ClientIndex				= m_character.ClientIndex;
	pSendClientGameStartOK->mexCharacter			= m_character;
	pSendClientGameStartOK->GuildMasterCharUID		= 0;
	pSendClientGameStartOK->bStealthState1			= TRUE;			// 기본적으로 스텔스 상태로 시작된다. 아이템이 로딩되고 정상적으로 설정됨
	pSendClientGameStartOK->bInvisible				= FALSE;		// 2006-11-27 by dhjin
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMESTART_OK));

	char szSystemLog[256];
	sprintf(szSystemLog, "  GameStartRoutine(%s) %s Map(%04d) Position(%4d, %4d, %4d) IP(%s)\r\n",
			GetProtocolTypeString(msgType), GetCharacterString(&m_character, string()),
			m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
			(int)m_character.PositionVector.y, (int)m_character.PositionVector.z,
			GetPeerIP());
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
	DBGOUT(szSystemLog);

	m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)
	
	// send MSG_FC_STORE_GET_ITEM to DB Manager
	MSG_FC_STORE_GET_ITEM *pGetItem = new MSG_FC_STORE_GET_ITEM;
	pGetItem->AccountUniqueNumber	= m_character.AccountUniqueNumber;
	pGetItem->PossessCharacter		= m_character.CharacterUniqueNumber;
	pGetItem->ItemStorage0			= ITEM_IN_CHARACTER;
	pGetItem->bSendToClient			= TRUE;
	pGetItem->bMainGameStartFlag	= FALSE;		// 2012-11-21 by hskim, GLog 3차 빠진 부분 추가 작업
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetStoreItem, this, m_character.AccountUniqueNumber, (MSG_FC_STORE_GET_ITEM*)pGetItem);

	this->ResetAllSkill();

	ms_pFieldIOCP->SendInRangeCharacterOtherInfo(this, m_pCurrentFieldMapChannel);

	this->GPInitGameStartTime();		// 2007-06-19 by cmkwon, 게임 지속 시간 수정 - 중국 5시간 후 접속 처리
	this->m_nGameStartTimeInSeconds		= ms_pFieldIOCP->GetCurrentServerTime();			// 2006-11-15 by cmkwon, CAtumLogSender::SendLogMessageGAMESTART()에 있던것을 이쪽을 옮김

	// 스텔스 설정
	if (COMPARE_RACE(m_character.Race, RACE_GUEST))
	{
		m_bIsInvisibleCharacter		= TRUE;
	}

//	// IM Server에 등록
//	INIT_MSG(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP, T_FI_CONNECT_NOTIFY_FIELDSERVER_IP, msgNotiryFieldIP, SendBuf);
//	msgNotiryFieldIP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
//	msgNotiryFieldIP->FieldServerID = ms_pFieldIOCP->m_FieldServerID;
//
//	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP));
//
//	// IM Server에 게임 시작을 알림
//	INIT_MSG(MSG_FI_CONNECT_NOTIFY_GAMESTART, T_FI_CONNECT_NOTIFY_GAMESTART, msgNotifyGameStart, SendBuf);
//	msgNotifyGameStart->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
//	msgNotifyGameStart->FieldGameStartType = GST_GAMESTART;
//	msgNotifyGameStart->MapChannelIndex = m_character.MapChannelIndex;
//
//	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_GAMESTART));

//	// Pre Server에 게임 시작을 알림
//	INIT_MSG(MSG_FP_EVENT_GAME_STARTED, T_FP_EVENT_GAME_STARTED, msgGameStarted, SendBuf);
//	STRNCPY_MEMSET(msgGameStarted->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
//	STRNCPY_MEMSET(msgGameStarted->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
//	msgGameStarted->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
//	msgGameStarted->MapChannelIndex = m_character.MapChannelIndex;
//	ms_pFieldIOCP->m_pPreWinSocket->Write(SendBuf, MSG_SIZE(MSG_FP_EVENT_GAME_STARTED));

	// Pre Server에도 알림
	INIT_MSG_WITH_BUFFER(MSG_FP_EVENT_MAP_CHANGED, T_FP_EVENT_MAP_CHANGED, msgMapChanged, msgMapChangedBuf);
	STRNCPY_MEMSET(msgMapChanged->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(msgMapChanged->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgMapChanged->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	msgMapChanged->MapChannelIndex			= m_character.MapChannelIndex;
	ms_pFieldIOCP->m_pPreWinSocket->Write(msgMapChangedBuf, MSG_SIZE(MSG_FP_EVENT_MAP_CHANGED));

	// 게임 시작 시간 저장, LastStartedTime 저장
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLastStartedTime, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber);

	// 첫 HP 정보 전송
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

	// 첫 회복용 Timer 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_DO_MINUTELY_WORK);

// 2009-03-31 by dhjin, 선전 포고 - 세력전 승리 시 지급 되는 이벤트 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-04-21 by cmkwon
//	SDB_INFLUENCE_WAR_INFO *pCurWarInfo = NULL;
//	if(ms_pFieldIOCP->m_InflWarManager.GetINFLUENCE_WAR_INFO_ByInflType(&pCurWarInfo, m_character.InfluenceType))
//	{
//		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
//		pSInflData->byInfluenceType		= pCurWarInfo->InfluenceType;
//		pSInflData->fHPRepairRate		= pCurWarInfo->HPRepairRate;
//		pSInflData->fDPRepairRate		= pCurWarInfo->DPRepairRate;
//		pSInflData->fSPRepairRate		= pCurWarInfo->SPRepairRate;
//		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
//	}
	CInflWarData *pInflWarData = ms_pFieldIOCP->m_InflWarManager.GetInflWarDataByInflType(m_character.InfluenceType);
	if(pInflWarData)
	{
		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
		pSInflData->byInfluenceType		= m_character.InfluenceType;
		pSInflData->fHPRepairRate		= pInflWarData->fInflHPRepairRate;
		pSInflData->fDPRepairRate		= pInflWarData->fInflDPRepairRate;
		pSInflData->fSPRepairRate		= pInflWarData->fInflSPRepairRate;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
	}

	// 디버그용, 지난 시간을 저장
	m_nOldTimeStampDBG = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			인피 시작 전 CFieldIOCPSocket에 설정 해야되는 값 처리
/// \brief		인피니티 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetDataInfinityGameStart() {
	BYTE SendBuf[SIZE_MAX_PACKET];
	MessageType_t msgType		= T_NA;
	
	m_character.CharacterMode	= FALSE;

	m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	// send MSG_FC_STORE_GET_ITEM to DB Manager
	MSG_FC_STORE_GET_ITEM *pGetItem = new MSG_FC_STORE_GET_ITEM;
	pGetItem->AccountUniqueNumber	= m_character.AccountUniqueNumber;
	pGetItem->PossessCharacter		= m_character.CharacterUniqueNumber;
	pGetItem->ItemStorage0			= ITEM_IN_CHARACTER;
	pGetItem->bSendToClient			= TRUE;
	pGetItem->bMainGameStartFlag	= FALSE;		// 2012-11-21 by hskim, GLog 3차 빠진 부분 추가 작업
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetStoreItem, this, m_character.AccountUniqueNumber, (MSG_FC_STORE_GET_ITEM*)pGetItem);

	this->ResetAllSkill();

	this->GPInitGameStartTime();		// 2007-06-19 by cmkwon, 게임 지속 시간 수정 - 중국 5시간 후 접속 처리
	this->m_nGameStartTimeInSeconds		= ms_pFieldIOCP->GetCurrentServerTime();			// 2006-11-15 by cmkwon, CAtumLogSender::SendLogMessageGAMESTART()에 있던것을 이쪽을 옮김

	// 스텔스 설정
	if (COMPARE_RACE(m_character.Race, RACE_GUEST))
	{
		m_bIsInvisibleCharacter		= TRUE;
	}

	// 게임 시작 시간 저장, LastStartedTime 저장
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLastStartedTime, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber);

	// 프리미엄 체크
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CashLoadPremiumCard, this, NULL, NULL);

	// 첫 HP 정보 전송
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

	// 첫 회복용 Timer 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_DO_MINUTELY_WORK);

	CInflWarData *pInflWarData = ms_pFieldIOCP->m_InflWarManager.GetInflWarDataByInflType(m_character.InfluenceType);
	if(pInflWarData)
	{
		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
		pSInflData->byInfluenceType		= m_character.InfluenceType;
		pSInflData->fHPRepairRate		= pInflWarData->fInflHPRepairRate;
		pSInflData->fDPRepairRate		= pInflWarData->fInflDPRepairRate;
		pSInflData->fSPRepairRate		= pInflWarData->fInflSPRepairRate;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
	}

	// 디버그용, 지난 시간을 저장
	m_nOldTimeStampDBG = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();	
	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendArenaCharacterPay(BYTE i_byIssue, INT i_nPayWarPoint)
/// \brief		아레나 통합 - 필드 서버로 보상 전송 , 아레나 서버에서 호출 
/// \author		dhjin
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendArenaCharacterPay(BYTE i_byIssue, INT i_nPayWarPoint)
{
	CIOCPSocket * MainFieldServer = ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == MainFieldServer)
	{
		return;
	}

	INIT_MSG_WITH_BUFFER(MSG_FtoA_ARENA_CHARACTER_PAY, T_FtoA_ARENA_CHARACTER_PAY, pPayMSG, PaySendBuf);
	pPayMSG->Issue				= i_byIssue;
	pPayMSG->PayWarPoint		= i_nPayWarPoint;
	pPayMSG->AccountUID			= this->m_character.AccountUniqueNumber;
	pPayMSG->MFSCharacterUID	= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pPayMSG->MFSClientIndex		= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pPayMSG->AFSClientIndex		= this->m_character.ClientIndex;
	MainFieldServer->SendAddData(PaySendBuf, MSG_SIZE(MSG_FtoA_ARENA_CHARACTER_PAY));
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendArenaCharacterDisConnect()
/// \brief		아레나 통합 - 필드 서버로 강제 종료 전송, 아레나 서버에서 호출 
/// \author		dhjin
/// \date		2008-01-15 ~ 2008-01-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////	
void CFieldIOCPSocket::SendArenaCharacterDisConnect()
{
	CIOCPSocket * MainFieldServer = ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == MainFieldServer)
	{
		return;
	}

	INIT_MSG_WITH_BUFFER(MSG_FtoA_ARENA_CHARACTER_DISCONNECT, T_FtoA_ARENA_CHARACTER_DISCONNECT, pSendMSG, SendBuf);
	pSendMSG->AccountUID			= this->m_character.AccountUniqueNumber;
	pSendMSG->MFSCharacterUID		= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pSendMSG->ArenaCharacterUID		= this->m_character.CharacterUniqueNumber;	// 2012-10-21 by jhseol, 아레나 버그수정 - 아레나 종료시 케릭터 정보 리셋.
	pSendMSG->MFSClientIndex		= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pSendMSG->AFSClientIndex		= this->m_character.ClientIndex;
	MainFieldServer->SendAddData(SendBuf, MSG_SIZE(MSG_FtoA_ARENA_CHARACTER_DISCONNECT));
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnCharacterReadyGameStartFromArenaToMainServer()
/// \brief		아레나 통합 - 아레나 종료 후 필드 서버 시작 처리, 클라이언트 시작 도와주기	, 메인서버에서 호출
/// \author		dhjin
/// \date		2008-01-31 ~ 2008-01-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnCharacterReadyGameStartFromArenaToMainServer()
{
	CMTAutoCriticalSection mtAuto(m_mtCritSecForGameEndRoutine.GetCriticalSectionPtr());

	this->SetClientState(CS_PLAYING);

	// 2008-01-11 by dhjin, 맵 할당
	CFieldMapChannel *pFMChann = this->GetCityFieldMapChannelPtr();
	if(NULL == pFMChann)
	{
		return;
	}
	m_character.MapChannelIndex	= pFMChann->GetMapChannelIndex();
	m_character.PositionVector	= pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition();
	
	// 2008-01-11 by dhjin, 맵채널에 케릭터 추가
	// m_pCurrentFieldMapChannel 할당
	SetCurrentFieldMapChannel(GetFieldMapChannel(&m_character.MapChannelIndex, TRUE, TRUE));
	if (m_pCurrentFieldMapChannel == NULL)
	{
		// ERROR! All Channels Not Available
		DBGOUT("[%d] All Channel Unavailable: [%04d]\n", m_character.ClientIndex, m_character.MapChannelIndex.MapIndex);
		Close(0x1405D);
		return;
	}

	// 2008-01-15 by dhjin, 아레나 종료 후에는 도시 맵에서 시작하므로 강제로 케릭터 모드를 설정한다.
	m_character.CharacterMode	= TRUE;
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER_OK, T_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER_OK, pCSendMsg, CSendBuf);
	pCSendMsg->CharacterMode0	= m_character.CharacterMode;
	pCSendMsg->bMemberPCBang	= m_bIsPCBangClient;
	pCSendMsg->MapWeather		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_Weather;	
	memcpy(&pCSendMsg->Character, &this->m_character, sizeof(CHARACTER));	// set character
	// 2008-09-08 by dhjin, 아레나 통합 - 클라이언트 퀘스트 시간 체크 오류 수정
	pCSendMsg->Character.TotalPlayTime	= this->GetTotalPlayTimeInSeconds();
	STRNCPY_MEMSET(pCSendMsg->ServerGroupName0, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);			
	STRNCPY_MEMSET(pCSendMsg->MainORTestServerName, g_pFieldGlobal->GetMainORTestServerName(), SIZE_MAX_SERVER_NAME);	
	STRNCPY_MEMSET(pCSendMsg->GamePublisher, g_pFieldGlobal->GetGamePublisherName(), SIZE_MAX_GAME_PUBLISHER_NAME);	

	///////////////////////////////////////////////////////////////////////////////
	// 2008-08-26 by cmkwon, 베트남 VTC-Intecom_Viet 2차 패스워드 시스템 버그 수정 - 아레나 이용 후 메인서버로 돌아 올때 2차 패스워드 플래그 전송
	// 2010-04-20 by cmkwon, 인피니티 2차 패스워드 버그 수정 - 2차패스워드 설정이 되어 있을때만 설정 정보 전달.
	if(this->IsSettingSecondaryPassword())
	{
		pCSendMsg->bIsLockSecondPW	= !this->m_bUnlockSecondaryPassword;
	}

	this->SendAddData(CSendBuf, MSG_SIZE(MSG_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER_OK));

	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼 - 인피 종료시 킬 카운트및 휴식 카운트 재전송
#ifdef S_BONUSEXPSYSTEM_RENEWAL
	SendToClient_RestCount();
#endif // S_BONUSEXPSYSTEM_RENEWAL
	// end 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼 - 인피 종료시 킬 카운트및 휴식 카운트 재전송

	// 2010-06-15 by shcho&hslee 펫시스템 - 인피 종료되면 펫 데이터 다시 전송
	SendPetItemList();			
	// END 2010-06-15 by shcho&hslee 펫시스템 - 인피 종료되면 펫 데이터 다시 전송

	// 2012-10-21 by jhseol, 아레나 버그수정 - 아레나 종료시 케릭터 정보 리셋.
	QPARAM_ARENA_CHARACTER_RESET *pArenaReset = new QPARAM_ARENA_CHARACTER_RESET;
	MEMSET_ZERO(pArenaReset, sizeof(pArenaReset));
	pArenaReset->AccountUID			= m_character.AccountUniqueNumber;
	pArenaReset->CharacterUID		= m_character.CharacterUniqueNumber;
	pArenaReset->ArenaCharacterUID	= m_nArenaCharacterUID;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaCharacterReset, NULL, 0, pArenaReset);
	m_nArenaCharacterUID = 0;	// 리셋 후 번호 초기화 - 이는 인피에서 복귀 했을때를 제외하기 위함이다.
	// end 2012-10-21 by jhseol, 아레나 버그수정 - 아레나 종료시 케릭터 정보 리셋.

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnCharacterGameStartFromArenaToMainServer()
/// \brief		아레나 통합 - 아레나 종료 후 필드 서버 시작 처리, 메인서버에서 호출
/// \author		dhjin
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnCharacterGameStartFromArenaToMainServer()
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-04 by cmkwon, 서버 다운 진행상태 체크
	if(ms_pFieldIOCP->m_bPrepareShutDown)
	{
		// 2008-06-05 by cmkwon, AdminTool, Monitor 접근 가능 IP를 server config file 에 설정하기 - 아래와 같이 수정 함
		//if(FALSE == IS_SCADMINTOOL_CONNECTABLE_IP(this->GetPeerIP())
		if(FALSE == g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP())	// 2008-06-05 by cmkwon, AdminTool, Monitor 접근 가능 IP를 server config file 에 설정하기 - 
			|| FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{// 2007-08-27 by cmkwon, 서버다운준비 상태에서 접속가능 IP 체크 - 관리자,운영자 접속 가능
			SendErrorMessage(T_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER, ERR_DOING_SERVER_SHUTDOWN);
			return;
		}
	}

	// Set Initial Position
	if(FALSE == m_pCurrentFieldMapChannel->SetInitialPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
	{
		char szTemp[256];
		sprintf(szTemp, "[Error] SetInitialPosition_2 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f)\n"
			, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
			, m_character.PositionVector.x, m_character.PositionVector.z);
		DBGOUT(szTemp);
		g_pGlobal->WriteSystemLog(szTemp);
	}
	m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.insertLock(m_character.CharacterUniqueNumber, this);

	// start 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
	if( TRUE == m_pCurrentFieldMapChannel->IsEnableTriggerMapBuff() )
	{
		m_pCurrentFieldMapChannel->GetTriggerMapBuffManager()->SetMapBuff(m_character.CharacterUniqueNumber, this);
	}
	// end 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	// 2008-01-11 by dhjin, NPC Server에 Character 의 GameStart 메세지를 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FN_CLIENT_GAMESTART_OK, T_FN_CLIENT_GAMESTART_OK, pSendClientGameStartOK, SendBuf);
	pSendClientGameStartOK->ChannelIndex			= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSendClientGameStartOK->ClientIndex				= m_character.ClientIndex;
	pSendClientGameStartOK->mexCharacter			= m_character;
	pSendClientGameStartOK->GuildMasterCharUID		= 0;
	pSendClientGameStartOK->bStealthState1			= TRUE;			// 기본적으로 스텔스 상태로 시작된다. 아이템이 로딩되고 정상적으로 설정됨
	pSendClientGameStartOK->bInvisible				= FALSE;		// 2006-11-27 by dhjin
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMESTART_OK));

	char szSystemLog[256];
	sprintf(szSystemLog, "  GameStartRoutineFromArena %s Map(%04d) Position(%4d, %4d, %4d) IP(%s)\r\n",
			GetCharacterString(&m_character, string()),
			m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
			(int)m_character.PositionVector.y, (int)m_character.PositionVector.z,
			GetPeerIP());
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
	DBGOUT(szSystemLog);

	// 2013-04-18 by jhseol,bckim 이달의 아머 - 아레나에서 메인서버 복귀시 이달의 아머 체크
#ifdef S_MONTHL_ARMOR_EVENT_JHSEOL_BCKIM		// 아레나에서 메인서버 복귀시 이달의 아머 체크
	if ( NULL != ms_pFieldIOCP->m_pMonthlyArmorManager )
	{
		mt_auto_lock mtAuto(&m_ItemManager.m_mapItemGeneral);
		mtmapUID2ItemGeneral::iterator itr = m_ItemManager.m_mapItemGeneral.begin();
		for(; itr != m_ItemManager.m_mapItemGeneral.end(); itr++) 
		{
			ITEM_GENERAL *pItemG = itr->second;
			m_ArmorCollection.CheckMonthlyArmorEvent(pItemG);	// 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경
		}
	}
#endif
	// end 2013-04-18 by jhseol,bckim 이달의 아머 - 아레나에서 메인서버 복귀시 이달의 아머 체크
	
	// 2008-01-11 by dhjin, 아이템, 스킬, 퀘스트 정보를 전송한다.
	this->SendCharacterItemList();
	this->SendSkillItemList();
	this->SendQuestList();

// 2010-03-10 by cmkwon, 인피에서 시간제한 액세서리 추가 관련 버그 수정 - 
// 	// 2008-03-04 by dhjin, 시간제 아이템 처리
// 	m_ItemManager.ResetTimeStampUsingTimeLimitedItemList(TRUE);
// 
// 	// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
// 	this->RearrangeCharacterTatalStat();
// 
// 	// 2009-09-09 ~ 2010-02-23 by dhjin, 인피니티 - 아이템 장착 동기화 수정.
// 	this->ResetAllSkillAndEnchant();
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-10 by cmkwon, 인피에서 시간제한 액세서리 추가 관련 버그 수정 - 
	MEMSET_ZERO(&m_UnitRenderInfo, sizeof(m_UnitRenderInfo));	// 2010-04-07 by cmkwon, 인피2차 추가 수정 - 
	this->InitCharacterInventoryItem(TRUE);
	this->InitRenderInfo();										// 2010-04-07 by cmkwon, 인피2차 추가 수정 - 

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 여기에서 초기화를 한다.
	m_WeaponIndexGenerator.Reset();			

	ms_pFieldIOCP->SendInRangeCharacterOtherInfo(this, m_pCurrentFieldMapChannel);

	// 주위에 있는 아이템의 정보를 얻어온다.
	SendDropItemsAroundPosition(m_character.PositionVector);

	// 스텔스 설정
	if (COMPARE_RACE(m_character.Race, RACE_GUEST))
	{
		m_bIsInvisibleCharacter		= TRUE;
	}

	// 첫 exp 정보를 전송한다
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_EXP);

	// 첫 HP 정보 전송
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);

	// 첫 회복용 Timer 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_DO_MINUTELY_WORK);

	// 각종 알림 메세지 전송
	if (COMPARE_RACE(m_character.Race, RACE_ACCOUNT_TYPE_MASK))
	{
		SendString128(STRING_128_USER_NOTICE, "************************************");
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0130, GetRaceString(m_character.Race&RACE_ACCOUNT_TYPE_MASK));
		if(this->IsInvisibleCharacter())
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0000);
		}
		if(m_bNoDamage)
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0001);
		}
		SendString128(STRING_128_USER_NOTICE, "************************************");
	}
	if(m_bStealthState)
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_060509_0002);
	}

// 2009-03-31 by dhjin, 선전 포고 - 세력전 승리 시 지급 되는 이벤트 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-04-21 by cmkwon
//	SDB_INFLUENCE_WAR_INFO *pCurWarInfo = NULL;
//	if(ms_pFieldIOCP->m_InflWarManager.GetINFLUENCE_WAR_INFO_ByInflType(&pCurWarInfo, m_character.InfluenceType))
//	{
//		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
//		pSInflData->byInfluenceType		= pCurWarInfo->InfluenceType;
//		pSInflData->fHPRepairRate		= pCurWarInfo->HPRepairRate;
//		pSInflData->fDPRepairRate		= pCurWarInfo->DPRepairRate;
//		pSInflData->fSPRepairRate		= pCurWarInfo->SPRepairRate;
//		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
//	}
	CInflWarData *pInflWarData = ms_pFieldIOCP->m_InflWarManager.GetInflWarDataByInflType(m_character.InfluenceType);
	if(pInflWarData)
	{
		INIT_MSG(MSG_FC_WAR_INFLUENCE_DATA, T_FC_WAR_INFLUENCE_DATA, pSInflData, SendBuf);
		pSInflData->byInfluenceType		= m_character.InfluenceType;
		pSInflData->fHPRepairRate		= pInflWarData->fInflHPRepairRate;
		pSInflData->fDPRepairRate		= pInflWarData->fInflDPRepairRate;
		pSInflData->fSPRepairRate		= pInflWarData->fInflSPRepairRate;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_DATA));
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-20 by cmkwon, 세력전보스몬스터 소환 정보 전송
	if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
	{
		BOOL	CheckBoss	= FALSE;		// 2007-07-16 by dhjin, 모선 전 시 거점 정보는 전송하지 않는다.
		INIT_MSG(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA, T_FC_WAR_BOSS_MONSTER_SUMMON_DATA, pSBossSummon, SendBuf);
		if(ms_pFieldIOCP->m_InflWarManager.GetSummonInflBossMonsterData(pSBossSummon, INFLUENCE_TYPE_VCN))
		{
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetSummonInflBossMonsterData(pSBossSummon, INFLUENCE_TYPE_ANI))
		{
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetVCNSummonedInflBossMonsterData(pSBossSummon))
		{// 2007-02-06 by dhjin, 바이제니유 보스(전함) 생성되어  있을시 정보 체크하여 보내기
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
			CheckBoss = TRUE;
		}
		if(ms_pFieldIOCP->m_InflWarManager.GetANISummonedInflBossMonsterData(pSBossSummon))
		{// 2007-02-06 by dhjin, 알링턴 보스(전함) 생성되어  있을시 정보 체크하여 보내기
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_BOSS_MONSTER_SUMMON_DATA));
			CheckBoss = TRUE;
		}
		if(FALSE == CheckBoss
			&& !ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.empty())
		{// 2007-07-16 by dhjin, 거점 정보 전송.
			
			INIT_MSG(MSG_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON, T_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON, pSBossSummon, SendBuf);

			mt_auto_lock mtA(&(ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo));	// 2007-10-08 by cmkwon, lock 필요
			mtvectorSSUMMON_STRATEGYPOINT_INFO::iterator	itr = ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.begin();
			while(itr != ms_pFieldIOCP->m_InflWarManager.m_mtvectSummonStrategyPointInfo.end())
			{
				pSBossSummon->InfluenceType				= itr->InfluenceType;
				pSBossSummon->MapIndex					= itr->MapIndex;
				STRNCPY_MEMSET(pSBossSummon->MapName, itr->MapName, SIZE_MAX_MAP_NAME);
				pSBossSummon->SummonStrategyPointTime	= itr->SummonStrategyPointTime;
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_WAR_STRATEGYPOINT_MONSTER_SUMMON));
				itr++;
			}
		}

	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-14 by dhjin, 전진기지 전쟁 정보 전송
	INIT_MSG(MSG_FC_OUTPOST_WAR_INFO, T_FC_OUTPOST_WAR_INFO, pSOutPostWarInfo, SendBuf);
	pSOutPostWarInfo->OutPostWarInfoListCount = this->ms_pFieldIOCP->m_OutPostManager.CheckAllOutPostWaringAndSendClient((SOUTPOST_WAR_INFO*)(SendBuf+MSG_SIZE(MSG_FC_OUTPOST_WAR_INFO)));
	if(0 < pSOutPostWarInfo->OutPostWarInfoListCount)
	{
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_OUTPOST_WAR_INFO)+pSOutPostWarInfo->OutPostWarInfoListCount*sizeof(SOUTPOST_WAR_INFO));
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-26 by dhjin, 모선전 정보 표시 기획안 - 전략포인트 생성 된 정보 설정
	if(ms_pFieldIOCP->m_InflWarManager.CheckSummonBoss())
	{
		ms_pFieldIOCP->m_InflWarManager.SendMSWarInfoForUser(this);
	}
	ms_pFieldIOCP->m_InflWarManager.SendMSWarOptionTypeForInfluenceUser(this);

	SendCouponEvent();		// 2008-04-28 by dhjin, 아레나 통합 - 쿠폰 정보 전송 

	// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
	if( this->IsCityCurrentFieldMapChannel() )
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES, T_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES, pInflVictory, pInflVictorySendBuf);
		pInflVictory->PointBCU = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(INFLUENCE_TYPE_VCN);
		pInflVictory->PointANI = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(INFLUENCE_TYPE_ANI);
		SendAddData(pInflVictorySendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_VICTORITES));
	}

	this->ApplyBuffSkillByTurnAround();
#endif
	// end 2013-05-09 by hskim, 세력 포인트 개선	

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
//	// 2009-09-09 ~ 2010-01-28 by dhjin, 인피니티 - 인피니티 종료 후 유저 총 스텟 계산 추가
//	this->CheckArmor_SendTotalStat(TRUE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetWearItem()
/// \brief		아레나 통합 - 장착 아이템 정보 초기화
/// \author		dhjin
/// \date		2008-01-29 ~ 2008-01-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetWearItem()
{
	memset(&m_ItemProw, 0x00, sizeof(ITEM));
	memset(&m_ItemProwIn, 0x00, sizeof(ITEM));
	memset(&m_ItemProwOut, 0x00, sizeof(ITEM));
	memset(&m_ItemWingIn, 0x00, sizeof(ITEM));
	memset(&m_ItemWingOut, 0x00, sizeof(ITEM));
	memset(&m_ItemCenter, 0x00, sizeof(ITEM));
	memset(&m_ItemRear, 0x00, sizeof(ITEM));

	// 2010-06-15 by shcho&hslee 펫시스템.
// 	memset(&m_ItemAttachment, 0x00, sizeof(ITEM));
// 	memset(&m_ItemPet, 0x00, sizeof(ITEM));
	memset(&m_ItemAccessoryUnLimited, 0x00, sizeof(ITEM));
	memset(&m_ItemAccessoryTimeLimit, 0x00, sizeof(ITEM));
	memset(&m_ItemPet, 0x00, sizeof(ITEM));

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetAllSkill()
/// \brief		아레나 통합 - 모든 스킬 초기화
/// \author		dhjin
/// \date		2008-02-25 ~ 2008-02-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetAllSkill()
{
	this->ResetTimeLimitSkill();
	this->ResetToggleSkill();
	this->ResetChargingSkill();
	this->ResetFieldDummySkill();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetTimeLimitSkill()
/// \brief		아레나 통합 - 시간제한형 스킬 초기화
/// \author		dhjin
/// \date		2008-02-25 ~ 2008-02-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetTimeLimitSkill()
{
	m_SkillManager.ResetTimeLimitSkillData();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetToggleSkill()
/// \brief		아레나 통합 - 토글 스킬형 초기화
/// \author		dhjin
/// \date		2008-02-25 ~ 2008-02-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetToggleSkill()
{
	m_SkillManager.ResetToggleSkillData();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetChargingSkill()
/// \brief		아레나 통합 - 차징 스킬형 초기화
/// \author		dhjin
/// \date		2008-02-25 ~ 2008-02-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetChargingSkill()
{
	m_SkillManager.ResetChargingSkillData();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ResetFieldDummySkill()
/// \brief		아레나 통합 - 더미 스킬 초기화
/// \author		dhjin
/// \date		2008-02-25 ~ 2008-02-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ResetFieldDummySkill()
{
	m_bDummyCheck			= FALSE;
	this->DeleteAllFieldDummy();

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InitUserInfoForArenaEnding()
/// \brief		아레나 통합 - 아레나 종료시 아레나 서버에 유저 정보 초기화 필요한 부분 처리, 아레나 서버에서 호출 
/// \author		dhjin
/// \date		2008-03-11 ~ 2008-03-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InitUserInfoForArenaEnding()
{
	// 임시로 변경했던 유저 세력을 정상값으로 변경
	this->m_character.InfluenceType	= ms_pFieldIOCP->m_ArenaManager.GetTeamInflW(this->m_ArenaInfo.TeamNum);

	this->ResetWearItem();

	// 무적 설정으로 아레나 종료 후 죽는 현상 방지
	this->m_bNoDamage = TRUE;

	///////////////////////////////////////////////////////////////////////////////
	// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다
	this->DeleteMeFromMonsterAttackedList();

	if (m_pCurrentFieldMapChannel != NULL)
	{
		///////////////////////////////////////////////////////////////////////////
		// NPC Server에 GameEndOK 메세지를 전송한다.
		INIT_MSG_WITH_BUFFER(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, SendBuf);
		pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));

		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 맵에서 자신에 존재를 지우자! (아레나 관련 보안 코드)
		///////////////////////////////////////////////////////////////////////////
		// 자신의 정보를 맵 Block에서 삭제 한다.
		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
		{
			char szTemp[256];
			sprintf(szTemp, "[Error] DeleteBlockPosition_3 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f) \r\n"
				, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
				, m_character.PositionVector.x, m_character.PositionVector.z);
			DBGOUT(szTemp);
			g_pFieldGlobal->WriteSystemLog(szTemp);
		}
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
	}

}

// start 2011-10-17 by hskim, 파트너 시스템 2차
///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InitUserInfoForArenaEnding()
/// \brief		// 2011-10-17 by hskim, 파트너 시스템 2차 - 아레나 종료시 아레나 서버에서 메인 서버로 데이터 전송 처리
/// \author		hskim
/// \date		2011-10-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendUserInfoForArenaEnding()
{
	CIOCPSocket	*MFSSock = this->ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);

	if(NULL == MFSSock) 
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Arena] CFieldIOCPSocket::ArenaFin MainFieldSocket is NULL! DRoomNum(%4d) %s \r\n", this->m_ArenaInfo.DeathMatchRoomNum, GetCharacterString(GetCharacter(), string()));
		return;
	}

	m_ItemManager.InfinitySendPetItemInfo((CFieldIOCPSocket*)MFSSock);
}
// end 2011-10-17 by hskim, 파트너 시스템 2차

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendMSWarInfoResult(vectSMSWAR_INFO_RESULT * i_pVectMSWarInfoResult)
/// \brief		모선전, 거점전 정보창 기획안 - 모선전 정보 전송
/// \author		dhjin
/// \date		2008-04-03 ~ 2008-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendMSWarInfoResult(vectSMSWAR_INFO_RESULT * i_pVectMSWarInfoResult)
{
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_MSWARINFO_RESULT_OK, T_FC_INFO_MSWARINFO_RESULT_OK, pSendMsg, SendBuf);
	pSendMsg->MSWarInfoResultListCount = this->MakeMSG_FC_INFO_MSWARINFO_RESULT_OK((SMSWAR_INFO_RESULT*)(SendBuf+MSG_SIZE(MSG_FC_INFO_MSWARINFO_RESULT_OK)), i_pVectMSWarInfoResult);
//	if(0 >= pSendMsg->MSWarInfoResultListCount)
//	{
//		pFISock->SendErrorMessage(T_FC_INFO_MSWARINFO_RESULT, ERR_INVALID_ARENASERVER_CHARACTER);
//		return;
//	}
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFO_MSWARINFO_RESULT_OK)+pSendMsg->MSWarInfoResultListCount*sizeof(SMSWAR_INFO_RESULT));
}

INT CFieldIOCPSocket::MakeMSG_FC_INFO_MSWARINFO_RESULT_OK(SMSWAR_INFO_RESULT *o_pMSWarInfoResult, vectSMSWAR_INFO_RESULT * i_pVectMSWarInfoResult)
{
	int	MSWarInfoResultListCount = 0;

	vectSMSWAR_INFO_RESULT::iterator itr = i_pVectMSWarInfoResult->begin();
	for(; itr != i_pVectMSWarInfoResult->end(); itr++)
	{
		o_pMSWarInfoResult[MSWarInfoResultListCount].AttInfluence			= itr->AttInfluence;
		o_pMSWarInfoResult[MSWarInfoResultListCount].MonsterUID				= itr->MonsterUID;
		o_pMSWarInfoResult[MSWarInfoResultListCount].ContributionPoint		= itr->ContributionPoint;
		o_pMSWarInfoResult[MSWarInfoResultListCount].MSWarStartTime			= itr->MSWarStartTime;
		o_pMSWarInfoResult[MSWarInfoResultListCount].MSWarEndTime			= itr->MSWarEndTime;
		o_pMSWarInfoResult[MSWarInfoResultListCount].WinInfluence			= itr->WinInfluence;
		MSWarInfoResultListCount++;
	}
	
	return MSWarInfoResultListCount;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendSPWarInfoResult(vectSSPWAR_INFO_RESULT * i_pVectSPWarInfoResult)
/// \brief		모선전, 거점전 정보창 기획안 - 거점전 정보 전송
/// \author		dhjin
/// \date		2008-04-03 ~ 2008-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendSPWarInfoResult(vectSSPWAR_INFO_RESULT * i_pVectSPWarInfoResult)
{
	BYTE SendBuf[SIZE_MAX_PACKET];
	int			nSendBytes		= 0;
	*(MessageType_t*)(SendBuf)	= T_FC_INFO_SPWARINFO_RESULT_OK_HEADER;
	nSendBytes					= SIZE_FIELD_TYPE_HEADER;
		
	for (int i=0; i < i_pVectSPWarInfoResult->size(); i++)
	{
		if(nSendBytes + MSG_SIZE(MSG_FC_INFO_SPWARINFO_RESULT_OK) > SIZE_MAX_PACKET)
		{
			this->SendAddData(SendBuf, nSendBytes);
			nSendBytes					= 0;
		}

		*((MessageType_t*)(SendBuf + nSendBytes))	= T_FC_INFO_SPWARINFO_RESULT_OK;
		nSendBytes									+= SIZE_FIELD_TYPE_HEADER;
		MSG_FC_INFO_SPWARINFO_RESULT_OK *pRMsg		= (MSG_FC_INFO_SPWARINFO_RESULT_OK*)(SendBuf + nSendBytes);
		*pRMsg										= (*i_pVectSPWarInfoResult)[i];
		nSendBytes									+= sizeof(MSG_FC_INFO_SPWARINFO_RESULT_OK);
	}

	if(nSendBytes > 0)
	{
		this->SendAddData(SendBuf, nSendBytes);
		nSendBytes						= 0;
	}

	this->SendAddMessageType(T_FC_INFO_SPWARINFO_RESULT_OK_DONE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GetDBAllLetter()
/// \brief		EP3 편지 시스템 - DB에서 편지 가져오기
/// \author		dhjin
/// \date		2008-04-23 ~ 2008-04-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GetDBAllLetter()
{
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetLetter, this, m_character.AccountUniqueNumber, NULL);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetAllLetter, this, m_character.AccountUniqueNumber, NULL);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			MapIndex_t CFieldIOCPSocket::GetBackMapIndex(CFieldMapProject *i_pCurFMPro)
/// \brief		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) -
/// \author		cmkwon
/// \date		2008-06-20 ~ 2008-06-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
MapIndex_t CFieldIOCPSocket::GetBackMapIndex(CFieldMapProject *i_pCurFMPro)
{
	if(NULL == i_pCurFMPro
		|| FALSE == i_pCurFMPro->IsValidBeforeMapIndex())
	{// 2008-06-20 by cmkwon, 백맵이 둘다 설정 되어 있지 않음
		return 0;
	}

	///////////////////////////////////////////////////////////////////////////////	
	// 2008-06-20 by cmkwon, 백맵 둘중에 하나만 설정되어 있으면 그것을 리턴
	if(0 == i_pCurFMPro->m_nBeforeMapIndex2)
	{
		return i_pCurFMPro->m_nBeforeMapIndex;
	}
	else if(0 == i_pCurFMPro->m_nBeforeMapIndex)
	{
		return i_pCurFMPro->m_nBeforeMapIndex2;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, 백맵이 두개 모두 설정 되어 있다. - 검색해서 처리

	mt_auto_lock mtA(&m_mtmapBackMapIndex);
	mtmapMapIdx2MapIdx::iterator itr = m_mtmapBackMapIndex.find(i_pCurFMPro->m_nMapIndex);
	if(itr != m_mtmapBackMapIndex.end())
	{// 2008-06-20 by cmkwon, 검색 결과가 있다면 검색된것을 리턴
		return itr->second;
	}

	return i_pCurFMPro->m_nBeforeMapIndex;	// 2008-06-20 by cmkwon, 검색 결과가 없으므로 기본값을 리턴
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::UpdateBackMapIndex(MapIndex_t i_nCurMapIndex, MapIndex_t i_nBackMapIndex)
/// \brief		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - CFieldIOCPSocket::UpdateBackMapIndex() 추가
/// \author		cmkwon
/// \date		2008-06-20 ~ 2008-06-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::UpdateBackMapIndex(MapIndex_t i_nCurMapIndex, MapIndex_t i_nBackMapIndex)
{
	mt_auto_lock mtA(&m_mtmapBackMapIndex);

	mtmapMapIdx2MapIdx::iterator itr = m_mtmapBackMapIndex.find(i_nCurMapIndex);
	if (itr != m_mtmapBackMapIndex.end())
	{
		itr->second = i_nBackMapIndex;	// 2008-06-20 by cmkwon, 기존 데이터를 업데이트 한다.
		return;
	}

	m_mtmapBackMapIndex.insert(pair<MapIndex_t, MapIndex_t>(i_nCurMapIndex, i_nBackMapIndex));
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckOneSecondTermSystem()
/// \brief		
/// \author		dhjin
/// \date		2008-08-18 ~ 2008-08-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckOneSecondTermSystem()
{
	DWORD dwCurTick	= timeGetTime();
	if(INTERVAL_SYSTEM_MS > (dwCurTick - m_dwMSTermSystem))
	{
		char szSystemLog[1024];
		sprintf(szSystemLog, "[Notify] INTERVAL_SYSTEM : %20d Old      %20d New			%10d\r\n",		m_dwMSTermSystem, dwCurTick, dwCurTick - m_dwMSTermSystem);
		g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
		return FALSE;	
	}
	this->m_dwMSTermSystem = dwCurTick;

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsInitializedSecurityServer(void)
/// \brief		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
/// \author		cmkwon
/// \date		2008-11-28 ~ 2008-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsInitializedSecurityServer(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - CFieldIOCPSocket::IsInitializedSecurityServer#, 보완시스템 서버 체크
	if(ms_bUsingSecuritySystem)
	{
		return TRUE;
	}

	if(ANTICPX_INVALID_HANDLE_VALUE != ms_hAhnHSServerHandle
		|| FALSE != ms_bUsingNProtect	// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 
		|| CFieldIOCPSocket::ms_XTrapUsingFlag				// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - CFieldIOCPSocket::IsInitializedSecurityServer# 처리
		|| FALSE != ms_bUsingXignCode)
	{
		return TRUE;
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::SecurityXignCodeInit(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK *i_pReqScanInitOK/*=NULL*/)
/// \brief		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
/// \author		cmkwon
/// \date		2008-11-28 ~ 2008-11-28
/// \warning	
///
/// \param		
/// \return		호출함수 쪽에서 ERR_NO_ERROR 이 아니면 해당 소켓을 종료 처리 해야한다.
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::SecurityXignCodeInit(MSG_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK *i_pReqScanInitOK/*=NULL*/)
{
	Err_t errRet = ERR_NO_ERROR;
	if(FALSE == ms_bUsingXignCode
		|| NULL == m_hXignCodeAntiCheatHandle
		|| FALSE != m_bXignCodeReceivedReqScanInitOK)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SecurityXignCodeInit# error !!, %s UsingXignCode(%d) XignCodeHandle(%d) ReceivedReqScanInitOK(%d)\r\n"
			, GetCharacterString(this->GetCharacter(), string()), ms_bUsingXignCode, m_hXignCodeAntiCheatHandle, m_bXignCodeReceivedReqScanInitOK);
		errRet	= ERR_SECURITY_ANTICPX_INVALID_HANDLE;
		return errRet;
	}

#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
	BOOL bReqScanInitOK = TRUE;
	if(FALSE == ZSWAVE_Verify(m_hXignCodeAntiCheatHandle, i_pReqScanInitOK->byResultData, MAX_PACKET_SIZE_FOR_XIGNCODE))
	{
		if(FALSE == this->SecurityXignCodeGetErrorString(m_hXignCodeAntiCheatHandle, (char*)i_pReqScanInitOK->byResultData))
		{
			errRet			= ERR_SECURITY_HACKING_GUID;
			bReqScanInitOK	= FALSE;
		}
	}
	ZSWAVE_Close(m_hXignCodeAntiCheatHandle);
	m_hXignCodeAntiCheatHandle			= NULL;
	m_bXignCodeReceivedReqScanInitOK	= bReqScanInitOK;

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)

	
	return errRet;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SecurityXignCodeGetErrorString(HANDLE i_hXignCode, char *i_pResultData)
/// \brief		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
/// \author		cmkwon
/// \date		2008-11-28 ~ 2008-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SecurityXignCodeGetErrorString(HANDLE i_hXignCode, char *i_pResultData)
{
	char szEnginErr[MAX_PACKET_SIZE_FOR_XIGNCODE];
	MEMSET_ZERO(szEnginErr, MAX_PACKET_SIZE_FOR_XIGNCODE);
	int rtn = 0;

#if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)// || defined(SERVICE_TYPE_CHINESE_SERVER_1)		// 2009-04-14 by cmkwon, 중국 Yetime에 XignCode 적용 - , // 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
// 2013-07-02 by jhseol, 중국 테스트서버 구축 - 임시방편 에러제거
	rtn = ZSWAVE_VerifyEx(i_hXignCode, i_pResultData, MAX_PACKET_SIZE_FOR_XIGNCODE, szEnginErr, MAX_PACKET_SIZE_FOR_XIGNCODE);
	switch(rtn)
	{
	case Z_RTN_NONCLIENT:				// valid result but wrong
	case Z_RTN_BLACK_CODE:				// result of anti-cheat
	case Z_RTN_RESEND:					// 
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notyfy] XignCode error !! ReturnCode(%d) ErrorString(%s) %s [closed]\r\n"
				, rtn, szEnginErr, GetCharacterString(this->GetCharacter(), string()));
			return FALSE;
		}
		break;
	}

#endif // END - #if defined(SERVICE_TYPE_TAIWANESE_SERVER_1)

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notyfy] XignCode error !! ReturnCode(%d) ErrorString(%s) %s [no problem]\r\n"
		, rtn, szEnginErr, GetCharacterString(this->GetCharacter(), string()));
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendUserInfoBySecretOption(SUSER_INFO_OPTION * i_pUserInfoOption)
/// \brief		EP3 유저정보옵션 - 유저 정보 전송
/// \author		dhjin
/// \date		2008-06-23 ~ 2008-06-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendUserInfoBySecretOption(SUSER_INFO_OPTION * i_pUserInfoOption)
{
	if(NULL == i_pUserInfoOption)
	{
		this->SendErrorMessage(T_FC_CHARACTER_GET_USER_INFO, ERR_INVALID_CHARACTER);
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_USER_INFO_OK, T_FC_CHARACTER_GET_USER_INFO_OK, pSendMsg, SendBuf);
	STRNCPY_MEMSET(pSendMsg->CharacterName, i_pUserInfoOption->CharacterName, SIZE_MAX_CHARACTER_NAME);
	pSendMsg->PilotFace		= i_pUserInfoOption->PilotFace;
	pSendMsg->UnitKind		= i_pUserInfoOption->UnitKind;
	STRNCPY_MEMSET(pSendMsg->NickName, i_pUserInfoOption->NickName, SIZE_MAX_CHARACTER_NAME);	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	// 2012-07-20 by jhseol, 아템미리보기 On/Off - 둘다 길드가 없을때는 체크를 한함, 체크하도록 수정
	//if(!strcmp(this->m_character.GuildName, i_pUserInfoOption->GuildName))
	if( (!strcmp(this->m_character.GuildName, i_pUserInfoOption->GuildName)) && this->m_character.GuildUniqueNumber != NULL && i_pUserInfoOption->GuildUID != NULL )
	// end 2012-07-20 by jhseol, 아템미리보기 On/Off - 둘다 길드가 없을때는 체크를 한함, 체크하도록 수정
	{
		if(ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(this->m_character.CharacterUniqueNumber))
		{
			pSendMsg->GuildUID			= i_pUserInfoOption->GuildUID;
			STRNCPY_MEMSET(pSendMsg->GuildName, i_pUserInfoOption->GuildName, SIZE_MAX_GUILD_NAME);		
			pSendMsg->Level				= i_pUserInfoOption->Level;
			pSendMsg->MapChannelIndex	= i_pUserInfoOption->MapChannelIndex;
			pSendMsg->Propensity		= i_pUserInfoOption->Propensity;
			pSendMsg->LastStartedTime	= i_pUserInfoOption->LastStartedTime;			
		}
		else
		{
			if(0 == (USER_INFO_OPTION_SECRET_GUILD_GUILD & i_pUserInfoOption->SecretInfoOption))
			{
				pSendMsg->GuildUID			= i_pUserInfoOption->GuildUID;
				STRNCPY_MEMSET(pSendMsg->GuildName, i_pUserInfoOption->GuildName, SIZE_MAX_GUILD_NAME);		
			}
			if(0 == (USER_INFO_OPTION_SECRET_GUILD_LEVEL & i_pUserInfoOption->SecretInfoOption))
			{
				pSendMsg->Level = i_pUserInfoOption->Level;
			}
			if(0 == (USER_INFO_OPTION_SECRET_GUILD_POSITION & i_pUserInfoOption->SecretInfoOption))
			{
				pSendMsg->MapChannelIndex = i_pUserInfoOption->MapChannelIndex;
			}
			if(0 == (USER_INFO_OPTION_SECRET_GUILD_PROPENSITY & i_pUserInfoOption->SecretInfoOption))
			{
				pSendMsg->Propensity = i_pUserInfoOption->Propensity;
			}
			if(0 == (USER_INFO_OPTION_SECRET_GUILD_LASTLOGIN & i_pUserInfoOption->SecretInfoOption))
			{
				pSendMsg->LastStartedTime = i_pUserInfoOption->LastStartedTime;
			}
		}
	}
	else
	{
		if(0 == (USER_INFO_OPTION_SECRET_GUILD & i_pUserInfoOption->SecretInfoOption))
		{
			pSendMsg->GuildUID			= i_pUserInfoOption->GuildUID;
			STRNCPY_MEMSET(pSendMsg->GuildName, i_pUserInfoOption->GuildName, SIZE_MAX_GUILD_NAME);		
		}
		if(0 == (USER_INFO_OPTION_SECRET_LEVEL & i_pUserInfoOption->SecretInfoOption))
		{
			pSendMsg->Level = i_pUserInfoOption->Level;
		}
		if(0 == (USER_INFO_OPTION_SECRET_POSITION & i_pUserInfoOption->SecretInfoOption))
		{
			pSendMsg->MapChannelIndex = i_pUserInfoOption->MapChannelIndex;
		}
		if(0 == (USER_INFO_OPTION_SECRET_PROPENSITY & i_pUserInfoOption->SecretInfoOption))
		{
			pSendMsg->Propensity = i_pUserInfoOption->Propensity;
		}
		if(0 == (USER_INFO_OPTION_SECRET_LASTLOGIN & i_pUserInfoOption->SecretInfoOption))
		{
			pSendMsg->LastStartedTime = i_pUserInfoOption->LastStartedTime;
		}
	}

	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_USER_INFO_OK));
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_MFSINFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 서버에서 호출
/// \author		dhjin
/// \date		2007-12-27 ~ 2007-12-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_MFSINFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_MFSINFO
									, MSG_FtoA_MFSINFO, pRMsg);

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}

	// 2007-12-27 by dhjin, 필드 서버 정보를 등록하고 등록 되었음을 알린다.
	SARENA_USE_FIELD_SERVER_INFO	tmFieldServerInfo;
	MEMSET_ZERO(&tmFieldServerInfo, sizeof(SARENA_USE_FIELD_SERVER_INFO));
	tmFieldServerInfo.MFS_ID		= pRMsg->MFS_ID;
	tmFieldServerInfo.MFS_Port		= pRMsg->MFS_Port;
	STRNCPY_MEMSET(tmFieldServerInfo.MFS_IP, pRMsg->MFS_IP, SIZE_MAX_IPADDRESS);
	STRNCPY_MEMSET(tmFieldServerInfo.MFS_Name, pRMsg->MFS_Name, SIZE_MAX_SERVER_NAME);
	tmFieldServerInfo.Socket		= this;

	if(FALSE == ms_pFieldIOCP->InsertFieldServerInfoForArenaServer(&tmFieldServerInfo))
	{// 2007-12-27 by dhjin, 등록
		// 2009-12-09 by cmkwon, 로그 정보 추가 - 
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer, MainFieldServer can't register. MFSID(%d) MFSName(%20s) MFSIP(%s) PeerSocketIP(%s) \r\n", pRMsg->MFS_ID, pRMsg->MFS_Name, pRMsg->MFS_IP, this->GetPeerIP());
		return RES_RETURN_FALSE;
	}

	// 2009-12-09 by cmkwon, 로그 정보 추가 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] ArenaServer, MainFieldServer is registered. MFSID(%d) MFSName(%20s) MFSIP(%s) PeerSocketIP(%s) \r\n", pRMsg->MFS_ID, pRMsg->MFS_Name, pRMsg->MFS_IP, this->GetPeerIP());
	this->SendAddMessageType(T_FtoA_MFSINFO_OK);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_AUTH_CHARACTER_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 서버에서 호출 
/// \author		dhjin
/// \date		2007-12-28 ~ 2007-12-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_AUTH_CHARACTER_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_AUTH_CHARACTER_OK
									, MSG_FtoA_AUTH_CHARACTER_OK, pRMsg);

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}

	CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIndex);
	if(NULL == ClientFISoc
		|| FALSE == ClientFISoc->IsUsing())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FtoA_AUTH_CHARACTER_OK# 10000 %s AccUID(%d) CliIdx(%d) Protocol(%s) Error(%s:%d) \r\n"
			, GetCharacterString(GetCharacter(), string()), pRMsg->AccountUID, pRMsg->AFSClientIndex, GetProtocolTypeString(pRMsg->ErrorMsgType), GetErrorString(pRMsg->ErrorCode), pRMsg->ErrorCode);

		ClientFISoc->SendErrorMessage(T_FtoA_AUTH_CHARACTER_OK, ERR_INVALID_MAINSERVER_CHARACTER, 10000);
		return RES_BREAK;		
	}
	
	if(pRMsg->ErrorCheck)
	{// 2007-12-28 by dhjin, 오류 전송
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FtoA_AUTH_CHARACTER_OK# 20000 %s AccUID(%d) CliIdx(%d) Protocol(%s) Error(%s:%d) \r\n"
			, GetCharacterString(GetCharacter(), string()), pRMsg->AccountUID, pRMsg->AFSClientIndex, GetProtocolTypeString(pRMsg->ErrorMsgType), GetErrorString(pRMsg->ErrorCode), pRMsg->ErrorCode);

		ClientFISoc->SendErrorMessage(T_FtoA_AUTH_CHARACTER_OK, ERR_INVALID_MAINSERVER_CHARACTER, 20000, pRMsg->ErrorCheck);
		return RES_BREAK;
	}
	
	// start 2011-11-03 by shcho, yedang 셧다운제 구현 - 아레나서버 셧다운제 인증용
	if(TRUE==pRMsg->ShutDownMins)	// 미성년자이면 종료가 아레나에서도 동작할 수 있도록 처리한다.
	{
		ShutdownUserData shutdownMins;
		MEMSET_ZERO(&shutdownMins,sizeof(ShutdownUserData));
		shutdownMins.Account_UniqueNumber	= pRMsg->AccountUID;
		shutdownMins.CharacterUniqueNumber[0]	= pRMsg->AFSCharacterUID;
		shutdownMins.CharacterUniqueNumber[1]	= 0;	// 안쓴다.
		shutdownMins.CharacterUniqueNumber[2]	= 0;	// 안쓴다.
		ms_pFieldIOCP->m_ShutDownData.push_back(shutdownMins);
		
		// 체크를 위해 로그를 남긴다.
		g_pFieldGlobal->WriteSystemLogEX(TRUE,
			"  [Notify] CFieldIOCPSocket::Process_FtoA_AUTH_CHARACTER_OK SHUTDOWNMINS CHECK OK!! MFAccountUID[ %d ] : MF_CLIENT_INDEX[ %d ], AF_CLIENT_INDEX[ %d ], ShutdownFLAG[%d]\r\n",
			pRMsg->AccountUID, pRMsg->MFSClientIndex, pRMsg->AFSClientIndex, pRMsg->ShutDownMins);
	}
	// end 2011-11-03 by shcho, yedang 셧다운제 구현 - 아레나서버 셧다운제 인증용

	ClientFISoc->m_character.CharacterUniqueNumber	= pRMsg->AFSCharacterUID;
	ClientFISoc->m_character.AccountUniqueNumber	= pRMsg->AccountUID;
	ClientFISoc->m_character.ClientIndex			= pRMsg->AFSClientIndex;	// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나에서 메인필드서버 소켓을 찾기위한 정보 설정

	///////////////////////////////////////////////////////////////////////////////////
	// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 유저가 최근에 플레이한 시간 확인
	ATUM_DATE_TIME tempTime;
	tempTime.SetCurrentDateTime(FALSE);
	if(pRMsg->ArenaPlayInfo.atimeLastPlayTime.Year == FALSE)
	{
		pRMsg->ArenaPlayInfo.atimeLastPlayTime = tempTime;
	}
	ClientFISoc->m_character.ArenaPlayInfo			= pRMsg->ArenaPlayInfo;		/// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 설정
	// end 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 유저가 최근에 플레이한 시간 확인

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaGetCharacter, ClientFISoc, NULL, NULL);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaPlayCount, ClientFISoc, NULL, NULL);	// 2012-04-12 by jhseol, 아레나 추가개발 - 아레나 플레이 카운트 확인 큐 등록 

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_ARENA_TEAM_MATCHING_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 서버에서 호출 
/// \author		dhjin
/// \date		2008-01-08 ~ 2008-01-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_ARENA_TEAM_MATCHING_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_ARENA_TEAM_MATCHING_OK
									, MSG_FtoA_ARENA_TEAM_MATCHING_OK, pRMsg);

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] isn't ArenaServer \r\n");
		return RES_RETURN_FALSE;
	}

	CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIndex);
	if(NULL == ClientFISoc
		|| pRMsg->AFSCharacterUID != ClientFISoc->m_character.CharacterUniqueNumber
		|| pRMsg->AccountUID != ClientFISoc->m_character.AccountUniqueNumber)
	{
		ClientFISoc->SendErrorMessage(T_FtoA_ARENA_TEAM_MATCHING_OK, ERR_INVALID_MAINSERVER_CHARACTER);
		return RES_BREAK;		
	}

	// 2008-01-08 by dhjin, 아레나 게임 시작 가능한 상태임을 전송한다.
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaStartGetCharacter, ClientFISoc, NULL, NULL);

	return RES_RETURN_TRUE;
}

// 2012-12-18 by jhseol, 아레나 캐릭터 리셋 후 캐릭터 정보 다시 로딩하기.
///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_ARENA_CHARACTER_RESET_RELOAD(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 종료 후 메인서버에서 캐릭터 정보를 다시 로딩하라는 패킷을 받음
/// \author		jhseol
/// \date		2012-12-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_ARENA_CHARACTER_RESET_RELOAD(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_ARENA_CHARACTER_RESET_RELOAD
		, MSG_FtoA_ARENA_CHARACTER_RESET_RELOAD, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FtoA_ARENA_CHARACTER_RESET_RELOAD, isn't ArenaServer \r\n");
		return RES_BREAK;
	}
	
	if( 0 != pRMsg->ArenaCharacterUID )		// 인피니티 종료 시엔 아레나 케릭터 번호가 '0' 으로 옴으로 필터링 해야함.
	{
		CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->ArenaCharacterUID);
		if(NULL == ClientFISoc || pRMsg->AccountUID != ClientFISoc->m_character.AccountUniqueNumber)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FtoA_ARENA_CHARACTER_RESET_RELOAD, not matched arena character \r\n");
			return RES_BREAK;		
		}
		
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaCharacterReload, ClientFISoc, NULL, NULL);
	}
	
	return RES_RETURN_TRUE;
}
// end 2012-12-18 by jhseol, 아레나 캐릭터 리셋 후 캐릭터 정보 다시 로딩하기.

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_MSWARINFO_DISPLAY_OPTION(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		모선전 정보 표시 기획안 - 옵션 수정
/// \author		dhjin
/// \date		2008-03-28 ~ 2008-03-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_MSWARINFO_DISPLAY_OPTION(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_MSWARINFO_DISPLAY_OPTION
									, MSG_FC_INFO_MSWARINFO_DISPLAY_OPTION, pRMsg);

	if(FALSE == IsValidCharacter()
		|| pRMsg->ClientIndex != m_character.ClientIndex
		|| pRMsg->CharacterUID != m_character.CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_INFO_MSWARINFO_DISPLAY_OPTION, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
	{
		SendErrorMessage(T_FC_INFO_MSWARINFO_DISPLAY_OPTION, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	this->ms_pFieldIOCP->m_InflWarManager.SetMSWarOptionTypeW(m_character.InfluenceType, pRMsg->MSWarOptionType);
	QPARAM_UPDATE_MSWAR_OPTION_TYPE *pQaram = new QPARAM_UPDATE_MSWAR_OPTION_TYPE;
	pQaram->InfluenceType		= m_character.InfluenceType;
	pQaram->MSWarOptionType		= pRMsg->MSWarOptionType;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateMSWarOptionType, this, m_character.AccountUniqueNumber, pQaram);
	this->ms_pFieldIOCP->m_InflWarManager.SendMSWarOptionTypeForInfluenceAllUser(m_character.InfluenceType);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_MSWARINFO_RESULT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		모선전, 거점전 정보창 기획안 - 
/// \author		dhjin
/// \date		2008-04-02 ~ 2008-04-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_MSWARINFO_RESULT(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_INFO_MSWARINFO_RESULT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetLogMSWarInfo, this, m_character.AccountUniqueNumber, NULL);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_SPWARINFO_RESULT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		모선전, 거점전 정보창 기획안 - 
/// \author		dhjin
/// \date		2008-04-02 ~ 2008-04-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_SPWARINFO_RESULT(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_INFO_SPWARINFO_RESULT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetLogSPWarInfo, this, m_character.AccountUniqueNumber, NULL);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_REQUEST_TITLE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-04-29 ~ 2008-04-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_REQUEST_TITLE(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_LETTER_REQUEST_TITLE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	
	
	this->m_LetterManager.SendLetterList();
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_READ(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-04-29 ~ 2008-04-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_READ(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_LETTER_READ
									, MSG_FC_CHAT_LETTER_READ, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_LETTER_READ, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		

	if (pRMsg->CheckRead)
	{
		this->m_LetterManager.SendLetterInfo(pRMsg->LetterUID);
	}
	else
	{
		QPARAM_READ_LETTER *pQParam	= new QPARAM_READ_LETTER;
		pQParam->LetterUID				= pRMsg->LetterUID;
		pQParam->RecvCharacterUID		= m_character.CharacterUniqueNumber;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ReadLetter, this, m_character.AccountUniqueNumber, pQParam);	
	}
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-04-29 ~ 2008-04-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_LETTER_DELETE
									, MSG_FC_CHAT_LETTER_DELETE, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_LETTER_DELETE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		
	
	if(!this->m_LetterManager.DeleteLetter(pRMsg->LetterUID))
	{
		SendErrorMessage(T_FC_CHAT_LETTER_DELETE, ERR_NO_SUCH_LETTER);
		return RES_BREAK;
	}

	this->SendAddMessageType(T_FC_CHAT_LETTER_DELETE_OK);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_SEND(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-05-08 ~ 2008-05-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_LETTER_SEND(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_LETTER_SEND
									, MSG_FC_CHAT_LETTER_SEND, pRMsg);

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - T_FC_CHAT_LETTER_SEND
	LowercaseOnly_i_forTurkish(pRMsg->RecvCharacterName, SIZE_MAX_CHARACTER_NAME);

	if (FALSE == IsValidCharacter()
		|| this->m_character.CharacterUniqueNumber != pRMsg->SendCharacterUID)
	{
		SendErrorMessage(T_FC_CHAT_LETTER_SEND, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		
	
	QPARAM_SEND_LETTER *pQParam	= new QPARAM_SEND_LETTER;
	STRNCPY_MEMSET(pQParam->RecvCharacterName, pRMsg->RecvCharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(pQParam->Title, pRMsg->Title, SIZE_MAX_LETTER_TITLE);
	STRNCPY_MEMSET(pQParam->Content, pRMsg->Content, SIZE_MAX_LETTER_CONTENT);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SendLetter, this, m_character.AccountUniqueNumber, pQParam);	
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_REQUEST_TITLE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-05-09 ~ 2008-05-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_REQUEST_TITLE(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_ALLLETTER_REQUEST_TITLE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	
	
	this->m_LetterManager.SendAllLetterList();

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_READ(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-05-09 ~ 2008-05-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_READ(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_ALLLETTER_READ
									, MSG_FC_CHAT_ALLLETTER_READ, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_ALLLETTER_READ, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		

	if (pRMsg->CheckRead)
	{
		this->m_LetterManager.SendAllLetterInfo(pRMsg->LetterUID);
	}
	else
	{
		QPARAM_READ_ALLLETTER *pQParam	= new QPARAM_READ_ALLLETTER;
		pQParam->LetterUID				= pRMsg->LetterUID;
		pQParam->RecvCharacterUID		= m_character.CharacterUniqueNumber;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ReadAllLetter, this, m_character.AccountUniqueNumber, pQParam);	
	}
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-05-09 ~ 2008-05-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_ALLLETTER_DELETE
									, MSG_FC_CHAT_ALLLETTER_DELETE, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHAT_ALLLETTER_DELETE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		
	
	if(!this->m_LetterManager.DeleteAllLetter(pRMsg->LetterUID))
	{
		SendErrorMessage(T_FC_CHAT_ALLLETTER_DELETE, ERR_NO_SUCH_LETTER);
		return RES_BREAK;
	}

	this->SendAddMessageType(T_FC_CHAT_ALLLETTER_DELETE_OK);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_SEND(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 편지 시스템 -
/// \author		dhjin
/// \date		2008-05-09 ~ 2008-05-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHAT_ALLLETTER_SEND(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHAT_ALLLETTER_SEND
									, MSG_FC_CHAT_ALLLETTER_SEND, pRMsg);

	if (FALSE == IsValidCharacter()
		|| this->m_character.CharacterUniqueNumber != pRMsg->SendCharacterUID)
	{
		SendErrorMessage(T_FC_CHAT_ALLLETTER_SEND, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		
	
	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK|RACE_OPERATION))		// 2014-04-09 by bckim, 관리자 모두에게 편지보내기 기능 활용
	{// 전체 메일은 지도자, 부지도자만 보낼 수 있다.
		SendErrorMessage(T_FC_CHAT_ALLLETTER_SEND, ERR_CHAT_PERMISSION_DENIED);
		return RES_BREAK;
	}

	QPARAM_SEND_ALLLETTER *pQParam	= new QPARAM_SEND_ALLLETTER;
	STRNCPY_MEMSET(pQParam->Title, pRMsg->Title, SIZE_MAX_LETTER_TITLE);
	STRNCPY_MEMSET(pQParam->Content, pRMsg->Content, SIZE_MAX_LETTER_CONTENT);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SendAllLetter, this, m_character.AccountUniqueNumber, pQParam);	

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_LUCKY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2008-11-04 ~ 2008-11-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_LUCKY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_LUCKY_ITEM,
									MSG_FC_ITEM_USE_LUCKY_ITEM, pRMsg);
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}

	if(NULL == this->m_pCurrentBuildingNPC	// 2008-12-02 by cmkwon, 체크 추가
		|| (BUILDINGKIND_LUCKY != this->m_pCurrentBuildingNPC->BuildingKind && BUILDINGKIND_MYSTERY_SHOP != this->m_pCurrentBuildingNPC->BuildingKind))		// 2012-07-09 by hskim, 미스터리 머신 구현
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_COMMON_INVALID_BUILDINGKIND, m_pCurrentBuildingNPC?m_pCurrentBuildingNPC->BuildingKind:0);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_LUCKY_ITEM
	if(this->CheckTradingItem(pRMsg->ItemUID))
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_ITEM_TRADING, pRMsg->ItemUID);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUID);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUID);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemG->ItemInfo;
	if(!COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_LUCKY_ITEM)
		|| ITEMKIND_INGOT != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	// 2009-05-27 by cmkwon, 럭키머신/해피머신 인벤 요구 개수 다르게 처리 - 체크 처리, 아래와 같이 수정함.
	//if(m_ItemManager.GetInventoryItemCounts() + MaxPayLuckyMachineItem > CAtumSJ::GetMaxInventorySize(m_ItemManager.IsExistPremiumCard()))
	// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
	int nNeededInvenCnt = this->GetNeededInventoryCount(pItemInfo, pRMsg->MachineNum, m_pCurrentBuildingNPC->BuildingIndex);	
	if(m_ItemManager.GetInventoryItemCounts() + nNeededInvenCnt > m_ItemManager.GetMaxInventoryCount())
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, m_ItemManager.GetInventoryItemCounts(), nNeededInvenCnt);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_LUCKY_ITEM
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pItemInfo);
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_ALREADY_USE_ITEMPARAM, pItemInfo->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}

	// 슬롯 추첨
	BOOL bDeleteCoinItem = FALSE;	// 아이템이 하나라도 지급이 된다면 코인을 삭제한다.
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	Err_t ReturnError = this->LuckyItemWin(m_pCurrentBuildingNPC->BuildingIndex, pItemInfo, pRMsg->MachineNum, &bDeleteCoinItem);		// 2009-03-03 by dhjin, 럭키머신 수정안 - i_nMachineNum추가
	if(ERR_NO_ERROR != ReturnError)
	{
		if(bDeleteCoinItem)
		{
			CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);
			m_ItemManager.DeleteItemFromCharacterByItemNum(pItemG->ItemNum, 1, IUT_USE_ITEM,ITEM_IN_CHARACTER, TRUE, TRUE, TRUE, IUT_LUCKY_ITEM);	// 2012-11-21 by khkim, GLog 2차 
			SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ERR_LUCKYITEM_INSERT_BUT_COINITEM_DELETE);
			return RES_BREAK;
		}

		SendErrorMessage(T_FC_ITEM_USE_LUCKY_ITEM, ReturnError);
		return RES_BREAK;		
	}
	
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);
	m_ItemManager.DeleteItemFromCharacterByItemNum(pItemG->ItemNum, 1, IUT_USE_ITEM,ITEM_IN_CHARACTER, TRUE, TRUE, TRUE, IUT_LUCKY_ITEM);			// 2012-11-21 by khkim, GLog 2차 

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_DISSOLVED_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2010-08-31 by shcho&jskim 아이템용해 시스템 - 용해 시스템 패킷 처리
/// \author		shcho&jskim
/// \date		2010-09-02 ~
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_DISSOLVED_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 결과 패킷을 생성
	INIT_MSG_WITH_BUFFER(MSG_FC_DISSOLVED_SUCCESS_AND_FAILED,T_FC_DISSOLVED_ITEM_OK,sendMsg,SendBuf);
	sendMsg->Dissolved_success =  TRUE;	// 초기화

	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_DISSOLVED_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_DISSOLVED_ITEM, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}
	
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_DISSOLVED_ITEM, ERR_USING_BAZAAR, this->m_bazaarManager.GetBazaarState());
		return RES_BREAK;
	}
	
	if(NULL == this->m_pCurrentBuildingNPC	// 2008-12-02 by cmkwon, 체크 추가
		|| BUILDINGKIND_DISSOLUTION != this->m_pCurrentBuildingNPC->BuildingKind)
	{
		SendErrorMessage(T_FC_DISSOLVED_ITEM, ERR_COMMON_INVALID_BUILDINGKIND, m_pCurrentBuildingNPC?m_pCurrentBuildingNPC->BuildingKind:0);
		return RES_BREAK;
	}

	// 패킷 정의
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_DISSOLVED_ITEM, MSG_FC_DISSOLVED_ITEM, pRMsg);
	
	tDissolutionItemInfo tmpItemInfo;		// 용해 아이템 정보
	ITEM* ptmppAddItemInfo;	// 메모리에 저장될 아이템 정보
	INT					 ret;
	BOOL				 bsuccess = FALSE;
	MEMSET_ZERO(&tmpItemInfo, sizeof(tDissolutionItemInfo));
	
	// 아이템 받으면 아이템 체크
	tmpItemInfo = ms_pFieldIOCP->m_cDissolutionItemManager.CheckDissolutionItem(pRMsg->Itemnum);

	// 2013-07-17 by bckim, 베트남 용해관련 스탯증가 버그 수정 
	// 클라이언트에서 1차처리 후 2차처리 (장착중인 아이템은 올릴수 없음)
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->UniqueNumber);   // 
	if (NULL != pItemG && WEAR_ATTACHED == pItemG->Wear) 
	{
		SendErrorMessage(T_FC_DISSOLVED_ITEM,ERR_NOT_DISSOLVED_ITEM); // 에러 메세지 전송
		return RES_BREAK;
	}
	// End. 2013-07-17 by bckim, 베트남 용해관련 스탯증가 버그 수정 

	if( 0 == tmpItemInfo.ResultItemNum )
	{
		g_pGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FC_DISSOLVED_ITEM, ItemNum(%d) IS NOT DATA \r\n", tmpItemInfo.ResultItemNum);
		SendErrorMessage(T_FC_DISSOLVED_ITEM,ERR_NOT_DISSOLVED_ITEM); // 에러 메세지 전송
		sendMsg->Dissolved_success =  FALSE;
		SendAddData(SendBuf,MSG_SIZE(MSG_FC_DISSOLVED_SUCCESS_AND_FAILED)); 
		return RES_BREAK;
	}
	else
	{
		// 패킷을 생성
		INIT_MSG_WITH_BUFFER(MSG_FC_DISSOLVED_SUCCESS_AND_FAILED,T_FC_DISSOLVED_ITEM_OK,sendMsg,SendBuf);
		
		MSG_FC_DISSOLVED_SUCCESS_AND_FAILED tmpflag;
		MEMSET_ZERO(&tmpflag,sizeof(MSG_FC_DISSOLVED_SUCCESS_AND_FAILED));
		DissolutionItems tmpDItems;
		MEMSET_ZERO(&tmpDItems,sizeof(DissolutionItems));

		ms_pFieldIOCP->m_cDissolutionItemManager.CreateDissolutionItem(pRMsg->Itemnum, tmpItemInfo, &tmpDItems); // 용해 결과 아이템 생성

		for(int icnt = 0 ; icnt < SIZE_MAX_DISSOLUTION_ITEMS ; icnt++)
		{
			if(0 != tmpDItems.Itemcount[icnt]) // 값이 있으면 추가
			{
				// 내가 가진 아이템에 정보가 있나 찾아본다.
				ptmppAddItemInfo = ms_pFieldIOCP->GetItemInfo(tmpDItems.Itemnum[icnt]);
				
				if( NULL == ptmppAddItemInfo)
				{
					return RES_BREAK;
				}

				ITEM_GENERAL*		 pItemG = new ITEM_GENERAL(ptmppAddItemInfo);		// 받을 아이템G					
				pItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
				pItemG->Possess				= m_character.CharacterUniqueNumber;
				pItemG->ItemStorage			= ITEM_IN_CHARACTER;
				pItemG->CurrentCount		= tmpDItems.Itemcount[icnt];
				ret = this->m_ItemManager.InsertItemGeneralByPointer(pItemG,IUT_DISSOLUTION_ITEM); // insert 방식 변경
					
				if(FALSE == ret)
				{	// 정상적으로 추가되지 않았으면~에러
					SendErrorMessage(T_FC_DISSOLVED_ITEM,ERR_NOT_INSERT_DISSOLVED_ITEMS);
					g_pGlobal->WriteSystemLogEX(TRUE,"FunctionName : Process_FC_DISSOLVED_ITEM  ERROR NOT INSERT DISSOLVED ITEMS");
					SAFE_DELETE(pItemG);
					return RES_BREAK;
				}
				bsuccess = TRUE;
			}
		}

		sendMsg->Item_Success = bsuccess;
		sendMsg->Dissolved_success	= TRUE;	//용해 성공
		SendAddData(SendBuf,MSG_SIZE(MSG_FC_DISSOLVED_SUCCESS_AND_FAILED)); 
		//캐릭터가 융해 처리하려한 아이템 삭제 OK
		// 2013-08-05 by bckim, 용해 대상아이템 로그 추가
		ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->UniqueNumber);
		if( pItemGeneral != NULL ) 
		{
			CAtumLogSender::SendLogMessageITEMDissolutionITEM(this, pItemGeneral, 1, IUT_DISSOLUTION_ITEM);
		}
		// End. 2013-08-05 by bckim, 용해 대상아이템 로그 추가
		this->m_ItemManager.DeleteItemFromCharacterByUID(pRMsg->UniqueNumber, IUT_DISSOLUTION_ITEM); 	

	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::LuckyItemWin(ITEM * i_pItem, INT i_nMachineNum, BOOL * o_pbDeleteCoinItem)
/// \brief		
///				// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 기존 소스 수정 - 
/// \author		dhjin
/// \date		2008-11-10 ~ 2008-11-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::LuckyItemWin(INT i_buildingIdx, ITEM * i_pItem, INT i_nMachineNum, BOOL * o_pbDeleteCoinItem)
{
	if(NULL == i_pItem)	
	{
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 기존 소스 수정 - 아래와 같이 수정
// 	int count = 0;
// 	LUCKYITEM_DROP_INFO SLuckyItemInfo;
// 	MEMSET_ZERO(&SLuckyItemInfo, sizeof(LUCKYITEM_DROP_INFO));
// 
// 	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_LUCKY_ITEM_OK, T_FC_ITEM_USE_LUCKY_ITEM_OK, pSMsg, SendBuf);
// 	for(vectSLUCKY_MACHINE::iterator itr = ms_pFieldIOCP->m_vectLuckyMachine.begin(); itr != ms_pFieldIOCP->m_vectLuckyMachine.end(); itr++)
// 	{// 럭키머신을 검색
// 		if(i_pItem->ItemNum == itr->CoinItemNum
// 			&& this->m_pCurrentBuildingNPC->BuildingIndex == itr->BuildingIndex
// 			&& i_nMachineNum == itr->MachineNum				// 2009-03-03 by dhjin, 럭키머신 수정안
// 			)
// 		{// 럭키머신에 상점번호와 주화가 일치하면 슬롯 당첨여부를 계산한다.
// 			Prob1000K_t nRandValue = ms_pFieldIOCP->GetRandInt32(0, MAX_RAND1000K_VALUE);
// 			if(nRandValue > itr->SlotProbability)
// 			{
// 				pSMsg->LuckyItemSimpleInfo[count].SlotNum = itr->SlotNum;
// 				pSMsg->LuckyItemSimpleInfo[count].MysteryItemDropNum	= itr->MysteryItemDropNum;
// 				count++;
// 				continue;
// 			}
// 			
// 			// 2009-03-31 by dhjin, 럭키머신 로그
// 			MSG_FL_LOG_LUCKY_DROP LuckyDropLog;
// 			MEMSET_ZERO(&LuckyDropLog, sizeof(MSG_FL_LOG_LUCKY_DROP));
// 	
// 			// 당첨시 아이템 지급
// 			ms_pFieldIOCP->GetLuckyDropItem(this, itr->MysteryItemDropNum, &SLuckyItemInfo, &LuckyDropLog);	// 2009-03-31 by dhjin, 럭키머신 로그
// 			if(FALSE == SLuckyItemInfo.LuckItemUsing)
// 			{
//  				return ERR_PROTOCOL_NO_SUCH_ITEM;
// 			}
// 
// 			ITEM *pAddItemInfo	= ms_pFieldIOCP->GetItemInfo(SLuckyItemInfo.DropItemNum);
// 			if(NULL == pAddItemInfo)
// 			{
// 				return ERR_PROTOCOL_NO_SUCH_ITEM;
// 			}
// 			
// 			pSMsg->LuckyItemSimpleInfo[count].MysteryItemDropNum	= SLuckyItemInfo.MysteryItemDropNum;
// 			pSMsg->LuckyItemSimpleInfo[count].Itemnum	= pAddItemInfo->ItemNum;
// 			pSMsg->LuckyItemSimpleInfo[count].n64ResultCounts	= RANDI(SLuckyItemInfo.MinCount, SLuckyItemInfo.MaxCount);
// 			if(0 >= pSMsg->LuckyItemSimpleInfo[count].n64ResultCounts)
// 			{
// 				return ERR_PROTOCOL_INVALID_ITEM_COUNT;
// 			}
// 
// 			if(FALSE == IS_COUNTABLE_ITEM(pAddItemInfo->Kind))
// 			{// 2007-05-11 by cmkwon, 넌카운터블 아이템
// 				ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
// 				pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
// 				pAddItemG->Possess				= m_character.CharacterUniqueNumber;
// 				pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
// 				
// 				this->ApplyGambleRareFix(pAddItemG, SLuckyItemInfo.PrefixProbability, SLuckyItemInfo.SuffixProbability);
// 				
// 				pSMsg->LuckyItemSimpleInfo[count].nPrefixCodeNum0	= pAddItemG->PrefixCodeNum;
// 				pSMsg->LuckyItemSimpleInfo[count].nSuffixCodeNum0	= pAddItemG->SuffixCodeNum;
// 				if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_LUCKY_ITEM))
// 				{
// 					if(*o_pbDeleteCoinItem)
// 					{
// 						g_pFieldGlobal->WriteSystemLogEX(TRUE, "LuckyItem Insert Error!!!, CharacterUID = %d, Itemnum = %d, ItemPrefixCode = %d, ItemSuffixCode = %d, ItemCount = %d \r\n"
// 													, this->m_character.CharacterUniqueNumber, pAddItemG->ItemNum, pAddItemG->PrefixCodeNum, pAddItemG->SuffixCodeNum, pSMsg->LuckyItemSimpleInfo[count].n64ResultCounts);
// 					}
// 					SAFE_DELETE(pAddItemG);
// 					return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
// 				}
// 			}
// 			else
// 			{// 2007-05-11 by cmkwon, 카운터블 아이템
// 				ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
// 				pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
// 				pAddItemG->Possess				= m_character.CharacterUniqueNumber;
// 				pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
// 				pAddItemG->CurrentCount			= pSMsg->LuckyItemSimpleInfo[count].n64ResultCounts;
// 				
// 				if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_LUCKY_ITEM))
// 				{
// 					if(*o_pbDeleteCoinItem)
// 					{
// 						g_pFieldGlobal->WriteSystemLogEX(TRUE, "LuckyItem Insert Error!!!, CharacterUID = %d, Itemnum = %d, ItemPrefixCode = %d, ItemSuffixCode = %d, ItemCount = %d \r\n"
// 													, this->m_character.CharacterUniqueNumber, pAddItemG->ItemNum, pAddItemG->PrefixCodeNum, pAddItemG->SuffixCodeNum, pSMsg->LuckyItemSimpleInfo[count].n64ResultCounts);
// 					}
// 					SAFE_DELETE(pAddItemG);
// 					return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
// 				}
// 			}
// 
// 			*o_pbDeleteCoinItem = TRUE;	// 아이템이 하나라도 지급이 된다면 코인을 삭제한다.
// 			
// 			if(FALSE != SLuckyItemInfo.Period)
// 			{// 2008-11-26 by dhjin, 기간제이면 카운트 업데이트
// 				QPARAM_UPDATE_LUCKYITEM_DROPCOUNT *pQParam = new QPARAM_UPDATE_LUCKYITEM_DROPCOUNT;
// 				pQParam->MysteryItemDropNum		= SLuckyItemInfo.MysteryItemDropNum;
// 				pQParam->DropItemNum			= SLuckyItemInfo.DropItemNum;
// 				pQParam->DropCount				= 1;
// 				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLuckyItemDropCount, this, m_character.AccountUniqueNumber, pQParam);
// 				// 2009-03-31 by dhjin, 럭키머신 로그
// 				CAtumLogSender::SendLogMessageLuckyDrop(&LuckyDropLog);
// 			}
// 
// 			pSMsg->LuckyItemSimpleInfo[count].SlotNum = itr->SlotNum;
// 			count++;
// 
// 			MEMSET_ZERO(&SLuckyItemInfo, sizeof(LUCKYITEM_DROP_INFO));
// 		}
// 	}
// 
// 	if(0 >= count)
// 	{
// 		return ERR_PROTOCOL_NO_SUCH_SHOP_ITEM;
// 	}
// 
// 	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_LUCKY_ITEM_OK));
// 
// 	return ERR_NO_ERROR;
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 기존 소스 수정 - 
	vectSLUCKY_MACHINEPtr	tmLuckyItemList;
	ms_pFieldIOCP->GetLuckyMachineItemList(&tmLuckyItemList, i_buildingIdx, i_nMachineNum, i_pItem->ItemNum);
	if(tmLuckyItemList.empty())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# No such LuckyMachineItemList !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) \r\n"
			, GetCharacterString(GetCharacter(), string()), i_buildingIdx, i_nMachineNum, i_pItem->ItemNum);
		return ERR_PROTOCOL_NO_SUCH_SHOP_ITEM;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_LUCKY_ITEM_OK, T_FC_ITEM_USE_LUCKY_ITEM_OK, pSMsg, SendBuf);
	vectSLUCKY_MACHINEPtr::iterator itr(tmLuckyItemList.begin());
	for(; itr != tmLuckyItemList.end(); itr++)
	{
		SLUCKY_MACHINE *pLuckyItem = *itr;

		int nSlotIndex = pLuckyItem->SlotNum - 1;
		if(MaxPayLuckyMachineItem < pLuckyItem->SlotNum							// 최대 슬롯 오버
			|| 0 != pSMsg->LuckyItemSimpleInfo[nSlotIndex].Itemnum)	// 이미 아이템 설정된 슬롯
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# invalid slot !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) SlotNum(%d) CurSlotIdx(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, pLuckyItem->SlotNum, nSlotIndex);
			continue;
		}
		pSMsg->LuckyItemSimpleInfo[nSlotIndex].SlotNum				= pLuckyItem->SlotNum;
		pSMsg->LuckyItemSimpleInfo[nSlotIndex].MysteryItemDropNum	= pLuckyItem->MysteryItemDropNum;

		Prob1000K_t nRandValue = ms_pFieldIOCP->GetRandInt32(0, MAX_RAND1000K_VALUE);
		if(nRandValue > pLuckyItem->SlotProbability)
		{// 2010-04-20 by cmkwon, 
			continue;
		}

		LUCKYITEM_DROP_INFO		SLuckyItemInfo;		MEMSET_ZERO(&SLuckyItemInfo, sizeof(LUCKYITEM_DROP_INFO));
		MSG_FL_LOG_LUCKY_DROP	LuckyDropLog;		MEMSET_ZERO(&LuckyDropLog, sizeof(MSG_FL_LOG_LUCKY_DROP));
		
		// 당첨시 아이템 지급
		ms_pFieldIOCP->GetLuckyDropItem(this, pLuckyItem->MysteryItemDropNum, &SLuckyItemInfo, &LuckyDropLog);
		if(FALSE == SLuckyItemInfo.LuckItemUsing)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# No such DropNumItem !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) MysteryItemDropNum(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, pLuckyItem->MysteryItemDropNum);
			return ERR_PROTOCOL_NO_SUCH_ITEM;
		}

		ITEM *pAddItemInfo	= ms_pFieldIOCP->GetItemInfo(SLuckyItemInfo.DropItemNum);
		if(NULL == pAddItemInfo)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# No such ItemInfo !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) ItemNum(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, SLuckyItemInfo.DropItemNum);
			return ERR_PROTOCOL_NO_SUCH_ITEM;
		}

		pSMsg->LuckyItemSimpleInfo[nSlotIndex].Itemnum				= pAddItemInfo->ItemNum;
		pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts		= (FALSE == IS_COUNTABLE_ITEM(pAddItemInfo->Kind)) ? 1 : RANDI(SLuckyItemInfo.MinCount, SLuckyItemInfo.MaxCount);
		if(0 >= pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# invalid item count !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) ItemNum(%d) ItemCnt(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, SLuckyItemInfo.DropItemNum, pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts);
			return ERR_PROTOCOL_INVALID_ITEM_COUNT;
		}

		if(FALSE == IS_COUNTABLE_ITEM(pAddItemInfo->Kind))
		{// 2007-05-11 by cmkwon, 넌카운터블 아이템
			ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
			pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
			pAddItemG->Possess				= m_character.CharacterUniqueNumber;
			pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
			
			this->ApplyGambleRareFix(pAddItemG, SLuckyItemInfo.PrefixProbability, SLuckyItemInfo.SuffixProbability);
			
			pSMsg->LuckyItemSimpleInfo[nSlotIndex].nPrefixCodeNum0	= pAddItemG->PrefixCodeNum;
			pSMsg->LuckyItemSimpleInfo[nSlotIndex].nSuffixCodeNum0	= pAddItemG->SuffixCodeNum;
			if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_LUCKY_ITEM))
			{
				if(*o_pbDeleteCoinItem)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# call InsertItemGeneralByPointer# error !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) ItemNum(%d) ItemCnt(%d) Prefix(%d) Suffix(%d) \r\n"
						, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, SLuckyItemInfo.DropItemNum, pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts, pAddItemG->PrefixCodeNum, pAddItemG->SuffixCodeNum);
				}
				SAFE_DELETE(pAddItemG);
				return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
			}
		}
		else
		{// 2007-05-11 by cmkwon, 카운터블 아이템
			ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
			pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
			pAddItemG->Possess				= m_character.CharacterUniqueNumber;
			pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
			pAddItemG->CurrentCount			= pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts;
			
			if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_LUCKY_ITEM))
			{
				if(*o_pbDeleteCoinItem)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::LuckyItemWin# call InsertItemGeneralByPointer# error !!, %s BuildingIdx(%d) MachineNum(%d) CoinItemNum(%d) ItemNum(%d) ItemCnt(%d) Prefix(%d) Suffix(%d) \r\n"
						, GetCharacterString(GetCharacter(), string()), pLuckyItem->BuildingIndex, pLuckyItem->MachineNum, pLuckyItem->CoinItemNum, SLuckyItemInfo.DropItemNum, pSMsg->LuckyItemSimpleInfo[nSlotIndex].n64ResultCounts, pAddItemG->PrefixCodeNum, pAddItemG->SuffixCodeNum);
				}
				SAFE_DELETE(pAddItemG);
				return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
			}
		}

		*o_pbDeleteCoinItem		= TRUE;			// 아이템이 하나라도 지급이 된다면 코인을 삭제한다.

		if(FALSE != SLuckyItemInfo.Period)
		{// 2008-11-26 by dhjin, 기간제이면 카운트 업데이트
			QPARAM_UPDATE_LUCKYITEM_DROPCOUNT *pQParam = new QPARAM_UPDATE_LUCKYITEM_DROPCOUNT;
			pQParam->MysteryItemDropNum		= SLuckyItemInfo.MysteryItemDropNum;
			pQParam->DropItemNum			= SLuckyItemInfo.DropItemNum;
			pQParam->DropCount				= 1;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLuckyItemDropCount, this, m_character.AccountUniqueNumber, pQParam);
			// 2009-03-31 by dhjin, 럭키머신 로그
			CAtumLogSender::SendLogMessageLuckyDrop(&LuckyDropLog);
		}
	}
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_LUCKY_ITEM_OK));

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			int CFieldIOCPSocket::GetNeededInventoryCount(ITEM * i_pItem, INT i_nMachineNum, UINT i_nBuildingIdx)
/// \brief		// 2009-05-27 by cmkwon, 럭키머신/해피머신 인벤 요구 개수 다르게 처리 - 함수 추가
/// \author		jwlee
/// \date		2009-05-26 ~ 2009-05-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int CFieldIOCPSocket::GetNeededInventoryCount(ITEM * i_pItem, INT i_nMachineNum, UINT i_nBuildingIdx)
{
	if(NULL == i_pItem)	
	{
		return MaxPayLuckyMachineItem;	// 최대 필요 개수 리턴
	}

// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 기존 소스 수정 - 
// 	vectSLUCKY_MACHINE::iterator itr = ms_pFieldIOCP->m_vectLuckyMachine.begin();
// 	for(; itr != ms_pFieldIOCP->m_vectLuckyMachine.end(); itr++)
// 	{//럭키 머신을 검색
// 		if(i_pItem->ItemNum == itr->CoinItemNum
// 			&& i_nBuildingIdx == itr->BuildingIndex
// 			&& i_nMachineNum == itr->MachineNum)
// 		{
// 			switch(itr->MachineKind)
// 			{
// 				case 1:			return 1;	// 해피머신 필요 인벤 공간
// 				case 3:			return MaxPayLuckyMachineItem;	// 럭키머신 필요 인벤 공간
// 				default:		return MaxPayLuckyMachineItem;	// 알 수 없음 - 최대 필요 개수 리턴
// 			}
// 		}
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 기존 소스 수정 - 
	int nMachineKind = ms_pFieldIOCP->GetLuckyMachineKind(i_nBuildingIdx, i_nMachineNum, i_pItem->ItemNum);	
	return CAtumSJ::GetLuckyMachineSlotCount(nMachineKind);	// 최대 필요 개수 리턴
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_MISSIONMASTER_HELP(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		미션마스터들을 랜덤하게 찾아 도움을 요청한다.
/// \author		dhjin
/// \date		2008-12-08 ~ 2008-12-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_MISSIONMASTER_HELP(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_REQUEST_MISSIONMASTER_HELP
									, MSG_FC_QUEST_REQUEST_MISSIONMASTER_HELP, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_MISSIONMASTER_HELP, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}		

	// 2010-03-30 by cmkwon, 미션마스터 요청시 완료된 미션 여부 체크 추가(E0044510) - 
	if(IsCheckQuestComplited(pRMsg->QuestIdx))
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_MISSIONMASTER_HELP, ERR_PROTOCOL_QUEST_ALREADY_COMPLETED, pRMsg->QuestIdx);
		return RES_BREAK;
	}

	CFieldParty *pFParty = this->m_pFieldParty;
	if(NULL == pFParty)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_MISSIONMASTER_HELP, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}
	
	if(0 == m_VecMissionMasterIOCPSocket.size())
	{
		ms_pFieldIOCP->SearchMissionMaster(pRMsg->QuestIdx, this, &m_VecMissionMasterIOCPSocket);
		if(0 == m_VecMissionMasterIOCPSocket.size())
		{
			SendErrorMessage(T_FC_QUEST_REQUEST_MISSIONMASTER_HELP, ERR_NO_SEARCH_CHARACTER);
			return RES_BREAK;		
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_MISSIONMASTER_HELP_INVITE, T_FC_QUEST_REQUEST_MISSIONMASTER_HELP_INVITE, pSMsg, SendBuf);
	pSMsg->ClientIdx		= this->m_character.ClientIndex;
	pSMsg->CharacterUID		= this->m_character.CharacterUniqueNumber;
	STRNCPY_MEMSET(pSMsg->CharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pSMsg->PartyID			= this->m_pFieldParty->m_PartyID;
	ms_pFieldIOCP->SendHelpMissionMaster(&m_VecMissionMasterIOCPSocket, SendBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_MISSIONMASTER_HELP_INVITE));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckQuestComplete(INT i_nQuestIdx)
/// \brief		해당 퀘스트를 완료했는지 체크한다.
/// \author		dhjin
/// \date		2008-12-09 ~ 2008-12-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckQuestComplete(INT i_nQuestIdx)
{
	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest

	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest = m_mapQuest.begin();
	for(; itrQuest != m_mapQuest.end(); itrQuest++)
	{
		CharacterQuest *pCharacterQuest = &itrQuest->second;
		if (m_character.CharacterUniqueNumber == pCharacterQuest->CharacterUniqueNumber 
			&& i_nQuestIdx == pCharacterQuest->QuestIndex
			&& QUEST_STATE_COMPLETED == pCharacterQuest->QuestState)
		{
			return TRUE;
		}
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MISSIONMASTER_HELP_INVITE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		미션마스터 승인 처리이다. 파티에 가입시킨 후 미션마스터 플래그를 설정한다.
/// \author		dhjin
/// \date		2008-12-09 ~ 2008-12-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MISSIONMASTER_HELP_INVITE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_MISSIONMASTER_HELP_INVITE
									, MSG_FC_QUEST_MISSIONMASTER_HELP_INVITE, pRMsg);

	CFieldIOCPSocket * HelpFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->CharacterUID);
	if(NULL == HelpFISoc
		|| FALSE == HelpFISoc->IsValidCharacter(FALSE)
		|| NULL == HelpFISoc->m_pFieldParty)
	{
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}
	PartyID_t reqUserPartyID = HelpFISoc->m_pFieldParty->m_PartyID;

	// 2008-12-09 by dhjin, 미션마스터가 퀘스트 진행중이면 오류 보내기
	mt_auto_lock mqLock(&m_mapQuest);		// lock m_mapQuest
	CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();
	if (pFCharQuest != NULL && pFCharQuest->QuestState == QUEST_STATE_IN_PROGRESS)
	{
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_QUEST_IS_IN_PROGRESS);
		return RES_BREAK;
	}
	mqLock.auto_unlock_cancel();

	if (this->m_pFieldParty)
	{// 2008-12-09 by dhjin, 미션마스터가 파티가 있으면 오류
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_PARTY_MEMBER_ALREADY_EXISTS);
		return RES_BREAK;
	}

	// 2013-08-30 by bckim, 필드이동금지아이템
	if( this->m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(DES_MOVEMENT_RESTRICTION_TAKE) )
	{
		this->SendString128(STRING_128_USER_NOTICE,STRMSG_130830_0002);
		return RES_BREAK;
	}
	// End. 2013-08-30 by bckim, 필드이동금지아이템

	// lock m_MapParties
	mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);
	CFieldParty *pParty = ms_pFieldIOCP->m_MapParties.findLock(reqUserPartyID);
	if (NULL == pParty)
	{
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_NO_SUCH_PARTY);
		return RES_BREAK;
	}

	mt_auto_lock pmlock(&pParty->m_ListPartyMember);

	FieldPartyMember tmpMember;
	if ( TRUE == pParty->GetMemberByCharacterUniqueNumber(m_character.CharacterUniqueNumber, tmpMember)
		|| NULL != m_pFieldParty)
	{
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_PARTY_MEMBER_ALREADY_EXISTS);
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0077);
		return RES_BREAK;
	}

	if (pParty->GetMasterCharacterUniqueNumber() == m_character.CharacterUniqueNumber)
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0078);
		return RES_BREAK;
	}

	if (pParty->m_PeerBattlePartyID != 0 || pParty->m_PeerBattleRequesterPartyID != 0)
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0079);
		return RES_BREAK;
	}

	if (pParty->m_FieldPartyInfo.nTotalPartyMember >= SIZE_MAX_PARTY_MEMBER)
	{
		SendErrorMessage(T_FC_QUEST_MISSIONMASTER_HELP_INVITE, ERR_PROTOCOL_ALREADY_MAX_PARTY_MEMBER);
		return RES_BREAK;
	}
	pmlock.auto_unlock_cancel();
	pslock.auto_unlock_cancel();

	// 파티원 및 필드 서버들에게 PARTY_ACCEPT_INVITE_OK를 보내도록 IM Server에 요청한다.
	INIT_MSG_WITH_BUFFER(MSG_FI_PARTY_ACCEPT_INVITE_OK, T_FI_PARTY_ACCEPT_INVITE_OK, msgAcceptInviteOK, msgAcceptInviteOKBuf);
	msgAcceptInviteOK->PartyID = reqUserPartyID;
	msgAcceptInviteOK->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	msgAcceptInviteOK->FieldPartyInfo.nTotalPartyMember = 0;	// 이 MSG가 F->I일 때는 무시함
	msgAcceptInviteOK->FieldPartyInfo.lowestMemberLevel = 0;	// 이 MSG가 F->I일 때는 무시함
	ms_pFieldIOCP->m_pIMWinSocket->Write((char*)msgAcceptInviteOKBuf, MSG_SIZE(MSG_FI_PARTY_ACCEPT_INVITE_OK));

	m_bMissionMaster = TRUE;

	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_MISSIONMASTER_HELP_INVITE_OK, T_FC_QUEST_MISSIONMASTER_HELP_INVITE_OK, pSMsg, SendBuf);
	pSMsg->ClientIdx		= this->m_character.ClientIndex;
	pSMsg->CharacterUID		= this->m_character.CharacterUniqueNumber;
	STRNCPY_MEMSET(pSMsg->CharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	HelpFISoc->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_MISSIONMASTER_HELP_INVITE_OK));


	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MISSIONMASTER_HELP_REJECT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		미션마스터 요청 취소 처리. 미션마스터 요청자에게 취소 사실을 알려준다.
/// \author		dhjin
/// \date		2008-12-09 ~ 2008-12-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MISSIONMASTER_HELP_REJECT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_MISSIONMASTER_HELP_REJECT
									, MSG_FC_QUEST_MISSIONMASTER_HELP_REJECT, pRMsg);
	
	CFieldIOCPSocket * HelpFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->CharacterUID);
	if(NULL == HelpFISoc)
	{
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_MISSIONMASTER_HELP_REJECT_OK, T_FC_QUEST_MISSIONMASTER_HELP_REJECT_OK, pSMsg, SendBuf);
	pSMsg->ClientIdx		= this->m_character.ClientIndex;
	pSMsg->CharacterUID		= this->m_character.CharacterUniqueNumber;
	STRNCPY_MEMSET(pSMsg->CharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	HelpFISoc->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_MISSIONMASTER_HELP_REJECT_OK));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::MissionMasterQuestResult(CQuest *pQuestInfo)
/// \brief		미션마스터 - 미션마스터 보상 지급
/// \author		dhjin
/// \date		2008-12-09 ~ 2008-12-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::MissionMasterQuestResult(CQuest *pQuestInfo)
{
// 2009-01-15 by cmkwon, 미션 마스터 보상 버그 수정 - 아래와 같이 수정 함.
// 	CFieldParty *pFParty = this->m_pFieldParty;
// 	if(pFParty)
// 	{		
// 		float	fDropRateOfGameRestriction	= 0.0f;
// 
// 		pFParty->m_ListPartyMember.lock();
// 		int nSize = pFParty->m_ListPartyMember.size();
// 		for(int i=0; i < nSize; i++)
// 		{
// 			CFieldIOCPSocket *pSocket = pFParty->m_ListPartyMember[i].PM_CharacterSocket;
// 			if (pSocket
// 				&& pSocket != this
// 				&& pSocket->IsValidCharacter(FALSE)
// 				&& TRUE == pSocket->m_bMissionMaster
// 				&& (USER_INFO_OPTION_MISSIONMASTER & pSocket->m_character.SecretInfoOption)
// 				&& pSocket->GetCurrentFieldMapChannel() == this->GetCurrentFieldMapChannel()
// 				&& pSocket->CheckQuestComplete(pQuestInfo->QuestIndex)				
// 				&& !(pSocket->GPGetApplyRateByGamePlayingTime(&fDropRateOfGameRestriction)
// 					&& fDropRateOfGameRestriction <= 0.0f)
// 				)
// 			{
// 				for (i = 0; i < pQuestInfo->EndMissionMasterPayItemVector.size(); i++)
// 				{
// 					QUEST_PAY_ITEM &tmpQestPayItem = pQuestInfo->EndMissionMasterPayItemVector[i];
// 
// 					if (!IS_SAME_UNITKIND(tmpQestPayItem.ToUnitKind, pSocket->m_character.UnitKind))
// 					{
// 						// 해당 unitkind가 다름
// 						continue;
// 					}
// 
// 					int nPayItemCount = 0;
// 					if (tmpQestPayItem.PerItem != 0)
// 					{
// 						ITEM_GENERAL *pItemGeneral = pSocket->m_ItemManager.GetFirstItemGeneralByItemNum(tmpQestPayItem.PerItem);
// 						if (pItemGeneral == NULL)
// 						{
// 							continue;
// 						}
// 						nPayItemCount = pItemGeneral->CurrentCount * tmpQestPayItem.Count;
// 					}
// 					else
// 					{
// 						nPayItemCount = tmpQestPayItem.Count;
// 					}
// 
// 					// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 퀘스트 보상 아이템에 드랍율 적용 
// 					nPayItemCount = max(1, (int)(nPayItemCount * fDropRateOfGameRestriction));
// 
// 					if (!pSocket->m_ItemManager.InsertItemBaseByItemNum(tmpQestPayItem.ItemNum, nPayItemCount, IUT_QUEST))
// 					{
// 						g_pFieldGlobal->WriteSystemLogEX(TRUE,
// 							"FATAL ERROR@CFieldIOCPSocket::MissionMasterQuestResult(): cannot insert item %d to %s\r\n",
// 							tmpQestPayItem.ItemNum, GetCharacterString(&pSocket->m_character, string()));
// 						continue;
// 					}
// 					
// 				}// for (i = 0; i < pQuestInfo->EndMissionMasterPayItemVector.size(); i++)
// 			}
// 			fDropRateOfGameRestriction	= 0.0f;
// 		}// for(int i=0; i < nSize; i++)
// 		pFParty->m_ListPartyMember.unlock();
// 	}// if(pFParty)

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-15 by cmkwon, 미션 마스터 보상 버그 수정 - 
	if(NULL == m_pFieldParty)
	{
		return;
	}

	vectCFieldIOCPSocket vectCFISockList;
	if(FALSE == this->GetPartyMemberList(&vectCFISockList))
	{
		return;
	}

	vectCFieldIOCPSocket::iterator itr(vectCFISockList.begin());
	for(; itr != vectCFISockList.end(); itr++)
	{
		CFieldIOCPSocket *ptmFISoc = *itr;
		
		float	fDropRateOfGameRestriction	= 0.0f;
		if (ptmFISoc
			&& ptmFISoc != this
			&& ptmFISoc->IsValidCharacter(FALSE)
			&& TRUE == ptmFISoc->m_bMissionMaster
			&& (USER_INFO_OPTION_MISSIONMASTER & ptmFISoc->m_character.SecretInfoOption)
			&& ptmFISoc->GetCurrentFieldMapChannel() == this->GetCurrentFieldMapChannel()
			&& ptmFISoc->CheckQuestComplete(pQuestInfo->QuestIndex)				
			&& !(ptmFISoc->GPGetApplyRateByGamePlayingTime(&fDropRateOfGameRestriction)	&& fDropRateOfGameRestriction <= 0.0f) )
		{
			for (int i = 0; i < pQuestInfo->EndMissionMasterPayItemVector.size(); i++)
			{
				QUEST_PAY_ITEM &tmpQestPayItem = pQuestInfo->EndMissionMasterPayItemVector[i];
				
				if (!IS_SAME_UNITKIND(tmpQestPayItem.ToUnitKind, ptmFISoc->m_character.UnitKind))
				{
					// 해당 unitkind가 다름
					continue;
				}
				
				// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 퀘스트 보상 아이템에 드랍율 적용 
				int nPayItemCount = max(1, (int)(tmpQestPayItem.Count * fDropRateOfGameRestriction));				
				if (!ptmFISoc->m_ItemManager.InsertItemBaseByItemNum(tmpQestPayItem.ItemNum, nPayItemCount, IUT_QUEST))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE,
						"FATAL ERROR@CFieldIOCPSocket::MissionMasterQuestResult(): cannot insert item %d to %s\r\n",
						tmpQestPayItem.ItemNum, GetCharacterString(&ptmFISoc->m_character, string()));
					continue;
				}				
			}// for (i = 0; i < pQuestInfo->EndMissionMasterPayItemVector.size(); i++)
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ArrangeAllPartyMember(vectCFieldIOCPSocket *i_pvectCFISockList)
/// \brief		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - 
/// \author		cmkwon
/// \date		2008-12-30 ~ 2008-12-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ArrangeAllPartyMember(vectCFieldIOCPSocket *i_pvectCFISockList)
{
	if(i_pvectCFISockList->empty())
	{
		return FALSE;
	}

	vectCFieldIOCPSocket::iterator itr(i_pvectCFISockList->begin());
	for(; itr != i_pvectCFISockList->end(); itr++)
	{
		CFieldIOCPSocket *pFISoc = *itr;
		if(pFISoc && pFISoc->IsValidCharacter(FALSE))
		{
			pFISoc->ArrangePartyMemberList(i_pvectCFISockList);
		}
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ArrangePartyMemberList(vectCFieldIOCPSocket *i_pvectCFISockList)
/// \brief		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - 
/// \author		cmkwon
/// \date		2008-12-30 ~ 2008-12-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ArrangePartyMemberList(vectCFieldIOCPSocket *i_pvectCFISockList)
{
	mt_auto_lock mtA(&m_mtvectCFISockPartyMemberList);
	
	// 2008-12-30 by cmkwon, 비우기
	this->CleanPartyMemberList();

	if(i_pvectCFISockList->empty())
	{
		return FALSE;
	}
	
	// 2008-12-30 by cmkwon, 자신을 포함한 모든 파티원 리스트
	m_mtvectCFISockPartyMemberList.insert(m_mtvectCFISockPartyMemberList.begin(), i_pvectCFISockList->begin(), i_pvectCFISockList->end());
	
	return TRUE;
}

struct Sfind_if_ClientIndex_t
{
	Sfind_if_ClientIndex_t(ClientIndex_t i_cliIdx): m_CliIdx(i_cliIdx){};
	bool operator()(const ClientIndex_t i_cliIdx)
	{
		return i_cliIdx == m_CliIdx;
	}
	ClientIndex_t m_CliIdx;
};

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GetPartyMemberList(vectCFieldIOCPSocket *o_pvectCFISockList)
/// \brief		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - 
/// \author		cmkwon
/// \date		2008-12-29 ~ 2008-12-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetPartyMemberList(vectCFieldIOCPSocket *o_pvectCFISockList)
{
	mt_auto_lock mtA(&m_mtvectCFISockPartyMemberList);
	if(m_mtvectCFISockPartyMemberList.empty())
	{
		return FALSE;
	}
	o_pvectCFISockList->insert(o_pvectCFISockList->begin(), m_mtvectCFISockPartyMemberList.begin(), m_mtvectCFISockPartyMemberList.end());
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::CleanPartyMemberList(void)
/// \brief		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - 
/// \author		cmkwon
/// \date		2008-12-29 ~ 2008-12-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::CleanPartyMemberList(void)
{
	mt_auto_lock mtA(&m_mtvectCFISockPartyMemberList);
	m_mtvectCFISockPartyMemberList.clearLock();
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::SetPartyFormationSkillNum
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetPartyFormationSkillNum(int i_nSkillNum)
{
	m_nPartyFormationSkillNum = i_nSkillNum;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::GetPartyFormationSkillNum
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int CFieldIOCPSocket::GetPartyFormationSkillNum(void)
{
	return m_nPartyFormationSkillNum;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::FindPartyFormationSkill
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM_SKILL * CFieldIOCPSocket::FindPartyFormationSkill(BYTE i_byFormationTy)
{
	int nSkillNum = CAtumSJ::FindPartyFormationSkillNum(i_byFormationTy);
	if(0 == nSkillNum)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] PFS Error(CFieldIOCPSocket::FindPartyFormationSkill#) 13000 !! FormationTy(%d) SkillNum(%d) \r\n", i_byFormationTy, nSkillNum);

		return NULL;
	}

	return ms_pFieldIOCP->SearchPartyFormationSkill(nSkillNum);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::ChangePartyFormationSkill
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ChangePartyFormationSkill(vectCFieldIOCPSocket *i_pvectPartyMemList, BOOL i_bOnOff, BYTE i_byFormationTy)
{
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804 1 CFieldIOCPSocket::ChangePartyFormationSkill# %s vectSize(%d) IsOn(%d) FormationTy(%d) \r\n"
//		, GetCharacterString(GetCharacter(), string()), i_pvectPartyMemList->size(), i_bOnOff, i_byFormationTy);

	if(FALSE == i_bOnOff)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2009-08-04 by cmkwon, 편대 스킬 해제 처리
		vectCFieldIOCPSocket::iterator itr(i_pvectPartyMemList->begin());
		for(; itr != i_pvectPartyMemList->end(); itr++)
		{
			CFieldIOCPSocket *pFISoc = *itr;
			if(NULL == pFISoc
				|| FALSE == pFISoc->IsValidCharacter(FALSE))
			{
				continue;
			}

			pFISoc->ReleasePartyFormationSkill(2);
		}
	}
	else
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2009-08-04 by cmkwon, 편대 스킬 적용 처리
		ITEM_SKILL *pItemSkill = this->FindPartyFormationSkill(i_byFormationTy);
		if(NULL == pItemSkill)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] PFS Error(CFieldIOCPSocket::ChangePartyFormationSkill#) 11000 !! %s FormationTy(%d) pItemSkill(0x%X) \r\n"
				, GetCharacterString(GetCharacter(), string()), i_byFormationTy, pItemSkill);
			return;
		}

		vectCFieldIOCPSocket::iterator itr(i_pvectPartyMemList->begin());
		for(; itr != i_pvectPartyMemList->end(); itr++)
		{
			CFieldIOCPSocket *pFISoc = *itr;
			if(NULL == pFISoc
				|| FALSE == pFISoc->IsValidCharacter(FALSE))
			{
				continue;
			}

			pFISoc->ApplyPartyFormationSkill(pItemSkill);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::ApplyPartyFormationSkill
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ApplyPartyFormationSkill(ITEM_SKILL *i_pSkill)
{
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 090804 1 CFieldIOCPSocket::ApplyPartyFormationSkill# %s %d %d \r\n", GetCharacterString(GetCharacter(), string()), GetPartyFormationSkillNum(), i_pSkill->ItemNum);

	int nPartySkillNum = this->GetPartyFormationSkillNum();
	if(nPartySkillNum)
	{
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 090804 2 CFieldIOCPSocket::ApplyPartyFormationSkill# %s %d %d \r\n", GetCharacterString(GetCharacter(), string()), GetPartyFormationSkillNum(), i_pSkill->ItemNum);

		this->ReleasePartyFormationSkill(3);
	}
	
	// 2009-08-04 by cmkwon, 1. 클라이언트에 스킬 적용 메시지 전달 처리
	MSG_FC_SKILL_USE_SKILL msgUseSkill;
	MEMSET_ZERO(&msgUseSkill, sizeof(msgUseSkill));
	msgUseSkill.SkillItemID.ItemUID		= i_pSkill->UniqueNumber;
	msgUseSkill.SkillItemID.ItemNum		= i_pSkill->ItemNum;
	if(FALSE == this->m_SkillManager.UseSkill(i_pSkill, &msgUseSkill))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] PFS Error(CFieldIOCPSocket::ApplyPartyFormationSkill#) 11000 !! %s %d \r\n"
			, GetCharacterString(GetCharacter(), string()), nPartySkillNum);
		return FALSE;
	}
	this->SetPartyFormationSkillNum(i_pSkill->ItemNum);

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::ReleasePartyFormationSkill
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ReleasePartyFormationSkill(int i_nTemp/*=0*/)
{
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804 CFieldIOCPSocket::ReleasePartyFormationSkill# 1 %s %d PosTemp(%d) \r\n", GetCharacterString(GetCharacter(), string()), GetPartyFormationSkillNum(), i_nTemp);

	int nPartySkillNum = this->GetPartyFormationSkillNum();
	if(0 == nPartySkillNum)
	{
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804 CFieldIOCPSocket::ReleasePartyFormationSkill# 2 %s %d \r\n", GetCharacterString(GetCharacter(), string()), nPartySkillNum);

		return FALSE;
	}

	ITEM_SKILL *pBeforeSkill = ms_pFieldIOCP->SearchPartyFormationSkill(nPartySkillNum);
	if(pBeforeSkill)
	{
		MSG_FC_SKILL_CANCEL_SKILL msgCancelSkill;
		MEMSET_ZERO(&msgCancelSkill, sizeof(msgCancelSkill));
		msgCancelSkill.SkillItemID.ItemNum		= pBeforeSkill->ItemNum;
		msgCancelSkill.SkillItemID.ItemUID		= pBeforeSkill->UniqueNumber;
		m_SkillManager.CancelSkill(pBeforeSkill->ItemInfo, &msgCancelSkill);
	}
	else
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] PFS Error(CFieldIOCPSocket::ReleasePartyFormationSkill#) 11000 !! %s %d \r\n"
			, GetCharacterString(GetCharacter(), string()), nPartySkillNum);
	}
	this->SetPartyFormationSkillNum(0);		// 2009-08-05 by cmkwon, 초기화

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::ApplyItemDesParam
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyItemDesParam(ITEM *i_pItem)
{
	for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
	{
		SetParamFactor(i_pItem->ArrDestParameter[i], i_pItem->ArrParameterValue[i]);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::ReleaseItemDesParam
/// \author		cmkwon
/// \date		2009-08-04 ~ 2009-08-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ReleaseItemDesParam(ITEM *i_pItem)
{
	for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
	{
		UnsetParamFactor(i_pItem->ArrDestParameter[i], i_pItem->ArrParameterValue[i]);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CFieldIOCPSocket::DamageDistributionToPartyMember
/// \author		cmkwon
/// \date		2009-08-17 ~ 2009-08-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::DamageDistributionToPartyMember(float i_fChangeValue, BYTE i_enumDamageType, BOOL i_bCheckRecovery/*=TRUE*/
		, CFieldMonster *i_pAttackMonster/*=NULL*/, CFieldIOCPSocket *i_pAttackCharacter/*=NULL*/, MSG_FC_BATTLE_SHOW_DAMAGE *i_pShowDamage/*=NULL*/)
{
	vectCFieldIOCPSocket vectCFISockList;
	if(FALSE == this->GetPartyMemberList(&vectCFISockList))
	{// 2009-08-17 by cmkwon, 파티원 리스트가 비어 있음
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] PFS error(CFieldIOCPSocket::DamageDistributionToPartyMember#) 12000 !! %s %d \r\n"
			, GetCharacterString(this->GetCharacter(), string()), vectCFISockList.size());
		return;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pSShowDamage, SendBuf);
	*pSShowDamage = *i_pShowDamage;
	pSShowDamage->AmountDamage	= i_fChangeValue;
	
	vectCFieldIOCPSocket::iterator itr(vectCFISockList.begin());
	for(; itr != vectCFISockList.end(); itr++)
	{
		CFieldIOCPSocket *pFISoc = *itr;
		if(NULL == pFISoc
			|| this == pFISoc
			|| FALSE == pFISoc->IsValidCharacter()
			|| COMPARE_BODYCON_BIT(pFISoc->GetCharacter()->BodyCondition, BODYCON_EVENT_HANDLE_MASK))
		{
			continue;
		}

// 		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 임시용 로그
// 		if(i_pAttackCharacter)
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804  CFieldIOCPSocket::DamageDistributionToPartyMember# %s Damage(%5.2f) DamageTy(%d) Attacker(%s) \r\n"
// 				, GetCharacterString(GetCharacter(), string()), i_fChangeValue, i_enumDamageType, GetCharacterString(i_pAttackCharacter->GetCharacter(), string()));
// 		}
// 		else
// 		{
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804  CFieldIOCPSocket::DamageDistributionToPartyMember# %s Damage(%5.2f) DamageTy(%d) Attacker(%d:%d) \r\n"
// 				, GetCharacterString(GetCharacter(), string()), i_fChangeValue, i_enumDamageType, i_pAttackMonster->MonsterIndex, i_pAttackMonster->MonsterInfoPtr->MonsterUnitKind);
// 		}
		
		pFISoc->DecreaseCharacterHPDP(i_fChangeValue, i_enumDamageType, i_bCheckRecovery, i_pAttackMonster, i_pAttackCharacter);
		
		pSShowDamage->TargetIndex	= pFISoc->GetCharacter()->ClientIndex;
		if(i_pAttackCharacter)
		{
			i_pAttackCharacter->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
		}		
		pFISoc->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
/// \author		cmkwon
/// \date		2009-08-27 ~ 2009-08-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsChangeItemNumMix(ITEM_GENERAL **o_ppMainItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;			// 초기화

	if(1 < i_nMixCnts){						return FALSE;}	// 2009-08-27 by cmkwon, 다중 조합은 FALSE
	if(2 != i_nSourceItemCnt){				return FALSE;}	// 2009-08-27 by cmkwon, 재료가 2개가 아니면 FALSE
	if(COMPARE_BIT_FLAG(i_pTargetItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM)){		return FALSE;}	// 2009-08-27 by cmkwon, 타겟 아이템이 유니크 아이템이면 FALSE

	ITEM_GENERAL *pValidItemG	= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}

		if(IS_ITEMKIND_REMAIN_RARE8ENCHANT_AS_MIX(pItemG->Kind))
		{
			if(pValidItemG)
			{// 2009-08-27 by cmkwon, 유효한 아이템은 1개 이어야 한다.
				return FALSE;
			}
			pValidItemG		= pItemG;
		}
	}
	
	if(NULL == pValidItemG)
	{// 2009-08-27 by cmkwon, 유효한 아이템은 없다.
		return FALSE;
	}

	if(pValidItemG->Kind != i_pTargetItemInfo->Kind)
	{// 2009-08-27 by cmkwon, 재료와 타겟 아이템의 ItemKind가 다르면 FALSE를 리턴
		return FALSE;
	}

	ITEM_GENERAL *ptmMainItemG	= NULL;
	ITEM_GENERAL *ptmSubItemG	= NULL;
	if(this->IsChangeShapeItemNumMix(&ptmMainItemG, &ptmSubItemG, i_arrSourceItem, i_nSourceItemCnt, i_nMixCnts, i_pTargetItemInfo)
		|| this->IsChangeEffectItemNumMix(&ptmMainItemG, &ptmSubItemG, i_arrSourceItem, i_nSourceItemCnt, i_nMixCnts, i_pTargetItemInfo))
	{// 2009-08-27 by cmkwon, 다른 형태의 조합 시스템이 존재한다
		return FALSE;
	}

	*o_ppMainItemG	= pValidItemG;
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
/// \author		cmkwon
/// \date		2009-08-27 ~ 2009-08-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsChangeShapeItemNumMix(ITEM_GENERAL **o_ppMainItemG, ITEM_GENERAL **o_ppSubItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;
	*o_ppSubItemG		= NULL;

	ITEM_GENERAL *pValidMainItemG	= NULL;
	ITEM_GENERAL *pValidShapeItemG	= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}
		
		if(IS_ENABLE_CHANGE_ShapeItemNum(pItemG->Kind))
		{
			if(pValidMainItemG)
			{// 2009-08-27 by cmkwon, 재료 중 유효한 아이템은 1개만 존재 해야 한다.
				return FALSE;
			}

			pValidMainItemG		= pItemG;
		}

		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 컬렉션 등룍용 외변킷 Kind 변경 지원
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 컬렉션 등룍용 외변킷 Kind 변경 지원
		if( ( ITEMKIND_INGOT == pItemG->Kind && pItemG->ItemInfo->IsExistDesParam(DES_SHAPE_ITEM) )
			|| pItemG->ItemInfo->IsExistDesParam(DES_COLLECTION_ARMOR_INDEX) )
#else
		if(ITEMKIND_INGOT == pItemG->Kind
			&& pItemG->ItemInfo->IsExistDesParam(DES_SHAPE_ITEM))
#endif
		// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 컬렉션 등룍용 외변킷 Kind 변경 지원
		{
			if(pItemG->ItemInfo->ItemNum != i_pTargetItemInfo->ItemNum)
			{// 2009-08-27 by cmkwon, 타겟 ItemNum이 외형 변경 재료 아이템과 같아야 한다.
				return FALSE;
			}

			if(pValidShapeItemG)
			{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템은 1개만 존재 해야 한다. 
				return FALSE;
			}

			pValidShapeItemG	= pItemG;
		}
	}

	if(NULL == pValidMainItemG
		|| NULL == pValidShapeItemG)
	{
		return FALSE;
	}

	if(FALSE == COMPARE_ITEMKIND(pValidShapeItemG->ItemInfo->ReqItemKind, pValidMainItemG->Kind))
	{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템의 ReqItemKind 체크
		return FALSE;
	}	

	*o_ppMainItemG		= pValidMainItemG;
	*o_ppSubItemG		= pValidShapeItemG;

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
/// \author		cmkwon
/// \date		2009-08-27 ~ 2009-08-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsChangeEffectItemNumMix(ITEM_GENERAL **o_ppMainItemG, ITEM_GENERAL **o_ppSubItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;
	*o_ppSubItemG		= NULL;
	
	ITEM_GENERAL *pValidMainItemG	= NULL;
	ITEM_GENERAL *pValidShapeItemG	= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}

		if(IS_ENABLE_CHANGE_EffectItemNum(pItemG->Kind))
		{
			if(pValidMainItemG)
			{// 2009-08-27 by cmkwon, 재료 중 유효한 아이템은 1개만 존재 해야 한다.
				return FALSE;
			}
			
			pValidMainItemG		= pItemG;
		}
		
		if(ITEMKIND_INGOT == pItemG->Kind
			&& pItemG->ItemInfo->IsExistDesParam(DES_EFFECT_ITEM))
		{
			if(pItemG->ItemInfo->ItemNum != i_pTargetItemInfo->ItemNum)
			{// 2009-08-27 by cmkwon, 타겟 ItemNum이 외형 변경 재료 아이템과 같아야 한다.
				return FALSE;
			}
			
			if(pValidShapeItemG)
			{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템은 1개만 존재 해야 한다. 
				return FALSE;
			}
			
			pValidShapeItemG	= pItemG;
		}
	}
	
	if(NULL == pValidMainItemG
		|| NULL == pValidShapeItemG)
	{
		return FALSE;
	}
	
	if(FALSE == COMPARE_ITEMKIND(pValidShapeItemG->ItemInfo->ReqItemKind, pValidMainItemG->Kind))
	{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템의 ReqItemKind 체크
		return FALSE;
	}	
	
	*o_ppMainItemG		= pValidMainItemG;
	*o_ppSubItemG		= pValidShapeItemG;
	
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-01 by cmkwon, 그래픽 리소스 변경 관련 초기화 기능 구현 - 
/// \author		cmkwon
/// \date		2009-09-30 ~ 2009-09-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsInitShapeItemNumMix(ITEM_GENERAL **o_ppMainItemG, ITEM_GENERAL **o_ppSubItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;
	*o_ppSubItemG		= NULL;

	if(ITEMKIND_INGOT != i_pTargetItemInfo->Kind
		|| FALSE == i_pTargetItemInfo->IsExistDesParam(DES_INIT_SHAPE_ITEM)
		|| 2 != i_nSourceItemCnt)
	{
		return FALSE;
	}
	
	ITEM_GENERAL *pValidMainItemG		= NULL;
	ITEM_GENERAL *pValidContentItemG	= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}
		
		if(IS_ENABLE_CHANGE_ShapeItemNum(pItemG->Kind))
		{
			if(pValidMainItemG)
			{// 2009-08-27 by cmkwon, 재료 중 유효한 아이템은 1개만 존재 해야 한다.
				return FALSE;
			}
			
			pValidMainItemG		= pItemG;
		}
		else
		{
			if(i_pTargetItemInfo->ItemNum != pItemG->ItemNum)
			{
				return FALSE;
			}
			pValidContentItemG	= pItemG;
		}		
	}
	
	if(NULL == pValidMainItemG
		|| NULL == pValidContentItemG)
	{
		return FALSE;
	}
	
	if(FALSE == COMPARE_ITEMKIND(pValidContentItemG->ItemInfo->ReqItemKind, pValidMainItemG->Kind))
	{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템의 ReqItemKind 체크
		return FALSE;
	}
	
	*o_ppMainItemG		= pValidMainItemG;
	*o_ppSubItemG		= pValidContentItemG;
	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-01 by cmkwon, 그래픽 리소스 변경 관련 초기화 기능 구현 - 
/// \author		cmkwon
/// \date		2009-09-30 ~ 2009-09-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsInitEffectItemNumMix(ITEM_GENERAL **o_ppMainItemG, ITEM_GENERAL **o_ppSubItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;
	*o_ppSubItemG		= NULL;
	
	if(ITEMKIND_INGOT != i_pTargetItemInfo->Kind
		|| FALSE == i_pTargetItemInfo->IsExistDesParam(DES_INIT_EFFECT_ITEM)
		|| 2 != i_nSourceItemCnt)
	{
		return FALSE;
	}
	
	ITEM_GENERAL *pValidMainItemG		= NULL;
	ITEM_GENERAL *pValidContentItemG	= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}
		
		if(IS_ENABLE_CHANGE_EffectItemNum(pItemG->Kind))
		{
			if(pValidMainItemG)
			{// 2009-08-27 by cmkwon, 재료 중 유효한 아이템은 1개만 존재 해야 한다.
				return FALSE;
			}
			
			pValidMainItemG		= pItemG;
		}
		else
		{
			if(i_pTargetItemInfo->ItemNum != pItemG->ItemNum)
			{
				return FALSE;
			}
			pValidContentItemG	= pItemG;
		}		
	}
	
	if(NULL == pValidMainItemG
		|| NULL == pValidContentItemG)
	{
		return FALSE;
	}
	
	if(FALSE == COMPARE_ITEMKIND(pValidContentItemG->ItemInfo->ReqItemKind, pValidMainItemG->Kind))
	{// 2009-08-27 by cmkwon, 외형 변경 재료 아이템의 ReqItemKind 체크
		return FALSE;
	}
	
	*o_ppMainItemG		= pValidMainItemG;
	*o_ppSubItemG		= pValidContentItemG;
	
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-02-11 by cmkwon, 조합시 외형,이펙트 유지 시스템 구현 - 소스아이템리스트에서 타겟과 ItemKind가 같은 아이템이 하나 있을경우
/// \author		cmkwon
/// \date		2010-02-11 ~ 2010-02-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsKeepShape8EffectMix(ITEM_GENERAL **o_ppMainItemG, ITEM_UNIQUE_NUMBER_W_COUNT *i_arrSourceItem, INT i_nSourceItemCnt, INT i_nMixCnts, ITEM *i_pTargetItemInfo)
{
	*o_ppMainItemG		= NULL;
	
	if(FALSE == IS_ATTACHABLE_ITEM(i_pTargetItemInfo))
	{
		return FALSE;
	}
	
	ITEM_GENERAL *pValidMainItemG		= NULL;
	for (int i = 0; i < i_nSourceItemCnt; i++)
	{
		ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(i_arrSourceItem[i].ItemUniqueNumber);
		if(NULL == pItemG)
		{
			return FALSE;
		}
		
		if(i_pTargetItemInfo->Kind == pItemG->Kind)
		{// 2010-02-11 by cmkwon, ItemKind가 같으면
			if(pValidMainItemG)
			{// 2009-08-27 by cmkwon, 재료 중 유효한 아이템은 1개만 존재 해야 한다.
				return FALSE;
			}
			
			pValidMainItemG		= pItemG;
		}
	}
	
	if(NULL == pValidMainItemG)
	{
		return FALSE;
	}
		
	*o_ppMainItemG		= pValidMainItemG;
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_DECLARATION_MSWAR_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		선전 포고 - 선전 포고 정보 전송
/// \author		dhjin
/// \date		2009-01-13 ~ 2009-01-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_DECLARATION_MSWAR_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_INFO_DECLARATION_MSWAR_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_DECLARATION_MSWAR_INFO_OK, T_FC_INFO_DECLARATION_MSWAR_INFO_OK, pSendMsg, SendBuf);
	pSendMsg->DeclarationOfWarListCount = this->ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.MakeMSG_FC_INFO_DECLARATION_MSWAR_INFO_OK((SDECLARATION_OF_WAR*)(SendBuf+MSG_SIZE(MSG_FC_INFO_DECLARATION_MSWAR_INFO_OK)), &(pSendMsg->ForbidTime));
	if(0 >= pSendMsg->DeclarationOfWarListCount)
	{
		SendErrorMessage(T_FC_INFO_DECLARATION_MSWAR_INFO, ERR_NO_SUCH_DECLARATION_MSWAR_INFO);
		return RES_BREAK;
	}
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFO_DECLARATION_MSWAR_INFO_OK)+pSendMsg->DeclarationOfWarListCount*sizeof(SDECLARATION_OF_WAR));
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_DECLARATION_MSWAR_SET(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		선전 포고 - 선전 포고 일정 및 포기 설정
/// \author		dhjin
/// \date		2009-01-13 ~ 2009-01-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_DECLARATION_MSWAR_SET(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_DECLARATION_MSWAR_SET
									, MSG_FC_INFO_DECLARATION_MSWAR_SET, pRMsg);

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_INFO_DECLARATION_MSWAR_SET, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
	{
		SendErrorMessage(T_FC_INFO_DECLARATION_MSWAR_SET, ERR_CHAT_PERMISSION_DENIED);
		return RES_BREAK;
	}

	QPARAM_UPDATE_MSWAR_START_TIME *pQParam = new QPARAM_UPDATE_MSWAR_START_TIME;
	INIT_MSG_WITH_BUFFER(MSG_FI_INFO_DECLARATION_MSWAR_SET_OK, T_FI_INFO_DECLARATION_MSWAR_SET_OK, pSendMsg, SendBuf);
	Err_t ReturnError = this->ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.SetSelectWarTime(pRMsg, this->m_character.InfluenceType, &(pQParam->SelectCount), &(pQParam->MSWarStartTime));
	if(ERR_NO_ERROR != ReturnError)
	{
		SendErrorMessage(T_FC_INFO_DECLARATION_MSWAR_SET, ReturnError);
		return RES_BREAK;
	}
	pSendMsg->SelectCount		= pQParam->SelectCount;
	pSendMsg->Influence			= this->m_character.InfluenceType;
	pSendMsg->MSWarStartTime	= pRMsg->MSWarStartTime;
	pSendMsg->GiveUp			= pRMsg->GiveUp;
	ms_pFieldIOCP->m_pIMWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FI_INFO_DECLARATION_MSWAR_SET_OK));
	pQParam->Influence			= this->m_character.InfluenceType;
	pQParam->MSWarStep			= pRMsg->MSWarStep;
	pQParam->GiveUp				= pRMsg->GiveUp;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateMSWarStartTime, NULL, 0, pQParam);

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_SERVICE_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
/// \author		cmkwon
/// \date		2009-02-19 ~ 2009-02-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_SERVICE_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{// No Body

	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	int SentCnt = ms_pFieldIOCP->m_WRankingManager.SendServiceListW(this);
	if(0 >= SentCnt)
	{
		SendErrorMessage(T_FC_INFO_WRK_GET_SERVICE_INFO, ERR_DB_NO_SUCH_DATA);
		return RES_BREAK;		
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_RANKER_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
/// \author		cmkwon
/// \date		2009-02-19 ~ 2009-02-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_RANKER_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_WRK_GET_RANKER_LIST
		, MSG_FC_INFO_WRK_GET_RANKER_LIST, pRMsg);

	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	int SentCnt = ms_pFieldIOCP->m_WRankingManager.SendRankerListByRankingType(pRMsg->byRankingType, pRMsg->UnitKind, pRMsg->byScope, this, pRMsg->byStartRank, pRMsg->byReqRankerCnt);
	if(0 >= SentCnt)
	{
		SendErrorMessage(T_FC_INFO_WRK_GET_RANKER_LIST, ERR_DB_NO_SUCH_DATA, pRMsg->byRankingType, pRMsg->UnitKind);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_SELF_RANKING(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
/// \author		cmkwon
/// \date		2009-02-19 ~ 2009-02-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_WRK_GET_SELF_RANKING(const char* pPacket, int nLength, int &nBytesUsed)
{// No Body	

	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetSelfRanking, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MODE_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 리스트 요청, C -> AFS
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MODE_LIST(const char* pPacket, int nLength, int &nBytesUsed) {

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	Err_t errCode = this->SendInfinityModeInfo();
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFINITY_MODE_LIST, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity] 'T_FC_INFINITY_MODE_LIST' Error = %s \r\n", GetErrorString(errCode));
		return RES_BREAK;
	}

	// 2010-05-13 by shcho, 인피니티 난이도 조절 -
	errCode = this->SendInfinityDifficulty_Info();
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFINITY_DIFFICULTY_LIST_OK, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity] 'T_FC_INFINITY_DIFFICULTY_LIST_OK' Error = %s \r\n", GetErrorString(errCode));
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 리스트 요청
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY_LIST(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_READY_LIST
		, MSG_FC_INFINITY_READY_LIST, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_READY_LIST_OK, T_FC_INFINITY_READY_LIST_OK, pSMsg, SendBuf);
	pSMsg->InfinityPlayingListCount	= this->ms_pFieldIOCP->m_InfinityManager.MakeMsgInfinityPlayingList((INFINITY_READY_LIST*)(SendBuf+MSG_SIZE(MSG_FC_INFINITY_READY_LIST_OK))
											, pRMsg->InfinityMapIdx, pRMsg->InfinityMode, this->m_character.InfluenceType);
	if(0 >= pSMsg->InfinityPlayingListCount) {
		this->SendErrorMessage(T_FC_INFINITY_READY_LIST, ERR_INFINITY_NO_SUCH_READY_LIST);
		return RES_BREAK;
	}
	
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_READY_LIST_OK)+pSMsg->InfinityPlayingListCount*sizeof(INFINITY_READY_LIST));
	
	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_CREATE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 생성 요청
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_CREATE(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_CREATE
		, MSG_FC_INFINITY_CREATE, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	if(ARENA_STATE_NONE != this->m_ArenaInfo.State) {
		SendErrorMessage(T_FC_INFINITY_CREATE, ERR_ARENA_STATE);
		return RES_BREAK;
	}
	if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_CREATE, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	if(FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckInfinityModeLevel(pRMsg->InfinityModeUID, this->m_character.Level)) {
		SendErrorMessage(T_FC_INFINITY_CREATE, ERR_INFINITY_MISMATCH_LEVEL);
		return RES_BREAK; 
	}

// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 아래와 같이 수정
// 	EntranceCount_t EntranceCount = 0;
// 	mt_auto_lock mtImpute(&m_mtVecInfiImpute);
// 	mt_vectorInfinityImpute::iterator itr = m_mtVecInfiImpute.begin();
// 	for(; itr != m_mtVecInfiImpute.end(); itr++) {
// 		// 진입 체크를 위한 값
// 		if(itr->InfinityModeUID == pRMsg->InfinityModeUID) {
// 			EntranceCount = itr->EntranceCount;
// 		}
// 	}
// 	mtImpute.auto_unlock_cancel();
// 
// 	if(FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckEntranceCount(pRMsg->InfinityModeUID, EntranceCount)) {
// 		// 인피 진입 카운트 체크
// 		SendErrorMessage(T_FC_INFINITY_CREATE, ERR_INFINITY_OVER_ENTRANCECOUNT);		
// 		return RES_BREAK;
// 	}

	// GM은 인피니티 입장 캐쉬 아이템 쓰는 것 무시.
	if ( FALSE == COMPARE_RACE( this->m_character.Race , RACE_OPERATION|RACE_GAMEMASTER ) )
	{
		///////////////////////////////////////////////////////////////////////////////	
		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 입장카운트 체크
		EntranceCount_t EntranceCount = this->InfinityGetEntranceCount(pRMsg->InfinityModeUID);
		if(FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckEntranceCount(pRMsg->InfinityModeUID, EntranceCount))
		{
			// 인피 진입 카운트 체크
			if(FALSE == this->m_InfinityPlayingInfo.bHaveReentryTicket
				|| FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckEntranceCount(pRMsg->InfinityModeUID, EntranceCount, 1))
			{
				SendErrorMessage(T_FC_INFINITY_CREATE, ERR_INFINITY_OVER_ENTRANCECOUNT, EntranceCount, this->m_InfinityPlayingInfo.bHaveReentryTicket);
				return RES_BREAK;
			}
		}
		else
		{
			this->m_InfinityPlayingInfo.bHaveReentryTicket	= FALSE;	// 사용되지 않으므로 소유정보 초기화
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_CREATE_OK, T_FC_INFINITY_CREATE_OK, pSMsg, SendBuf);
	if(FALSE == this->ms_pFieldIOCP->m_InfinityManager.CreateInfinity(pRMsg, this, &pSMsg->InfinityCreateUID , &pSMsg->IntinityDifficultyLevel )) {
		// 인피 생성
		SendErrorMessage(T_FC_INFINITY_CREATE, ERR_INFINITY_CREATE_FAIL);
		return RES_BREAK;
	}

	this->SendMFSInfinityStateChange(INFINITY_STATE_READY);		// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 인피 상태 값을 메인서버로 전송한다.
		
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_CREATE_OK));
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 가입 요청, C -> F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_JOIN
		, MSG_FC_INFINITY_JOIN, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	if(ARENA_STATE_NONE != this->m_ArenaInfo.State) {
		SendErrorMessage(T_FC_INFINITY_JOIN, ERR_ARENA_STATE);
		return RES_BREAK;
	}
	if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_JOIN, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}


	// GM은 인피니티 입장 캐쉬 아이템 쓰는 것 무시.
	if ( FALSE == COMPARE_RACE( this->m_character.Race , RACE_OPERATION|RACE_GAMEMASTER ) )
	{
		///////////////////////////////////////////////////////////////////////////////	
		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 입장카운트 체크
		EntranceCount_t EntranceCount = this->InfinityGetEntranceCount(pRMsg->InfinityModeUID);
		if(FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckEntranceCount(pRMsg->InfinityModeUID, EntranceCount))
		{
			// 인피 진입 카운트 체크
			// 2010-05-20 by cmkwon, 인피니티 입장카드 버그 수정 - 아래와 같이 pRMsg->InfinityModeUID를 인자에 넣게 수정
			if(FALSE == this->m_InfinityPlayingInfo.bHaveReentryTicket
				|| FALSE == this->ms_pFieldIOCP->m_InfinityManager.CheckEntranceCount(pRMsg->InfinityModeUID, EntranceCount, 1))
			{
				SendErrorMessage(T_FC_INFINITY_JOIN, ERR_INFINITY_OVER_ENTRANCECOUNT, EntranceCount, this->m_InfinityPlayingInfo.bHaveReentryTicket);
				return RES_BREAK;
			}
		}
		else
		{
			this->m_InfinityPlayingInfo.bHaveReentryTicket	= FALSE;	// 2010-05-20 by cmkwon, 인피니티 입장카드 버그 수정 - 사용되지 않으므로 소유정보 초기화
		}
	}

	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.JoinCheckInfinity(pRMsg, this);
	if(ERR_NO_ERROR != errCode) {
		SendErrorMessage(T_FC_INFINITY_JOIN, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FC_INFINITY_JOIN' Error = %s \r\n", pRMsg->InfinityCreateUID, GetErrorString(errCode));
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 방장에서 가입자 승인 여부 요청, C -> F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK
		, MSG_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	CFieldIOCPSocket * RequestUserFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->ReQuestClientIdx);
	if(FALSE == RequestUserFISoc) {
		return RES_BREAK;
	}

	if(INFINITY_STATE_NONE != RequestUserFISoc->m_InfinityPlayingInfo.InfinityState) {
		RequestUserFISoc->SendErrorMessage(T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK, ERR_INFINITY_STATE);
		return RES_BREAK;		
	}

	if(FALSE == pRMsg->bAccept) {
		// 승인 거절
		RequestUserFISoc->SendErrorMessage(T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK, ERR_INFINITY_JOIN_FAIL_MASTERUSER_REJECT);
		return RES_BREAK;		
	}
	
	// 가입 처리
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.JoinInfinity(pRMsg->InfinityMode, pRMsg->InfinityCreateUID, RequestUserFISoc);
	if(ERR_NO_ERROR != errCode) {
		SendErrorMessage(T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK, errCode);
		RequestUserFISoc->SendErrorMessage(T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK' Error = %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetErrorString(errCode));
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MEMBER_INFO_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 맴버 정보, C -> F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MEMBER_INFO_LIST(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	if(INFINITY_STATE_NONE == this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_MEMBER_INFO_LIST, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	// 맴버 리스트 얻어오기
	ClientIndex_t			MasterUserClientIdx;
	vectCFieldIOCPSocket 	InfinityMemberList;
	InfinityMemberList.clear();
	this->ms_pFieldIOCP->m_InfinityManager.GetPlayerListW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, &InfinityMemberList, &MasterUserClientIdx);
	if(0 >= InfinityMemberList.size()) {
		SendErrorMessage(T_FC_INFINITY_MEMBER_INFO_LIST, ERR_INFINITY_NO_SUCH_MEMBER_LIST);
		return RES_BREAK;
	}
	
	// 보내기
	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_MEMBER_INFO_LIST_OK, T_FC_INFINITY_MEMBER_INFO_LIST_OK, pSendMsg, SendBuf);
	pSendMsg->MasterClientIdx	= MasterUserClientIdx;
	int	InfinityMemberlistCount = 0;
	INFINITY_MEMBER_INFO_LIST * pMemberInfo = (INFINITY_MEMBER_INFO_LIST*)(SendBuf+MSG_SIZE(MSG_FC_INFINITY_MEMBER_INFO_LIST_OK));
	vectCFieldIOCPSocket::iterator itr = InfinityMemberList.begin();
	for(; itr != InfinityMemberList.end(); itr++) {
		if(NULL != *itr) {
			pMemberInfo[InfinityMemberlistCount].ClientIdx	= (*itr)->m_character.ClientIndex;
			pMemberInfo[InfinityMemberlistCount].Gear		= (*itr)->m_character.UnitKind;
			pMemberInfo[InfinityMemberlistCount].Lv			= (*itr)->m_character.Level;
			pMemberInfo[InfinityMemberlistCount].State		= (*itr)->m_InfinityPlayingInfo.InfinityState;
			STRNCPY_MEMSET(pMemberInfo[InfinityMemberlistCount].CharacterName, (*itr)->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
			InfinityMemberlistCount++;
		}
	}
	pSendMsg->InfinityMemberListCount	= InfinityMemberlistCount;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_MEMBER_INFO_LIST_OK) + InfinityMemberlistCount * sizeof(INFINITY_MEMBER_INFO_LIST));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_CHANGE_MASTER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 마스터 변경, C -> F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_CHANGE_MASTER(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_CHANGE_MASTER
		, MSG_FC_INFINITY_CHANGE_MASTER, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not\r\n");
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	if(INFINITY_STATE_NONE == this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_CHANGE_MASTER, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}
	
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.ChangeMasterUserW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID
																			, this->ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->ChangeMasterClientIdx));
	if(ERR_NO_ERROR != errCode) {
		SendErrorMessage(T_FC_INFINITY_CHANGE_MASTER, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FC_INFINITY_CHANGE_MASTER' Error = %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetErrorString(errCode));
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_LEAVE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 탈퇴, C -> AFS
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_LEAVE(const char* pPacket, int nLength, int &nBytesUsed)
{
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_LEAVE# ! %s InfiState(%d) \r\n"
//		, this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), m_InfinityPlayingInfo.InfinityState);

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	eINFINITY_STATE tmInfiState = this->m_InfinityPlayingInfo.InfinityState;
	if(INFINITY_STATE_NONE == tmInfiState)
	{
		SendErrorMessage(T_FC_INFINITY_LEAVE, ERR_INFINITY_STATE, 10000, tmInfiState);
		return RES_BREAK; 
	}
	
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.LeaveInfinity(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, this);
	if(ERR_NO_ERROR != errCode)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_LEAVE# ! %s Error(%d:%s) \r\n"
			, this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), errCode, GetErrorString(errCode));
	}

	// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
	// 기존
	//if(INFINITY_STATE_PLAYING == tmInfiState)

	// 수정
	if( TRUE == IS_INFINITY_STATE_PLAYING(tmInfiState) ) 
	// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
	{
		this->InfinityFinCharacterRoutine();
		this->InfinityFin();
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_BAN(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 추방, C -> F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_BAN(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_BAN
		, MSG_FC_INFINITY_BAN, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	if(pRMsg->BanClientIdx == this->m_character.ClientIndex) {
		SendErrorMessage(T_FC_INFINITY_BAN, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK; 
	}

	CFieldIOCPSocket * BanPlayerFISoc = this->ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->BanClientIdx);
	if(NULL == BanPlayerFISoc) {
		SendErrorMessage(T_FC_INFINITY_BAN, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK; 
	}

	if(INFINITY_STATE_NONE == this->m_InfinityPlayingInfo.InfinityState
		|| INFINITY_STATE_NONE == BanPlayerFISoc->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_BAN, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}
		
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.BanInfinity(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, BanPlayerFISoc);
	if(ERR_NO_ERROR != errCode) {
		SendErrorMessage(T_FC_INFINITY_BAN, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FC_INFINITY_BAN' Error = %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetErrorString(errCode));
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GetDBInfinityImpute()
/// \brief		인피니티 - 귀속 정보 가져오기
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GetDBInfinityImpute() {
	if(FALSE == IsValidCharacter(FALSE)) {
		return;
	}
	
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_LoadInfinityImpute, this, m_character.AccountUniqueNumber, NULL);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_IMPUTE_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 귀속 정보, MFS -> AFS
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_IMPUTE_LIST(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_INFINITY_IMPUTE_LIST
		, MSG_FtoA_INFINITY_IMPUTE_LIST, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(nLength-nBytesUsed < pRMsg->InfinityImputeListCount	* sizeof(INFINITY_IMPUTE)) {
		SendErrorMessage(T_FtoA_INFINITY_IMPUTE_LIST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		return RES_RETURN_FALSE;
	}
	nBytesUsed += pRMsg->InfinityImputeListCount	* sizeof(INFINITY_IMPUTE);
	
	CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIndex);
	if(NULL == ClientFISoc
		|| FALSE == ClientFISoc->IsUsing())
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] 'Process_FtoA_INFINITY_IMPUTE_LIST' Check ClientIndex \r\n");
		return RES_BREAK;		
	}

// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 아래와 같이 수정
// 	mt_auto_lock mtImpute(&ClientFISoc->m_mtVecInfiImpute);
// 	ClientFISoc->m_mtVecInfiImpute.clear();
// 	INFINITY_IMPUTE * pInfinityImpute = (INFINITY_IMPUTE*)(((BYTE*)pRMsg) + sizeof(MSG_FtoA_INFINITY_IMPUTE_LIST));
// 	for(int i =0; i < pRMsg->InfinityImputeListCount; i++) {
// 		ClientFISoc->m_mtVecInfiImpute.push_back(pInfinityImpute[i]);
// 	}
// 	mtImpute.auto_unlock_cancel();
// 	ClientFISoc->m_InfinityPlayingInfo.bHaveReentryTicket	= pRMsg->bHaveReentryTicket;	// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
	vectINFINITY_IMPUTE tmImputeList;
 	INFINITY_IMPUTE * pInfinityImpute = (INFINITY_IMPUTE*)(((BYTE*)pRMsg) + sizeof(MSG_FtoA_INFINITY_IMPUTE_LIST));
	for(int i =0; i < pRMsg->InfinityImputeListCount; i++)
	{
		tmImputeList.push_back(pInfinityImpute[i]);
	}
	ClientFISoc->InfinityInitImputeList(&tmImputeList);
	ClientFISoc->m_InfinityPlayingInfo.bHaveReentryTicket	= pRMsg->bHaveReentryTicket;

	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 준비 버튼 누름
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	if(INFINITY_STATE_UNPREPARED != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_READY, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}
	
	this->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_READY;

	// 맴버 리스트 얻어오기
	ClientIndex_t			MasterUserClientIdx;
	vectCFieldIOCPSocket 	InfinityMemberList;
	InfinityMemberList.clear();
	this->ms_pFieldIOCP->m_InfinityManager.GetPlayerListW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, &InfinityMemberList, &MasterUserClientIdx);
	if(0 >= InfinityMemberList.size()) {
		SendErrorMessage(T_FC_INFINITY_READY, ERR_INFINITY_NO_SUCH_MEMBER_LIST);
		return RES_BREAK;
	}
	
	// 보내기
	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_READY_OK, T_FC_INFINITY_READY_OK, pSendMsg, SendBuf);
	pSendMsg->ReadyClientIdx	= this->m_character.ClientIndex;
	vectCFieldIOCPSocket::iterator itr = InfinityMemberList.begin();
	for(; itr != InfinityMemberList.end(); itr++) {
		if(NULL != *itr) {
			(*itr)->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_READY_OK));
		}
	}
	
	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY_CANCEL(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 준비취소 버튼 누름
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_READY_CANCEL(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	if(INFINITY_STATE_READY != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_READY, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	this->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_UNPREPARED;
	
	// 맴버 리스트 얻어오기
	ClientIndex_t			MasterUserClientIdx;
	vectCFieldIOCPSocket 	InfinityMemberList;
	InfinityMemberList.clear();
	this->ms_pFieldIOCP->m_InfinityManager.GetPlayerListW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, &InfinityMemberList, &MasterUserClientIdx);
	if(0 >= InfinityMemberList.size()) {
		SendErrorMessage(T_FC_INFINITY_READY_CANCEL, ERR_INFINITY_NO_SUCH_MEMBER_LIST);
		return RES_BREAK;
	}
	
	// 보내기
	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_READY_CANCEL_OK, T_FC_INFINITY_READY_CANCEL_OK, pSendMsg, SendBuf);
	pSendMsg->ReadyCancelClientIdx	= this->m_character.ClientIndex;
	vectCFieldIOCPSocket::iterator itr = InfinityMemberList.begin();
	for(; itr != InfinityMemberList.end(); itr++) {
		if(NULL != *itr) {
			(*itr)->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_READY_CANCEL_OK));
		}
	}

	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 시작 버튼 누름(인피 시작)
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_START(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	if(INFINITY_STATE_READY != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_START, ERR_INFINITY_STATE, 10000, this->m_InfinityPlayingInfo.InfinityState);
		return RES_BREAK; 
	}

	// 2010-04-06 by cmkwon, 인피2차 추가 수정 - 
	Err_t errCode = ms_pFieldIOCP->m_InfinityManager.CheckInfinityAllPlayerStateW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, INFINITY_STATE_READY);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFINITY_START, errCode, 20000, this->m_InfinityPlayingInfo.InfinityState);
		return RES_BREAK; 
	}

// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 아래와 같이 수정	
// 	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.StartInfinity(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, this);
// 	if(ERR_NO_ERROR != errCode) {
// 		this->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_READY;	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 시작 버튼 누른 상태 추가
// 		SendErrorMessage(T_FC_INFINITY_START, errCode);
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FC_INFINITY_START' Error = %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetErrorString(errCode));
// 		return RES_BREAK;
// 	}
	///////////////////////////////////////////////////////////////////////////////	
	// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
	errCode = ms_pFieldIOCP->m_InfinityManager.SendFtoA_INFINITY_START_CHECK_W(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFINITY_START, errCode, 30000);
		return RES_BREAK; 
	}
	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_START_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 시작 MainFieldSever준비 완료 전송
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_START_OK(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_INFINITY_START_OK
		, MSG_FtoA_INFINITY_START_OK, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}

	CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIndex);
	if(NULL == ClientFISoc)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][ClientIdx = %10d] 'T_FtoA_INFINITY_START_OK' Error = 'Null Socket' \r\n", pRMsg->AFSClientIndex);
		return RES_BREAK;		
	}

	if(FALSE == ClientFISoc->IsValidCharacter(FALSE)) {
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FtoA_INFINITY_START_OK' Error = 'InvalidCharacter ' \r\n", ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID);
		return RES_BREAK;
	}

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] T_FtoA_INFINITY_START_OK 1 , CharacterName = %s \r\n", ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID, ClientFISoc->m_character.CharacterName);	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 체크를 위한 로그 추가

	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 시작 버튼 누른 상태 추가, 밑과 같이 수정
//	if(INFINITY_STATE_READY != ClientFISoc->m_InfinityPlayingInfo.InfinityState) {
	if(INFINITY_STATE_ENTERING != ClientFISoc->m_InfinityPlayingInfo.InfinityState) {
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FtoA_INFINITY_START_OK' InfinityState Error = %d \r\n", ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID, ClientFISoc->m_InfinityPlayingInfo.InfinityState);
		return RES_BREAK;
	}

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] T_FtoA_INFINITY_START_OK 2 , CharacterName = %s \r\n", ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID, ClientFISoc->m_character.CharacterName);	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 체크를 위한 로그 추가

	ClientFISoc->m_bIsPCBangClient	= pRMsg->bIsPCBangClient;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ArenaStartGetCharacter, ClientFISoc, NULL, NULL);
	
	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 맵 로딩 종료
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] T_FC_INFINITY_MAP_LOADED 1, %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()));	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 체크를 위한 로그 추가

	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 시작 버튼 누른 상태 추가
//	if(INFINITY_STATE_READY != this->m_InfinityPlayingInfo.InfinityState) {
	if(INFINITY_STATE_ENTERING != this->m_InfinityPlayingInfo.InfinityState)
	{
		SendErrorMessage(T_FC_INFINITY_MAP_LOADED, ERR_INFINITY_STATE, 10000, m_InfinityPlayingInfo.InfinityState);
		return RES_BREAK; 
	}
	
	//g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] T_FC_INFINITY_MAP_LOADED 2 , CharacterName = %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, this->m_character.CharacterName);	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 체크를 위한 로그 추가

	// 맴버 리스트 얻어오기
	ClientIndex_t			MasterUserClientIdx;
	vectCFieldIOCPSocket 	InfinityMemberList;
	InfinityMemberList.clear();
	this->ms_pFieldIOCP->m_InfinityManager.GetPlayerListW(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, &InfinityMemberList, &MasterUserClientIdx);
	if(0 >= InfinityMemberList.size()) {
		SendErrorMessage(T_FC_INFINITY_MAP_LOADED, ERR_INFINITY_NO_SUCH_MEMBER_LIST);
		return RES_BREAK;
	}

	this->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_MAPLOADED;

	int	MapLoadedUserCount = 0;
	int PlayingUserCount = 0;
	vectCFieldIOCPSocket::iterator itr = InfinityMemberList.begin();
	for(; itr != InfinityMemberList.end(); itr++) {
		if(NULL != *itr) {
			if(INFINITY_STATE_MAPLOADED == (*itr)->m_InfinityPlayingInfo.InfinityState) {
				MapLoadedUserCount++;
			}
			PlayingUserCount++;
		}
	}
	

	if(PlayingUserCount == MapLoadedUserCount)
	{
		// 2010-04-02 by cmkwon, 인피2차 추가 수정 - 
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED# All user was loaded map !, LastCharacterName(%s) PalyingUserCnt(%d) \r\n"
			, this->m_InfinityPlayingInfo.InfinityCreateUID, this->m_character.CharacterName, PlayingUserCount);

		// 모든 유저가 맵 로딩 준비가 끝났다.
		Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.UserMapLoadedComplete(this->m_InfinityPlayingInfo.ModeTypeNum, this->m_InfinityPlayingInfo.InfinityCreateUID, this->m_InfinityPlayingInfo.MapIdx);
		if(ERR_NO_ERROR != errCode)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED# !! %s Error(%d:%s) \r\n"
				, m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), errCode, GetErrorString(errCode));
			return RES_BREAK;
		}
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SetInfinityMap(MapIndex_t i_MapIdx, ChannelIndex_t i_ChannelIdx)
/// \brief		인피니티 - 인피 시작 전 맵 설정
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetInfinityMap(MapIndex_t i_MapIdx, ChannelIndex_t i_ChannelIdx) {
	MessageType_t msgType		= T_NA;

	MAP_CHANNEL_INDEX InfinityMapIndex;
	MEMSET_ZERO(&InfinityMapIndex, sizeof(MAP_CHANNEL_INDEX));
	InfinityMapIndex.MapIndex = i_MapIdx;
	InfinityMapIndex.ChannelIndex = i_ChannelIdx;

	SetCurrentFieldMapChannel(GetFieldMapChannel(&InfinityMapIndex, TRUE, TRUE));
	if (m_pCurrentFieldMapChannel == NULL)
	{
		// ERROR! All Channels Not Available
		DBGOUT("[%d] All Channel Unavailable: [%04d]\n", m_character.ClientIndex, m_character.MapChannelIndex.MapIndex);
		Close(0x1405D);
		return FALSE;
	}

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] [Infinity][%I64d] CFieldIOCPSocket::SetInfinityMap# !, MapInfo(%s) \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetMapString(m_pCurrentFieldMapChannel->GetMapChannelIndex(), string()));	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 체크를 위한 로그 추가

	int	nWarpObjectIndex	= m_pCurrentFieldMapChannel->GetWarpObjectIndexW(this->m_character.InfluenceType);
	D3DXVECTOR3 v3 = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetRandomWarpPoint(nWarpObjectIndex);
	m_character.PositionVector	=	v3;
	
	// 2008-03-06 by dhjin, IM서버로 맵 정보를 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FI_EVENT_NOTIFY_WARP, T_FI_EVENT_NOTIFY_WARP, pNotifyWarp, pNotifyWarpBuf);
	pNotifyWarp->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pNotifyWarp->MapChannelIndex		= m_character.MapChannelIndex;
	pNotifyWarp->nNumOfTimer			= 0;
	ms_pFieldIOCP->m_pIMWinSocket->Write((char*)pNotifyWarpBuf, MSG_SIZE(MSG_FI_EVENT_NOTIFY_WARP));

	// Set Initial Position
	if(FALSE == m_pCurrentFieldMapChannel->SetInitialPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
	{
		char szTemp[256];
		sprintf(szTemp, "[Error] SetInitialPosition_2 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f)\n"
			, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
			, m_character.PositionVector.x, m_character.PositionVector.z);
		DBGOUT(szTemp);
		g_pGlobal->WriteSystemLog(szTemp);
	}
	m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.insertLock(m_character.CharacterUniqueNumber, this);
	
	// start 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
	if( TRUE == m_pCurrentFieldMapChannel->IsEnableTriggerMapBuff() )
	{
		m_pCurrentFieldMapChannel->GetTriggerMapBuffManager()->SetMapBuff(m_character.CharacterUniqueNumber, this);
	}
	// end 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	// NPC Server에 Character 의 GameStart 메세지를 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FN_CLIENT_GAMESTART_OK, T_FN_CLIENT_GAMESTART_OK, pSendClientGameStartOK, SendBuf);
	pSendClientGameStartOK->ChannelIndex			= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
	pSendClientGameStartOK->ClientIndex				= m_character.ClientIndex;
	pSendClientGameStartOK->mexCharacter			= m_character;
	pSendClientGameStartOK->GuildMasterCharUID		= 0;
	pSendClientGameStartOK->bStealthState1			= TRUE;			// 기본적으로 스텔스 상태로 시작된다. 아이템이 로딩되고 정상적으로 설정됨
	pSendClientGameStartOK->bInvisible				= FALSE;		// 2006-11-27 by dhjin
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMESTART_OK));
	
	char szSystemLog[256];
	sprintf(szSystemLog, "  GameStartRoutine(%s) %s Map(%04d) Position(%4d, %4d, %4d) IP(%s)\r\n",
		GetProtocolTypeString(msgType), GetCharacterString(&m_character, string()),
		m_character.MapChannelIndex.MapIndex, (int)m_character.PositionVector.x,
		(int)m_character.PositionVector.y, (int)m_character.PositionVector.z,
		GetPeerIP());
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
	DBGOUT(szSystemLog);

	// Pre Server에도 알림
	INIT_MSG_WITH_BUFFER(MSG_FP_EVENT_MAP_CHANGED, T_FP_EVENT_MAP_CHANGED, msgMapChanged, msgMapChangedBuf);
	STRNCPY_MEMSET(msgMapChanged->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(msgMapChanged->CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	msgMapChanged->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	msgMapChanged->MapChannelIndex			= m_character.MapChannelIndex;
	ms_pFieldIOCP->m_pPreWinSocket->Write(msgMapChangedBuf, MSG_SIZE(MSG_FP_EVENT_MAP_CHANGED));

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_FIN_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 종료 확인 후 마을(Main서버로 돌아감)
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_FIN_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_FIN_OK# ! %s InfiState(%d) \r\n"
//		, this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), m_InfinityPlayingInfo.InfinityState);

	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	// 2010-03-31 by dhjin, 인피니티(기지방어) - 밑과 같이 수정
//	if(INFINITY_STATE_DONE != m_InfinityPlayingInfo.InfinityState) {
	if(INFINITY_STATE_PLAYING >= m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_FIN_OK, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	///////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리, 밑과 같이 수정
// 	///////////////////////////////////////////////////////////////////////////
// 	// 자신의 정보를 맵 Block에서 삭제 한다.
// 	if (m_pCurrentFieldMapChannel != NULL)
// 	{
// 		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
// 		{
// 			char szTemp[256];
// 			sprintf(szTemp, "[Error] DeleteBlockPosition_3 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f)\n"
// 				, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
// 				, m_character.PositionVector.x, m_character.PositionVector.z);
// 			DBGOUT(szTemp);
// 			g_pFieldGlobal->WriteSystemLog(szTemp);
// 		}
// 		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
// 	}
// 	
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다
// 	this->DeleteMeFromMonsterAttackedList();
	this->InfinityFinCharacterRoutine();
	this->InfinityFin();

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InfinityFin()
/// \brief		인피니티 - 인피 종료로 Main서버로 전송할 부분 전송
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityFin() {
	CIOCPSocket	*	MFSSock;
	MFSSock = this->ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	if(NULL == MFSSock) {// 2007-12-28 by dhjin, 필드 서버에 대한 정보가 없으면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::InfinityFin# MainFieldSocket is NULL! %s \r\n", this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()));
		return;
	}

	// start 2011-10-17 by hskim, 파트너 시스템 2차
	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_COME_BACK_PREWORK, T_FtoA_INFINITY_COME_BACK_PREWORK, pPreworkSendMsg, PreworkSendBuf);
	pPreworkSendMsg->AccountUID				= this->m_character.AccountUniqueNumber;
	pPreworkSendMsg->MFSCharacterUID		= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pPreworkSendMsg->MFSClientIndex			= this->m_AfsNeedMfsInfo.MFSClientIdx;
	MFSSock->SendAddData(PreworkSendBuf, MSG_SIZE(MSG_FtoA_INFINITY_COME_BACK_PREWORK));
	// end 2011-10-17 by hskim, 파트너 시스템 2차

	// 유저 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_UPDATE_USER_INFO, T_FtoA_INFINITY_UPDATE_USER_INFO, pCharacterSendMsg, CharacterSendBuf);
	pCharacterSendMsg->AccountUID				= this->m_character.AccountUniqueNumber;
	pCharacterSendMsg->MFSCharacterUID			= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pCharacterSendMsg->MFSClientIndex			= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pCharacterSendMsg->BonusStat				= this->m_character.BonusStat;
	pCharacterSendMsg->BonusStatPoint			= this->m_character.BonusStatPoint;
	pCharacterSendMsg->CumulativeWarPoint		= this->m_character.CumulativeWarPoint;
	pCharacterSendMsg->DownExperience			= this->m_character.DownExperience;
	pCharacterSendMsg->DownSPIOnDeath			= this->m_character.DownSPIOnDeath;
	pCharacterSendMsg->Experience				= this->m_character.Experience;
	pCharacterSendMsg->GearStat					= this->m_character.GearStat;
	pCharacterSendMsg->Level					= this->m_character.Level;
	pCharacterSendMsg->LevelUpTime				= this->m_character.LevelUpTime;
	pCharacterSendMsg->PCBangTotalPlayTime		= this->m_character.PCBangTotalPlayTime;
	pCharacterSendMsg->SecretInfoOption			= this->m_character.SecretInfoOption;
	pCharacterSendMsg->TotalPlayTime			= this->m_character.TotalPlayTime;
	pCharacterSendMsg->WarPoint					= this->m_character.WarPoint;
	pCharacterSendMsg->InfinityMapIndex			= this->m_character.MapChannelIndex.MapIndex;				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
	pCharacterSendMsg->InfinityChannelIndex		= this->m_character.MapChannelIndex.ChannelIndex;			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
	MFSSock->SendAddData(CharacterSendBuf, MSG_SIZE(MSG_FtoA_INFINITY_UPDATE_USER_INFO));
	
	// 유저 아이템 본섭 업뎃을 위해 최종 점검!!!
	SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemProwOut.ItemNum);	// 1형 무기
	SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemWingOut.ItemNum);	// 2형 무기
	this->m_ItemManager.StoreCountableItem();								// 카운터블 아이템
	this->m_ItemManager.StoreTimeStampUsingTimeLimitedIteList();			// 사용 시간 제한 아이템
	
	this->GameEndAllInvokingEquipItem();									// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	
	this->ResetWearItem();

	// 아템 관련 된 컨테이너..들 락을 안잡아도 되겠지??...음...
	// 업뎃 할 아이템 총 수 전송
	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_UPDATE_ALL_ITEM_COUNT, T_FtoA_INFINITY_UPDATE_ALL_ITEM_COUNT, pAllItemCntSendMsg, AllItemCntSendBuf);
	pAllItemCntSendMsg->AccountUID				= this->m_character.AccountUniqueNumber;
	pAllItemCntSendMsg->MFSCharacterUID			= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pAllItemCntSendMsg->MFSClientIndex			= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pAllItemCntSendMsg->AllItemCount			= this->m_ItemManager.m_mtInfinityDeleteItemInfoList.size() + this->m_ItemManager.m_mtInfinityUpdateItemInfoList.size() + this->m_ItemManager.m_mtInfinityInsertItemInfoList.size();
	MFSSock->SendAddData(AllItemCntSendBuf, MSG_SIZE(MSG_FtoA_INFINITY_UPDATE_ALL_ITEM_COUNT));		

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] [Infinity][%I64d] CFieldIOCPSocket::InfinityFin# !, %s DeleteItemCnt(%d) UpdateItemCnt(%d) InsertItemCnt(%d) \r\n"
		, this->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(GetCharacter(), string()), this->m_ItemManager.m_mtInfinityDeleteItemInfoList.size(), this->m_ItemManager.m_mtInfinityUpdateItemInfoList.size(), this->m_ItemManager.m_mtInfinityInsertItemInfoList.size());

	m_ItemManager.InfinitySendPetItemInfo((CFieldIOCPSocket*)MFSSock);		// 2011-09-30 by hskim, 파트너 시스템 2차 - 파트너 정보 전달

	// 2010-04-02 by cmkwon, 인피2차 추가 수정 - 
	m_ItemManager.InfinitySendDeleteItemList((CFieldIOCPSocket*)MFSSock);
	m_ItemManager.InfinitySendInsertItemList((CFieldIOCPSocket*)MFSSock);
	m_ItemManager.InfinitySendUpdateItemList((CFieldIOCPSocket*)MFSSock);

	// start 2012-01-16 by hskim, 통계 - 화패
	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_COME_BACK_POSTWORK, T_FtoA_INFINITY_COME_BACK_POSTWORK, pPostworkSendMsg, PostworkSendBuf);
	pPostworkSendMsg->AccountUID				= this->m_character.AccountUniqueNumber;
	pPostworkSendMsg->MFSCharacterUID			= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pPostworkSendMsg->MFSClientIndex			= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pPostworkSendMsg->DeltaMoney				= StatisticsInfinityEnd();
	MFSSock->SendAddData(PostworkSendBuf, MSG_SIZE(MSG_FtoA_INFINITY_COME_BACK_POSTWORK));
	// end 2012-01-16 by hskim, 통계 - 화패
}

// start 2011-10-17 by hskim, 파트너 시스템 2차
///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InfinityFin()
/// \brief		// 2011-10-17 by hskim, 파트너 시스템 2차 - 아레나 종료로 Main서버로 전송할 부분 전송
/// \author		hskim
/// \date		2011-10-17
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ArenaFin()
{
	this->SendUserInfoForArenaEnding();
}
// end 2011-10-17 by hskim, 파트너 시스템 2차

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_READY_FINISH_MAINSVR_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - Main서버로 돌아갈 준비가 완료 됨, MFS -> AFS
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_READY_FINISH_MAINSVR_START(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_INFINITY_READY_FINISH_MAINSVR_START
		, MSG_FtoA_INFINITY_READY_FINISH_MAINSVR_START, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	CFieldIOCPSocket * ClientFISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIndex);
	if(NULL == ClientFISoc)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][ClientIdx = %10d] 'T_FtoA_INFINITY_READY_FINISH_MAINSVR_START' Error = 'Null Socket' \r\n", pRMsg->AFSClientIndex);
		return RES_BREAK;		
	}
	
	if(FALSE == ClientFISoc->IsValidCharacter(FALSE))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][%I64d] 'T_FtoA_INFINITY_READY_FINISH_MAINSVR_START' Error = 'InvalidCharacter ' \r\n", ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID);
		return RES_BREAK;
	}
	
// 2009-09-09 ~ 2010-02-18 by dhjin, 인피니티 - 진행 상황 체크 로그 추가
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::Process_FtoA_INFINITY_READY_FINISH_MAINSVR_START# ! %s InfiState(%d) \r\n"
//		, ClientFISoc->m_InfinityPlayingInfo.InfinityCreateUID, GetCharacterString(ClientFISoc->GetCharacter(), string()), ClientFISoc->m_InfinityPlayingInfo.InfinityState);

	ClientFISoc->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_NONE;

	// 2010. 08. 18. by hsLee. 메인 서버로 InfinityStater값 갱신 요청. (AFS -> MFS) 
	ClientFISoc->SendMFSInfinityStateChange ( ClientFISoc->m_InfinityPlayingInfo.InfinityState );

	ClientFISoc->SendAddMessageType(T_FC_INFINITY_READY_FINISH_MAINSVR_START);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::InfinityResetImpute(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 귀속 정보 리셋
///				// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 함수명 변경(기존 InfinityImputeReset)
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InfinityResetImpute(InfiModeUID_t i_ninfiModeUID)
{
	mt_auto_lock mtImpute(&m_mtVecInfiImpute);
	mt_vectorInfinityImpute::iterator itr = m_mtVecInfiImpute.begin();
	for(; itr != m_mtVecInfiImpute.end(); itr++)
	{
		INFINITY_IMPUTE *pImpute = itr;
		if(i_ninfiModeUID == pImpute->InfinityModeUID)
		{
			m_mtVecInfiImpute.erase(itr);
			return TRUE;
		}
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InfinityFinReloadAllItem()
/// \brief		인피니티 - 인피 종료 후 MainSvr에 인피 진행하면서 수정된 아이템 업데이트 종료로 모든 아이템 다시 불러오기!!
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityFinReloadAllItem() {
	m_InfinityUpdateAllItemCount--;
	// 2009-09-09 ~ 2010-02-18 by dhjin, 인피니티 - 진행 상황 체크 로그 추가
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ITEM][Infinity] InfinityFinReloadAllItem - , CharacterName = %s, InfinityUpdateAllItemCount = %d\r\n"
			, this->m_character.CharacterName, m_InfinityUpdateAllItemCount);
	if(0 == m_InfinityUpdateAllItemCount) {
		INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_READY_FINISH_MAINSVR_START, T_FtoA_INFINITY_READY_FINISH_MAINSVR_START, pSendMsg, SendBuf);
		pSendMsg->AFSClientIndex		= this->m_AFSClientIndex;
		ms_pFieldIOCP->m_pArenaFieldWinSocket->Write(SendBuf, MSG_SIZE(MSG_FtoA_INFINITY_READY_FINISH_MAINSVR_START));
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GetLvCheckRevision()
/// \brief		인피니티 - 보정 상황인지 체크
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Lv_t CFieldIOCPSocket::GetLvCheckRevision() {
	if(g_pFieldGlobal->IsArenaServer()

		// start 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		// 기존
		// && INFINITY_STATE_PLAYING == this->m_InfinityPlayingInfo.InfinityState) {

		// 수정
		&& TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState)) {
		// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		
		return max(this->m_character.Level, this->m_InfinityPlayingInfo.RevisionLevel);
	}
	
	return this->m_character.Level;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		인피니티 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::CalcDamageOfAttackMonsterToMonster(float i_fDamageWeight,
											  CFieldIOCPSocket *i_pAttackSocket, void* i_pAttackUnit, SATTACK_PARAMETER *i_pAttParam,
											  void *i_pTargetUnit) 
{
	
	float	fRetDamage = 0.0f;
	
	if(0.0f >= i_fDamageWeight) {
		return fRetDamage;
	}
	
	CParamFactor	*pTargetParamFactor = NULL;		// 피공격자가 캐릭터(C2C, M2C)
	
	CFieldMonster	*pAttackMonster = (CFieldMonster*)i_pAttackUnit;			// 공격자가 몬스터(M2C)
	CFieldMonster	*pTargetMonster = (CFieldMonster*)i_pTargetUnit;		// 피공격자가 몬스터(C2M)
	if(FALSE == pAttackMonster->IsValidMonster()
		|| FALSE == pTargetMonster->IsValidMonster()) {
		return fRetDamage;
	}

	MONSTER_INFO	*pTargetMonsterInfo = NULL;		// 피공격자가 몬스터(C2M)
	pTargetMonsterInfo	= pTargetMonster->MonsterInfoPtr;

	char szWeaponTypeString[1024];	// 디버그 스트링용
	STRNCPY_MEMSET(szWeaponTypeString, "Weapon", 1024);
#ifdef _DEBUG
	if (IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind))
	{
		sprintf(szWeaponTypeString, STRMSG_S_F2NOTIFY_0002);
	}
	else if (IS_SECONDARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind))
	{
		sprintf(szWeaponTypeString, STRMSG_S_F2NOTIFY_0003);
	}
	else if (IS_PRIMARY_WEAPON_MONSTER(i_pAttParam->pWeaponItemInfo->Kind))
	{
		sprintf(szWeaponTypeString, STRMSG_S_F2NOTIFY_0004, i_pAttParam->pWeaponItemInfo->ItemName);
	}
	else if (IS_SECONDARY_WEAPON_MONSTER(i_pAttParam->pWeaponItemInfo->Kind))
	{
		sprintf(szWeaponTypeString, STRMSG_S_F2NOTIFY_0005, i_pAttParam->pWeaponItemInfo->ItemName);
	}
	else if(IS_SKILL_ITEM(i_pAttParam->pWeaponItemInfo->Kind))
	{
		sprintf(szWeaponTypeString, "Skill(%s)", i_pAttParam->pWeaponItemInfo->ItemName);
	}
	else
	{
		// invalid item kind
		sprintf(szWeaponTypeString, STRMSG_S_F2NOTIFY_0006);
	}
#endif

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 1. 공격/방어 확률 처리
	///////////////////////////////////////////////////////////////////////////////	
	BOOL bIsPrimaryAttack = IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind) || IS_PRIMARY_WEAPON_MONSTER(i_pAttParam->pWeaponItemInfo->Kind);
	
	float	fAttackSuccessProbability	= 0.0f;
	float	fAttackProbability			= 0.0f;
	float	fDefenseProbability			= 0.0f;

	fAttackProbability	= i_pAttParam->fAttackProbability;

	if ((pAttackMonster->MonsterInfoPtr->Level - pTargetMonster->MonsterInfoPtr->Level) >= 1) {
		// 2010-07-19 by dhjin, 확률 수식 변경
		// 2% UP
//		fAttackProbability += 0.02f*PROB256_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - pTargetMonster->MonsterInfoPtr->Level);
		fAttackProbability += 0.02f*PROB100_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - pTargetMonster->MonsterInfoPtr->Level);
	}
	else {
		// 2010-07-19 by dhjin, 확률 수식 변경
		// 2% DOWN
//		fAttackProbability -= 0.02f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - pAttackMonster->MonsterInfoPtr->Level);
		fAttackProbability -= 0.02f*PROB100_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - pAttackMonster->MonsterInfoPtr->Level);	
	}
	
	// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
	//fDefenseProbability	= CAtumSJ::GetDefenseProbabilityM(pTargetMonsterInfo);
	fDefenseProbability	= CAtumSJ::GetDefenseProbabilityM(pTargetMonsterInfo , &pTargetMonster->MonsterInfoExtend );
	// End 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )

	fAttackSuccessProbability = fAttackProbability - fDefenseProbability;
	// 2010-07-19 by dhjin, 확률 수식 변경
	float fRandProbability = RANDF2(0,100);
	if(fRandProbability > fAttackSuccessProbability)
	{// 2007-06-07 by cmkwon, 공격 실패 - 공격/방어 확률로
		return 0.0f;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 2. 공격력/방어력 처리(피어스율적용)
	///////////////////////////////////////////////////////////////////////////////	
	float fDefense = 0.0f;

	// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
	//fDefense	= max(0.0f, CAtumSJ::GetDefenseM(pTargetMonsterInfo) - i_pAttParam->fPierceAttackProbability);
	fDefense	= max(0.0f, CAtumSJ::GetDefenseM(pTargetMonsterInfo , FALSE , &pTargetMonster->MonsterInfoExtend ) - i_pAttParam->fPierceAttackProbability);
	// End 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )

	// 2010-07-19 by dhjin, 확률 수식 변경
//	fRetDamage	= i_pAttParam->fAttack*(PROB256_MAX_VALUE-fDefense)/PROB256_MAX_VALUE;
	fRetDamage	= i_pAttParam->fAttack*(PROB100_MAX_VALUE-fDefense)/PROB100_MAX_VALUE;

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-07 by cmkwon, 3. 각과 거리에 따른 factor 적용 - 확률이 성공하면 최소 1의 데미지
	///////////////////////////////////////////////////////////////////////////////	
	fRetDamage = max(1.0f, fRetDamage * i_fDamageWeight);
	fRetDamage = min(i_pAttParam->fMaxAttack, fRetDamage);

	///////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 계산된 데미지 적용
	///////////////////////////////////////////////////////////////////////////
//	float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByMonster(fRetDamage);
	float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHP(fRetDamage);		// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리
	pAttackMonster->GetCurrentMapChannelMonster()->FieldSendMonsterChangeInfo(pTargetMonster, T_FN_MONSTER_CHANGE_HP);
	if (fMonCurHP <= 0.0f) {
		// 몬스터가 폭파된 경우
		OnMonsterDeadByMonster((CFieldMonster*)pTargetMonster, i_pAttParam->pWeaponItemInfo);
	}
	
// 2010-04-02 by cmkwon
//	if(BELL_INFINITY_DEFENSE_MONSTER == pTargetMonster->MonsterInfoPtr->Belligerence
//		&& COMPARE_BIT_FLAG(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_KEY_MONSTER_ALIVE_FOR_GAMECLEAR))
//	{
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] Check CFieldIOCPSocket::CalcDamageOfAttackMonsterToMonster# Map(%s) AttMonIdx(%d) TargMonIdx(%d) WeaponIdx(%d) Damage(%5.2f) CurHP(%5.2f) \r\n"
//			, GetMapString(pAttackMonster->GetCurrentMapChannelMonster()->GetMapChannelIndex(), string()), pAttackMonster->MonsterIndex, pTargetMonster->MonsterIndex, i_pAttParam->WeaponIndex, fRetDamage, fMonCurHP);
//	}

	return fRetDamage;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnMonsterDeadByMonster(CFieldMonster *pTargetMonster, ITEM *pAttackItem)
/// \brief		인피니티 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnMonsterDeadByMonster(CFieldMonster *pTargetMonster, ITEM *pAttackItem) {

	CFieldMapChannel *pFieldMapChannel = pTargetMonster->GetCurrentMapChannelMonster();
	if(NULL == pFieldMapChannel){						return;}
	
	///////////////////////////////////////////////////////////////////////////////
	// 몬스터가 공격받은 리스트를 임시 변수에 할당하고 초기화 한다
	vectorActionInfoPtr tmAttackedInfo;
	if(FALSE == pTargetMonster->OnDead(&tmAttackedInfo))
	{
		return;
	}

	if(tmAttackedInfo.empty()) {
		pFieldMapChannel->OnMonsterDeadFieldMapChannel(pTargetMonster);
		return;
	}

	// 2005-12-28 by cmkwon, 여단 데미지 합 계산을 위해
	CGuildDamageManager	guildDamageManager;
	CEXPDivisionManager	expDivisionMan(ms_pFieldIOCP, pFieldMapChannel);

	CFieldIOCPSocket	*pFISock = NULL;
	/////////////////////////////////////////////////////////////////////////
	// - 경험치 데미지 계산
	/////////////////////////////////////////////////////////////////////////
	vectorActionInfoPtr::iterator itr = tmAttackedInfo.begin();
	while (itr != tmAttackedInfo.end())
	{
		ActionInfo *pTmpActionInfo = *itr;
		pFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pTmpActionInfo->UnitIndex);
		if (NULL == pFISock
			|| FALSE == pFISock->IsValidCharacter())
		{// 공격한 캐릭터가 유효하지 않다
			delete pTmpActionInfo;
			itr = tmAttackedInfo.erase(itr);
			continue;
		}

		pFISock->DeleteAttackTargetIndexVector(pTargetMonster->MonsterIndex);
		if (pFieldMapChannel != pFISock->GetCurrentFieldMapChannel())
		{// 죽은 몬스터와 맵이 다를때, Aggro 시스템이 적용되면서 데미지합이 0.0인 데이타도 정상적으로 처리해야함
			delete pTmpActionInfo;
			itr = tmAttackedInfo.erase(itr);
			continue;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-28 by cmkwon, 세력전 보스 몬스터 처리
		if(COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER)
			&& IS_MOTHERSHIPWAR_MONSTER(pTargetMonster->MonsterInfoPtr->Belligerence)	
//			&& IS_INFLWAR_MONSTER(pTargetMonster->MonsterInfoPtr->Belligerence)	// 2007-08-21 by dhjin, 모선전 관련 모선, 전략포인트만 구분 가능하게 변경
			&&	pFISock->IsValidGuild())
		{
			guildDamageManager.AddSumOfDamage(pFISock->GetCharacter()->GuildUniqueNumber, pFISock->m_character.GuildName, pTmpActionInfo->fSumDamage);
		}

		expDivisionMan.AddEXPDivision(pFISock, pTmpActionInfo->fSumDamage, pTmpActionInfo->fSumAggro);
		itr++;
	}// 총 Damage 합산 완료

	///////////////////////////////////////////////////////////////////////////////
	// 보스급 몬스터 DB에 로그 저장하기
	// 
	// for boss monster log
	MSG_FL_LOG_MONSTER_BOSS msgBossMonsterLog;
	if (COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER))
	{
		msgBossMonsterLog.MapChannel		= pFieldMapChannel->GetMapChannelIndex();
		time_t tmpTime = ms_pFieldIOCP->m_dwTimeStarted + (pTargetMonster->m_dwTimeCreatedTick - ms_pFieldIOCP->m_dwTickStarted)/1000;
		msgBossMonsterLog.CreatedTime		= *localtime(&tmpTime);
		msgBossMonsterLog.DeadTime.SetCurrentDateTime();
		msgBossMonsterLog.MonsterUnitKind	= pTargetMonster->MonsterInfoPtr->MonsterUnitKind;
		MEMSET_ZERO(msgBossMonsterLog.AttackUser, SIZE_MAX_USERLIST_ON_BOSS_MONSTER_DEAD*SIZE_MAX_CHARACTER_NAME);

		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-28 by cmkwon, 세력전 보스 몬스터 처리
		if(IS_MOTHERSHIPWAR_MONSTER(pTargetMonster->MonsterInfoPtr->Belligerence))
//		if(IS_INFLWAR_MONSTER(pTargetMonster->MonsterInfoPtr->Belligerence))			// 2007-08-21 by dhjin, 모선전 관련 모선, 전략포인트만 구분 가능하게 변경
		{
			OnInfluenceBossMonsterDead(pTargetMonster, pFieldMapChannel, &guildDamageManager);
		}
	}
	//
	///////////////////////////////////////////////////////////////////////////////
	// 2010-06-21 by jskim, 2010 이벤트(한명당 아이템 하나씩) - 오리진(2098200)
	if(pTargetMonster->MonsterInfoPtr->MonsterUnitKind == 2098200)
	{
		pFieldMapChannel->AddWarPointInMap(ADD_WARPOINT_EVENT_MONSTER_BY_LOSE, FALSE);
	}

	if(CFieldIOCPSocket::IsValidStrategyPointMonster(pTargetMonster, pFieldMapChannel))
	{// 2006-11-21 by cmkwon, 전략포인트 몬스터 유효성 체크 - 전략포인트 몬스터 죽음 처리
		OnStrategyPointMonsterDead(pTargetMonster, pFieldMapChannel);
	}

	// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정
	if(IS_TELEPORT_MONSTER(pTargetMonster->MonsterInfoPtr->Belligerence))
	{
		CFieldIOCPSocket::OnTeleportMonsterDead(pTargetMonster, pFieldMapChannel);
	}

	float	fTotalDamage = expDivisionMan.GetTotalOfDamage();
	int		nDivisionCnt = expDivisionMan.GetvectSEXP_DIVISIONListSize();
	if (fTotalDamage <= 0.0f
		|| 0 >= nDivisionCnt)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 임시 변수를 삭제 처리한다
		for_each(tmAttackedInfo.begin(), tmAttackedInfo.end(), Delete_Object());
		tmAttackedInfo.clear();
		
		if (COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER))
		{// 보스몹 로그 저장
			string strDropItemList;
			CAtumLogSender::SendLogMessageMonsterBoss(&msgBossMonsterLog, strDropItemList);
		}
		pFieldMapChannel->OnMonsterDeadFieldMapChannel(pTargetMonster);

		return;
	}
	
	/////////////////////////////////////////////////////////////////////////
	// - Damage 기여도에 따라 경험치 분배 및 아이템 먹기 Delay 설정
	// - 파티가 있는 경우, 그 파티원들이 준 Damage의 총 합을 기여도로 하여,
	//                   모든 파티원에게 경험치 및 Delay를 균등하게 설정
	/////////////////////////////////////////////////////////////////////////
	expDivisionMan.SortByDamageDecrease();
	CFieldIOCPSocket *pFISockofTopDamage = NULL;
	SEXP_DIVISION tmExpDivison;
	if(expDivisionMan.GetSEXP_DIVISIONOfTopDamage(&tmExpDivison))
	{
		pFISockofTopDamage = tmExpDivison.ArrSEXP_PARTYMEMBER[0].pFISock0;
		pFISockofTopDamage->AddCharacterQuestMonsterCount(pTargetMonster->MonsterInfoPtr->MonsterUnitKind, TRUE);	

		///////////////////////////////////////////////////////////////////////////////
		// 2009-01-13 by cmkwon, 미션 보상을 파티원 모두에게 주기 명령어 추가 - 모든 파티원 보상 체크를 한다.
		if(tmExpDivison.pFParty0)
		{
			vectCFieldIOCPSocket vectCFISockList;
			pFISockofTopDamage->GetPartyMemberList(&vectCFISockList);

			vectCFieldIOCPSocket::iterator itr(vectCFISockList.begin());
			for(; itr != vectCFISockList.end(); itr++)
			{
				CFieldIOCPSocket *pTmFISoc = *itr;
				if(NULL == pTmFISoc
					|| pTmFISoc == pFISockofTopDamage
					|| FALSE == pTmFISoc->IsValidCharacter(FALSE)
					|| FALSE == pFISockofTopDamage->m_character.MapChannelIndex.IsSameMapChannelIndex(pTmFISoc->m_character.MapChannelIndex))	// 2009-01-13 by cmkwon, 같은 맵의 유저 체크
				{
					continue;
				}

				BOOL bAttacker	= FALSE;
 				for(int j=0; j < tmExpDivison.nPartyMemberCnts; j++)
 				{
 					CFieldIOCPSocket *pTm2FISoc	= tmExpDivison.ArrSEXP_PARTYMEMBER[j].pFISock0;
 					if(pTm2FISoc
						&& pTmFISoc == pTm2FISoc)
 					{
 						bAttacker = TRUE;
						break;
 					}
 				}
 				pTmFISoc->AddCharacterQuestMonsterCount(pTargetMonster->MonsterInfoPtr->MonsterUnitKind, FALSE, bAttacker);
			}
		}

	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-13 by cmkwon, 경험치 분배
	DROPITEM			dropItem;	// priorityInfoCount는 생성자에서 0으로 할당
	
	// 2010. 05. 31 by hsLee 인피니티 필드 2차 난이도 조절. (오브젝트 몬스터 밸런스 적용 문제 수정.) - 몬스터 처치 획득 경험치에 밸런스 정보 적용.
// 	if(IS_MAP_INFLUENCE_INFINITY(pFieldMapChannel->GetMapInfluenceTypeW())) {
// 		expDivisionMan.ProcessEXPDivisionInfinityMap(&dropItem, &msgBossMonsterLog, pTargetMonster->MonsterInfoPtr->Experience, COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER));
// 	}
// 	else {
// 		expDivisionMan.ProcessEXPDivision(&dropItem, &msgBossMonsterLog, pTargetMonster->MonsterInfoPtr->Experience, COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER));
// 	}
	if( IS_MAP_INFLUENCE_INFINITY(pFieldMapChannel->GetMapInfluenceTypeW() ) ) 
	{
		expDivisionMan.ProcessEXPDivisionInfinityMap(&dropItem, &msgBossMonsterLog, pTargetMonster->rtn_MonsterExperience() , COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER));
	}
	else 
	{
		expDivisionMan.ProcessEXPDivision(&dropItem, &msgBossMonsterLog, pTargetMonster->rtn_MonsterExperience() , COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER));
	}
	// End 2010. 05. 31 by hsLee 인피니티 필드 2차 난이도 조절. (오브젝트 몬스터 밸런스 적용 문제 수정.)

	float fPartyBonus = 0.0f;
	if(pFISockofTopDamage
		&& pFISockofTopDamage->IsValidCharacter()
		&& pFISockofTopDamage->m_pFieldParty)
	{
		SEXP_DIVISION *pExpDivision = expDivisionMan.FindEXPDivisionByFPartyPtr(pFISockofTopDamage->m_pFieldParty);
		if(pExpDivision)
		{
			fPartyBonus = pExpDivision->fPartyBonus - 1.0f;
		}
	}
	ms_pFieldIOCP->CreateDropItems(expDivisionMan.GetlitMonsterDropItemPtr(), pTargetMonster, pFISockofTopDamage, fPartyBonus);

	string strDropItemList;
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
//	expDivisionMan.ProcessPickUpDropItems(&strDropItemList, &dropItem, pTargetMonster, pFISockofTopDamage);
	if(IS_MAP_INFLUENCE_INFINITY(pFieldMapChannel->GetMapInfluenceTypeW()))
	{
		expDivisionMan.ProcessPickUpDropItemsInfinityMap(&strDropItemList, &dropItem, pTargetMonster, &(ms_pFieldIOCP->m_InfinityManager));
	}
	else
	{
		expDivisionMan.ProcessPickUpDropItems(&strDropItemList, &dropItem, pTargetMonster, pFISockofTopDamage);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 임시 변수를 삭제 처리한다
	for_each(tmAttackedInfo.begin(), tmAttackedInfo.end(), Delete_Object());
	tmAttackedInfo.clear();
	
	if (COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER))
	{// 보스몹 로그 저장
		
		CAtumLogSender::SendLogMessageMonsterBoss(&msgBossMonsterLog, strDropItemList);
	}

	pFieldMapChannel->OnMonsterDeadFieldMapChannel(pTargetMonster);

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-24 by dhjin, 전진기지 관련 처리
	if(BELL_ATTACK_OUTPOST_PROTECTOR == pTargetMonster->MonsterInfoPtr->Belligerence
		|| BELL_OUTPOST_PROTECTOR_VCN == pTargetMonster->MonsterInfoPtr->Belligerence
		|| BELL_OUTPOST_PROTECTOR_ANI == pTargetMonster->MonsterInfoPtr->Belligerence)
	{// 2007-08-24 by dhjin, 전진기지 보호막 파괴시
		ms_pFieldIOCP->OnOutPostProtectorDestroyW(pFieldMapChannel->GetMapChannelIndex().MapIndex);
	}
	if(BELL_OUTPOST_RESET_VCN == pTargetMonster->MonsterInfoPtr->Belligerence
		|| BELL_OUTPOST_RESET_ANI == pTargetMonster->MonsterInfoPtr->Belligerence)
	{// 2007-08-24 by dhjin, 전진기지 중앙처리장치 파괴시
		ms_pFieldIOCP->OnOutPostResetDestroyW(pFieldMapChannel->GetMapChannelIndex().MapIndex);
	}

}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
/// \author		cmkwon
/// \date		2009-12-11 ~ 2009-12-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetLastMonsterIndexAttack2Me(ClientIndex_t i_MonIdx)
{
	m_nLastMonsterIndexAttack2Me	= i_MonIdx;
}
///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
/// \author		cmkwon
/// \date		2009-12-11 ~ 2009-12-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ClientIndex_t CFieldIOCPSocket::GetLastMonsterIndexAttack2Me(void)
{
	return m_nLastMonsterIndexAttack2Me;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
/// \author		cmkwon
/// \date		2009-12-11 ~ 2009-12-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetTargetMonsterIndex(ClientIndex_t i_MonIdx)
{
	m_nTargetMonsterIndex	= i_MonIdx;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
/// \author		cmkwon
/// \date		2009-12-11 ~ 2009-12-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ClientIndex_t CFieldIOCPSocket::GetTargetMonsterIndex(void)
{
	return m_nTargetMonsterIndex;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
/// \author		cmkwon
/// \date		2009-12-11 ~ 2009-12-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GetAttackedMonsterIndex(setClientIndex_t *o_pMonsterIdxList)
{
	o_pMonsterIdxList->insert(this->GetTargetMonsterIndex());
	
	mt_auto_lock mtAuto(&m_mtvectAttackTargetMonsterIndex);
	o_pMonsterIdxList->insert(m_mtvectAttackTargetMonsterIndex.begin(), m_mtvectAttackTargetMonsterIndex.end());
	mtAuto.auto_unlock_cancel();
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::MonsterAttackSecM2C(CFieldMonster * i_pAttackMonster, MSG_FN_BATTLE_ATTACK_SECONDARY * i_pAttackSecMsgInfo, ITEM * i_pAttackItem)
/// \brief		인피니티 - 몬스터 일반 공격 처리 M->C
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::MonsterAttackSecM2C(CFieldMonster * i_pAttackMonster, MSG_FN_BATTLE_ATTACK_SECONDARY * i_pAttackSecMsgInfo, ITEM * i_pAttackItem) {
	CFieldIOCPSocket	*pPeerFieldIOCPSocket = NULL;
	CHARACTER			*pCharacter;
	if(!CheckValidAttackTargetCharacter(i_pAttackMonster->m_pCurrentFieldMapChannelMonster, i_pAttackSecMsgInfo->TargetIndex, pPeerFieldIOCPSocket, pCharacter))
	{
		// 피공격자의 캐릭터가 유효한지 체크
		return FALSE;
	}
	
	D3DXVECTOR3		vec3AttackPos = A2DX(i_pAttackSecMsgInfo->AttackPosition);
	if(D3DXVec3Length(&(pPeerFieldIOCPSocket->m_character.PositionVector - vec3AttackPos)) > i_pAttackItem->Range) {
		return FALSE;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
	pSFCAttackOK->AttackIndex = i_pAttackSecMsgInfo->AttackIndex;
	pSFCAttackOK->TargetInfo.TargetIndex = i_pAttackSecMsgInfo->TargetIndex;
	pSFCAttackOK->TargetInfo.TargetItemFieldIndex = 0;
	pSFCAttackOK->TargetInfo.TargetPosition = pCharacter->PositionVector;
	pSFCAttackOK->FirePosition.Reset();	
	pSFCAttackOK->AttackType = ATT_TYPE_GENERAL_SEC;
	pSFCAttackOK->WeaponIndex = i_pAttackSecMsgInfo->WeaponIndex;
	pSFCAttackOK->ItemNum = i_pAttackItem->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
	pSFCAttackOK->RemainedBulletFuel = 0;
	pSFCAttackOK->SkillNum = 0;

	pPeerFieldIOCPSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
	ms_pFieldIOCP->SendInRangeMessageExactAroundPosition(i_pAttackMonster->PositionVector, Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK)
		, i_pAttackMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW()/2, i_pAttackMonster->m_pCurrentFieldMapChannelMonster
			, pPeerFieldIOCPSocket->GetCharacter()->ClientIndex);

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::MonsterAttackSecM2M(CFieldMonster * i_pAttackMonster, MSG_FN_BATTLE_ATTACK_SECONDARY * i_pAttackSecMsgInfo, ITEM * i_pAttackItem)
/// \brief		인피니티 - 몬스터 일반 공격 처리 M->M
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::MonsterAttackSecM2M(CFieldMonster * i_pAttackMonster, MSG_FN_BATTLE_ATTACK_SECONDARY * i_pAttackSecMsgInfo, ITEM * i_pAttackItem) {
	CFieldMonster *pTargetFMonster = m_pFieldMapProjectForNPC->GetFieldMonsterW(i_pAttackSecMsgInfo->ChannelIndex, i_pAttackSecMsgInfo->TargetIndex, 105);
	if(NULL == pTargetFMonster
		|| pTargetFMonster->m_enMonsterState != MS_PLAYING
		|| TRUE == COMPARE_BODYCON_BIT(pTargetFMonster->BodyCondition, BODYCON_DEAD_MASK)) {
		return FALSE;
	}
	
	D3DXVECTOR3		vFrontVel, vExpectPos;

	D3DXVECTOR3		vec3AttackPos = A2DX(i_pAttackSecMsgInfo->AttackPosition);

	// start 2011-06-13 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	int fMonsterMultiTargetIndex = 0;
	D3DXVECTOR3 fMonsterMultiTargetVector = pTargetFMonster->GetNearMultiTarget(vec3AttackPos, &fMonsterMultiTargetIndex);

	//////////
	// 기존
	//if(D3DXVec3Length(&(pTargetFMonster->PositionVector - vec3AttackPos)) > i_pAttackItem->Range)

	//////////
	// 수정
	if(D3DXVec3Length(&(fMonsterMultiTargetVector - vec3AttackPos)) > i_pAttackItem->Range)
	// end 2011-06-13 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	{
		return FALSE;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
	pSFCAttackOK->AttackIndex						= i_pAttackSecMsgInfo->AttackIndex;
	pSFCAttackOK->TargetInfo.TargetIndex			= i_pAttackSecMsgInfo->TargetIndex;
	pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;

	// start 2011-03-22 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	//////////
	// 기존 //
	//pSFCAttackOK->TargetInfo.TargetPosition			= pTargetFMonster->PositionVector;
	//////////
	// 수정 //
	pSFCAttackOK->TargetInfo.TargetPosition			= pTargetFMonster->PositionVector + pTargetFMonster->GetPointMultiTarget(i_pAttackSecMsgInfo->MultiTargetIndex);

	pSFCAttackOK->TargetInfo.MultiTargetIndex		= i_pAttackSecMsgInfo->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	// end 2011-03-22 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가

	pSFCAttackOK->FirePosition.Reset();	
	pSFCAttackOK->AttackType						= ATT_TYPE_GENERAL_SEC;
	pSFCAttackOK->WeaponIndex						= i_pAttackSecMsgInfo->WeaponIndex;
	pSFCAttackOK->ItemNum							= i_pAttackItem->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
	pSFCAttackOK->RemainedBulletFuel				= 0;
	pSFCAttackOK->SkillNum							= 0;


	if(FALSE == this->GetDelegateClientIdxByMonsterAttackSecM2M(i_pAttackMonster, &pSFCAttackOK->DelegateClientIdx)) 
	{
		// start 2011-03-28 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		///////////////
		// 기존 소스 //
		// return FALSE;

		///////////////
		// 수정 소스 //
		ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pSFCAttackOK->ItemNum);

		if(NULL == pItemInfo) 
		{
			return FALSE;
		}

		if( pItemInfo->Kind == ITEMKIND_FOR_MON_MAIN_ARMAMENT )		// 공격 아이템 종류가 메인 주포일 경우
		//if( g_pFieldGlobal->IsArenaServer() == TRUE )		// 아레나 서버일 경우
		{
			this->GetDelegateClientIdx(i_pAttackMonster, &pSFCAttackOK->DelegateClientIdx);			// 2011-04-18 by hskim, 인피니티 3차 - 주포 공격 방식 변경
		}
		else
		{
			return FALSE;
		}
		// end 2011-03-28 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-13 by cmkwon, 결과 전송
	i_pAttackMonster->GetCurrentMapChannelMonster()->SendMessageToAllInChannel(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
// 	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(i_pAttackSecMsgInfo->AttackIndex, Sendbuf
// 		, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), i_pAttackMonster->m_pCurrentFieldMapChannelMonster
// 			, FALSE, i_pAttackMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW());

	return TRUE;
}

// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack#로 통합
// ///////////////////////////////////////////////////////////////////////////////
// /// \fn			void CFieldIOCPSocket::ProcessRangeDamageMonsterAllAttack(MSG_FN_BATTLE_ATTACK_PRIMARY *i_pAttackPri, CFieldIOCPSocket *i_pAttackMonSock, CFieldMonster *i_pAttackMon, ITEM *i_pAttackItem)
// /// \brief		인피니티 - 몬스터 범위 공격
// /// \author		dhjin
// /// \date		2009-09-09 ~ 2010
// /// \warning	
// ///
// /// \param		
// /// \return		
// ///////////////////////////////////////////////////////////////////////////////
// void CFieldIOCPSocket::ProcessRangeDamageMonsterAllAttack(MSG_FN_BATTLE_ATTACK_PRIMARY *i_pAttackPri, CFieldIOCPSocket *i_pAttackMonSock, CFieldMonster *i_pAttackMon, ITEM *i_pAttackItem) {
// 	if (i_pAttackItem->Kind != ITEMKIND_FOR_MON_RANGE_ATTACK
// 		|| i_pAttackItem->ExplosionRange <= 0)
// 	{// 2005-12-13 by cmkwon, 아이템 설정 오류
// 		char szTemp[1024];
// 		sprintf(szTemp, "[Error] Monster Item Error, Monster(%d:%s) MonsterItem(%d:%s), ItemKind(%s), ExplosionRange(%d)\r\n"
// 			, i_pAttackMon->MonsterInfoPtr->MonsterUnitKind, i_pAttackMon->MonsterInfoPtr->MonsterName
// 			, i_pAttackItem->ItemNum, i_pAttackItem->ItemName, CAtumSJ::GetItemKindName(i_pAttackItem->Kind), i_pAttackItem->ExplosionRange);
// 		DbgOut(szTemp);
// 		g_pFieldGlobal->WriteSystemLog(szTemp);
// 		return;
// 	}
// 	
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2007-10-22 by cmkwon, 체크 추가
// 	if(NULL == i_pAttackMon)
// 	{
// 		return;
// 	}
// 	MONSTER_INFO *pMonInfo = i_pAttackMon->MonsterInfoPtr;
// 	if(NULL == pMonInfo
// 		|| FALSE == i_pAttackMon->IsValidMonster())
// 	{
// 		return;
// 	}
// 	
// 	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
// 	pSFCAttackOK->AttackIndex						= i_pAttackPri->AttackIndex;
// 	pSFCAttackOK->TargetInfo.TargetIndex			= i_pAttackPri->TargetIndex;
// 	pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 	pSFCAttackOK->TargetInfo.TargetPosition			= i_pAttackPri->TargetPosition;
// 	pSFCAttackOK->FirePosition.Reset();	
// 	pSFCAttackOK->AttackType						= ATT_TYPE_GENERAL_PRI;
// 	pSFCAttackOK->WeaponIndex						= i_pAttackPri->WeaponIndex;
// 	pSFCAttackOK->ItemNum							= i_pAttackItem->ItemNum;	// 몬스터의 공격 무기 ItemNum을 설정
// 	pSFCAttackOK->RemainedBulletFuel				= 0;
// 	pSFCAttackOK->SkillNum							= 0;
// 	
// 	vector<ClientIndex_t>	ClientIndexVector;		ClientIndexVector.reserve(100);
// 	CFieldMapChannel		*pMapChannel = i_pAttackMon->m_pCurrentFieldMapChannelMonster;
// 	
// 	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
// 	SATTACK_PARAMETER attParam;	
// 	MEMSET_ZERO(&attParam, sizeof(attParam));
// 	i_pAttackMon->APCalcAttckParameter(&attParam, i_pAttackItem, i_pAttackPri->WeaponIndex);
// 	
// 	// 2009-09-09 ~ 2010-01-20 by dhjin, 인피니티 - 공격자 중심 반경으로 체크한다. 밑과 같이 수정
// //	D3DXVECTOR3		vec3ExplosionPos = A2DX(i_pAttackPri->TargetPosition);		
// 	D3DXVECTOR3		vec3ExplosionPos = i_pAttackMon->PositionVector;
// 	
// 	////////////////////////////////////////////////////////////////////////////////
// 	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - BELL_INFINITY_DEFENSE_MONSTER 몬스터는 BELL_INFINITY_ATTACK_MONSTER 몬스터에게만 공격
// 	// 1. 폭발 범위 안에 있는 BELL_INFINITY_ATTACK_MONSTER 몬스터 목록 뽑는다.
// 	// 2. 범위각 안에 있는 BELL_INFINITY_ATTACK_MONSTER 몬스터라면 빙고.
// 	if(BELL_INFINITY_DEFENSE_MONSTER == pMonInfo->Belligerence) {
// 		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 															i_pAttackItem->ExplosionRange, &ClientIndexVector);		//	1. 폭발 범위 안에 있는 BELL_INFINITY_ATTACK_MONSTER 몬스터 목록 뽑는다.
// 		if (nMonsters <= 0) {
// 			// 2005-12-13 by cmkwon, 타겟이 없음
// 			return;
// 		}
// 		
// 		for(int i= 0; i < nMonsters; i++) {
// 			///////////////////////////////////////////////////////////////////////////////
// 			// 초기화
// 			CFieldMonster *pTargetFMonster = pMapChannel->GetFieldMonster(i_pAttackPri->TargetIndex, 108);
// 			if(NULL == pTargetFMonster
// 				|| pTargetFMonster->m_enMonsterState != MS_PLAYING
// 				|| TRUE == COMPARE_BODYCON_BIT(pTargetFMonster->BodyCondition, BODYCON_DEAD_MASK)
// 				|| BELL_INFINITY_ATTACK_MONSTER != pTargetFMonster->MonsterInfoPtr->Belligerence) {
// 				continue;
// 			}
// 			pSFCAttackOK->TargetInfo.TargetIndex			= 0;
// 			pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 			
// 			float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetFMonster->PositionVector));
// 			D3DXVECTOR3		tmUnitVec3M2C;
// 			D3DXVec3Normalize(&tmUnitVec3M2C, &(pTargetFMonster->PositionVector - i_pAttackMon->PositionVector));		// 현재 몬스터에서 클라이언트를 향하는 Target Vector를 구한다.
// 			float fPinPoint = ACOS(D3DXVec3Dot(&i_pAttackMon->TargetVector, &tmUnitVec3M2C));						// 몬스터에서 Target Vector와 위에서 구한 현재 Target Vector 사이의 각을 구한다
// 			if(fPinPoint <= i_pAttackItem->RangeAngle) {
// 				// 2. 범위각 안에 있는 BELL_INFINITY_ATTACK_MONSTER 몬스터라면 빙고.
// 				float fDamage = CalcDamageOfAttackMonsterToMonster(1.0f
// 					, i_pAttackMonSock, i_pAttackMon, &attParam, (void*)pTargetFMonster);
// 			}
// 
// 			ms_pFieldIOCP->SendInRangeMessageAroundCharacter(i_pAttackPri->AttackIndex, Sendbuf
// 				, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), i_pAttackMon->m_pCurrentFieldMapChannelMonster
// 				, FALSE, i_pAttackMon->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW());
// 		}// end_for(int i= 0; i < nMonsters; i++)
// 		
// 		return;
// 	}
// 
// 	////////////////////////////////////////////////////////////////////////////////
// 	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - BELL_INFINITY_ATTACK_MONSTER 몬스터는 BELL_INFINITY_DEFENSE_MONSTER 몬스터와 유저 공격
// 	// 1. 폭발 범위 안에 있는 BELL_INFINITY_DEFENSE_MONSTER 몬스터 목록 뽑는다.
// 	// 2. 범위각 안에 있는 BELL_INFINITY_DEFENSE_MONSTER 몬스터라면 빙고.
// 	// 3. 폭발 범위 안에 있는 유저 목록 뽑는다.
// 	// 4. 범위각 안에 있는 유저라면 빙고.
// 	if(BELL_INFINITY_ATTACK_MONSTER == pMonInfo->Belligerence) {
// 		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 															i_pAttackItem->ExplosionRange, &ClientIndexVector);					// 1. 폭발 범위 안에 있는 BELL_INFINITY_DEFENSE_MONSTER 몬스터 목록 뽑는다.
// 		if (nMonsters > 0) {
// 			for(int i= 0; i < nMonsters; i++) {
// 				///////////////////////////////////////////////////////////////////////////////
// 				// 초기화
// 				CFieldMonster *pTargetFMonster = pMapChannel->GetFieldMonster(i_pAttackPri->TargetIndex, 105);
// 				if(NULL == pTargetFMonster
// 					|| pTargetFMonster->m_enMonsterState != MS_PLAYING
// 					|| TRUE == COMPARE_BODYCON_BIT(pTargetFMonster->BodyCondition, BODYCON_DEAD_MASK)
// 					|| BELL_INFINITY_DEFENSE_MONSTER != pTargetFMonster->MonsterInfoPtr->Belligerence) {
// 					continue;
// 				}
// 				pSFCAttackOK->TargetInfo.TargetIndex			= 0;
// 				pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 				
// 				float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetFMonster->PositionVector));
// 				D3DXVECTOR3		tmUnitVec3M2C;
// 				D3DXVec3Normalize(&tmUnitVec3M2C, &(pTargetFMonster->PositionVector - i_pAttackMon->PositionVector));		// 현재 몬스터에서 클라이언트를 향하는 Target Vector를 구한다.
// 				float fPinPoint = ACOS(D3DXVec3Dot(&i_pAttackMon->TargetVector, &tmUnitVec3M2C));						// 몬스터에서 Target Vector와 위에서 구한 현재 Target Vector 사이의 각을 구한다
// 				if(fPinPoint <= i_pAttackItem->RangeAngle) {
// 					// 2. 범위각 안에 있는 BELL_INFINITY_DEFENSE_MONSTER 몬스터라면 빙고.
// 					float fDamage = CalcDamageOfAttackMonsterToMonster(1.0f
// 						, i_pAttackMonSock, i_pAttackMon, &attParam, (void*)pTargetFMonster);
// 				}
// 
// 				ms_pFieldIOCP->SendInRangeMessageAroundCharacter(i_pAttackPri->AttackIndex, Sendbuf
// 					, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), i_pAttackMon->m_pCurrentFieldMapChannelMonster
// 					, FALSE, i_pAttackMon->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW());
// 			}// end_for(int i= 0; i < nMonsters; i++)	
// 		}
// 		
// 		int nCharacters = pMapChannel->GetAdjacentCharacterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 									i_pAttackItem->ExplosionRange, &ClientIndexVector);	// 3. 폭발 범위 안에 있는 유저 목록 뽑는다.
// 		if (nCharacters <= 0) {
// 			for(int i= 0; i < nCharacters; i++)
// 			{
// 				///////////////////////////////////////////////////////////////////////////////
// 				// 초기화
// 				pSFCAttackOK->TargetInfo.TargetIndex			= 0;
// 				pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 				
// 				CFieldIOCPSocket	*pTargetCharacterSocket = NULL;
// 				CHARACTER			*pTargetCharacter = NULL;
// 				ClientIndex_t		tmpClientIndex = ClientIndexVector[i];
// 				
// 				if (FALSE == i_pAttackMonSock->CheckValidAttackTargetCharacter(pMapChannel, tmpClientIndex, pTargetCharacterSocket, pTargetCharacter))
// 				{
// 					continue;
// 				}
// 				
// 				if(FALSE == IS_SAME_CHARACTER_MONSTER_INFLUENCE(pTargetCharacter->InfluenceType, pMonInfo->Belligerence)
// 					&& BELL_INFINITY_DEFENSE_MONSTER != pMonInfo->Belligerence)		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - BELL_INFINITY_DEFENSE_MONSTER 몬스터에게 공격 받지 않음.
// 				{// 2007-10-22 by cmkwon, 같은 세력인지 체크한다.
// 					float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetCharacter->PositionVector));
// 					D3DXVECTOR3		tmUnitVec3M2C;
// 					D3DXVec3Normalize(&tmUnitVec3M2C, &(pTargetCharacter->PositionVector - i_pAttackMon->PositionVector));		// 현재 몬스터에서 클라이언트를 향하는 Target Vector를 구한다.
// 					float fPinPoint = ACOS(D3DXVec3Dot(&i_pAttackMon->TargetVector, &tmUnitVec3M2C));						// 몬스터에서 Target Vector와 위에서 구한 현재 Target Vector 사이의 각을 구한다
// 					if(fPinPoint <= i_pAttackItem->RangeAngle) {
// 						// 4. 범위각 안에 있는 유저라면 빙고.
// 						BYTE DamageKind = DAMAGEKIND_NORMAL;
// 						float fDamage = CalcDamageOfAttackNew(&DamageKind, M2C, 1.0f, i_pAttackMonSock, i_pAttackMon, &attParam, pTargetCharacterSocket, pTargetCharacter, i_pAttackItem->Range, ((i_pAttackItem->OrbitType == ORBIT_BODYSLAM) ? 0.0f : fDistance ));
// 					}
// 				}
// 				
// 				if(pTargetCharacter
// 					&& pTargetCharacterSocket->IsValidCharacter())
// 				{
// 					pTargetCharacterSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
// 				}
// 			}// end_for(int i= 0; i < nCharacters; i++)
// 		}
// 		return;
// 	}
// 	
// 	////////////////////////////////////////////////////////////////////////////////
// 	// 일반 유저 처리
// 	// 1. 폭발 범위 안에 있는 유저 목록 뽑는다.
// 	// 2. 범위각 안에 있는 유저라면 빙고.
// 	int nCharacters = pMapChannel->GetAdjacentCharacterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 									i_pAttackItem->ExplosionRange, &ClientIndexVector);	// 1. 폭발 범위 안에 있는 유저 목록 뽑는다.
// 	if (nCharacters <= 0) {
// 		return;
// 	}
// 
// 	for(int i= 0; i < nCharacters; i++)
// 	{
// 		///////////////////////////////////////////////////////////////////////////////
// 		// 초기화
// 		pSFCAttackOK->TargetInfo.TargetIndex			= 0;
// 		pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 		
// 		CFieldIOCPSocket	*pTargetCharacterSocket = NULL;
// 		CHARACTER			*pTargetCharacter = NULL;
// 		ClientIndex_t		tmpClientIndex = ClientIndexVector[i];
// 		
// 		if (FALSE == i_pAttackMonSock->CheckValidAttackTargetCharacter(pMapChannel, tmpClientIndex, pTargetCharacterSocket, pTargetCharacter))
// 		{
// 			continue;
// 		}
// 		
// 		if(FALSE == IS_SAME_CHARACTER_MONSTER_INFLUENCE(pTargetCharacter->InfluenceType, pMonInfo->Belligerence)
// 			&& BELL_INFINITY_DEFENSE_MONSTER != pMonInfo->Belligerence)		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - BELL_INFINITY_DEFENSE_MONSTER 몬스터에게 공격 받지 않음.
// 		{// 2007-10-22 by cmkwon, 같은 세력인지 체크한다.
// 			float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetCharacter->PositionVector));
// 			D3DXVECTOR3		tmUnitVec3M2C;
// 			D3DXVec3Normalize(&tmUnitVec3M2C, &(pTargetCharacter->PositionVector - i_pAttackMon->PositionVector));		// 현재 몬스터에서 클라이언트를 향하는 Target Vector를 구한다.
// 			float fPinPoint = ACOS(D3DXVec3Dot(&i_pAttackMon->TargetVector, &tmUnitVec3M2C));						// 몬스터에서 Target Vector와 위에서 구한 현재 Target Vector 사이의 각을 구한다
// 			if(fPinPoint <= i_pAttackItem->RangeAngle) {
// 				// 2. 범위각 안에 있는 유저라면 빙고.
// 				BYTE DamageKind = DAMAGEKIND_NORMAL;
// 				float fDamage = CalcDamageOfAttackNew(&DamageKind, M2C, 1.0f, i_pAttackMonSock, i_pAttackMon, &attParam, pTargetCharacterSocket, pTargetCharacter, i_pAttackItem->Range, ((i_pAttackItem->OrbitType == ORBIT_BODYSLAM) ? 0.0f : fDistance ));
// 			}
// 		}
// 		
// 		if(pTargetCharacter
// 			&& pTargetCharacterSocket->IsValidCharacter())
// 		{
// 			pTargetCharacterSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
// 		}
// 	}// end_for(int i= 0; i < nCharacters; i++)
// 
// 
// }

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GetDelegateClientIdxByMonsterAttackSecM2M(CFieldMonster * i_pAttackMonster, ClientIndex_t * o_pDelegateClientIdx)
/// \brief		인피니티 - 몬스터 간 2형 공격 판단 해줄 클라이언트 위임자 찾기 - ping좋은 클라이언트? 아님 거리로? 둘 중 하나로 수정해야됨
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetDelegateClientIdxByMonsterAttackSecM2M(CFieldMonster * i_pAttackMonster, ClientIndex_t * o_pDelegateClientIdx) {
	vectClientIndex_t	tmClientIndexList;
	if(FALSE == i_pAttackMonster->GetCurrentMapChannelMonster()->GetAdjacentCharacterIndexes(&i_pAttackMonster->PositionVector,i_pAttackMonster->m_pCurrentFieldMapChannelMonster->GetMonsterVisibleDiameterW(), &tmClientIndexList)) {
		// 위임자 없다. 2형 처리하지 않는다.
		return FALSE;
	}
	vectClientIndex_t::iterator itrDelegateClientIdx = tmClientIndexList.begin();
	for(; itrDelegateClientIdx != tmClientIndexList.end(); itrDelegateClientIdx++) {
		CFieldIOCPSocket * DelegateClient = this->ms_pFieldIOCP->GetFieldIOCPSocket(*itrDelegateClientIdx);
		if(NULL != DelegateClient
			&& DelegateClient->IsValidCharacter(FALSE)) {
			*o_pDelegateClientIdx	= *itrDelegateClientIdx;
			return TRUE;
		}
	}	

	return FALSE;
}

// start 2011-04-18 by hskim, 인피니티 3차 - 주포 공격 방식 변경
BOOL CFieldIOCPSocket::GetDelegateClientIdx(CFieldMonster * i_pAttackMonster, ClientIndex_t * o_pDelegateClientIdx) 
{
	vectClientIndex_t	tmClientIndexList;

	i_pAttackMonster->GetCurrentMapChannelMonster()->m_mtClientIndexList.lock();
	tmClientIndexList.insert(tmClientIndexList.begin(), i_pAttackMonster->GetCurrentMapChannelMonster()->m_mtClientIndexList.begin(), i_pAttackMonster->GetCurrentMapChannelMonster()->m_mtClientIndexList.end());
	i_pAttackMonster->GetCurrentMapChannelMonster()->m_mtClientIndexList.unlock();
	
	if( true == tmClientIndexList.empty() ) return FALSE;				// 위임자 한명도 없다. 이 2형은 처리하지 않는다.

	vectClientIndex_t::iterator itrDelegateClientIdx = tmClientIndexList.begin();
	for(; itrDelegateClientIdx != tmClientIndexList.end(); itrDelegateClientIdx++) {
		CFieldIOCPSocket * DelegateClient = this->ms_pFieldIOCP->GetFieldIOCPSocket(*itrDelegateClientIdx);
		if(NULL != DelegateClient
			&& DelegateClient->IsValidCharacter(FALSE)) {
			*o_pDelegateClientIdx	= *itrDelegateClientIdx;
			return TRUE;
		}
	}	

	return FALSE;
}
// end 2011-04-18 by hskim, 인피니티 3차 - 주포 공격 방식 변경

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_TENDER_PUT_IN_TENDER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - Tender
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_TENDER_PUT_IN_TENDER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_TENDER_PUT_IN_TENDER
		, MSG_FC_INFINITY_TENDER_PUT_IN_TENDER, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	if(INFINITY_STATE_PLAYING > m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_TENDER_PUT_IN_TENDER, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	DiceCnt_t retDice = 0;		// 0이면 포기
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.ChoiceTenderItemW(&retDice, pRMsg, this->m_character.ClientIndex);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_INFINITY_TENDER_PUT_IN_TENDER, errCode, pRMsg->GiveUp, pRMsg->ItemFieldIndex);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_TENDER_PUT_IN_TENDER# %s Err(0x%X:%s) GiveUp(%d) ItemFieldIdx(%d) \r\n"
			, pRMsg->InfinityCreateUID, GetCharacterString(GetCharacter(), string()), errCode, GetErrorString(errCode), pRMsg->GiveUp, pRMsg->ItemFieldIndex);
		return RES_BREAK;
	}	
	// 2010-06-25 by shcho, 인피니티 관련로그 찍기 - 습득 아이템 정보 DB저장
	else if(0==retDice) //포기시에만 로그를 남김
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Infinity][%I64d] CFieldIOCPSocket::Process_FC_INFINITY_TENDER_PUT_IN_TENDER# | GIVE UP TENDER!! | CharacterInfo:[ %s ] GiveUp(%d) DropItemNum(%d) \r\n"
			, pRMsg->InfinityCreateUID, GetCharacterString(GetCharacter(), string()), pRMsg->GiveUp,  pRMsg->TenderDropItemNum);
	}
	// End 2010-06-25 by shcho, 인피니티 관련로그 찍기 - 습득 아이템 정보 DB저장

	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_TENDER_PUT_IN_TENDER_OK, T_FC_INFINITY_TENDER_PUT_IN_TENDER_OK, pTenderPutInSMsg, TenderPutInBuf);
	pTenderPutInSMsg->ItemFieldIndex		= pRMsg->ItemFieldIndex;
	pTenderPutInSMsg->DiceUserIdx			= this->GetCharacter()->ClientIndex;
	pTenderPutInSMsg->DiceCount				= retDice;
	m_pCurrentFieldMapChannel->SendMessageToAllInChannel(TenderPutInBuf, MSG_SIZE(MSG_FC_INFINITY_TENDER_PUT_IN_TENDER_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsApplyItemIgnoreDefence()
/// \brief		인피니티 - 방어력 무시 아이템 사용 체크	
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsApplyItemIgnoreDefence() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreDefence;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsApplyItemIgnoreAvoid()
/// \brief		인피니티 - 회피력 무시 아이템 사용 체크
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsApplyItemIgnoreAvoid() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pfb_BitFlag.pfb_ITEM_IgnoreAvoid;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ParamValue_t CFieldIOCPSocket::GetParamResistance()
/// \brief		인피니티 - 저항 아이템 사용 체크 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ParamValue_t CFieldIOCPSocket::GetParamResistance() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_ITEM_Resistance;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ParamValue_t CFieldIOCPSocket::GetParamOnceResistance()
/// \brief		인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ParamValue_t CFieldIOCPSocket::GetParamOnceResistance() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_ITEM_OnceResistance;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ParamValue_t CFieldIOCPSocket::GetParamAddAttack()
/// \brief		인피니티 - 절대값 타격치 아이템 사용 체크 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ParamValue_t CFieldIOCPSocket::GetParamAddAttack() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_ITEM_AddAttack;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ParamValue_t CFieldIOCPSocket::GetParamAddAttackSec()
/// \brief		인피니티 -  절대값 타격치 아이템 고급무기용(기무와 분류)
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-01-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ParamValue_t CFieldIOCPSocket::GetParamAddAttackSec() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_ITEM_AddAttack_Sec;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ParamValue_t CFieldIOCPSocket::GetParamReduceDamage()
/// \brief		인피니티 - 데미지 절대값 감소 아이템 사용 체크
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ParamValue_t CFieldIOCPSocket::GetParamReduceDamage() {
	CParamFactor *pParamFactor = this->GetParamFactor();
	return pParamFactor->pf_ITEM_ReduceDamage;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::AddAttackDamage(CFieldIOCPSocket *i_pAttackSocket, void* i_pAttackUnit, void *i_pTargetUnit, ParamValue_t i_AddAttackDamage, SATTACK_PARAMETER *i_pAttParam)
/// \brief		// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류) ParamValue_t i_AddAttackDamage추가 , 인피니티 - 절대값 추가 타격치 아이템 적용
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::AddAttackDamage(CFieldIOCPSocket *i_pAttackSocket, void* i_pAttackUnit, void *i_pTargetUnit, ParamValue_t i_AddAttackDamage, SATTACK_PARAMETER *i_pAttParam) {
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 추가 타격치 아이템
	CHARACTER		*pAttackCharacter = NULL;
	CFieldMonster	*pTargetMonster = NULL;
	pAttackCharacter	= (CHARACTER*)i_pAttackUnit;
	pTargetMonster		= (CFieldMonster*)i_pTargetUnit;
	if(NULL == i_pAttackSocket
		|| NULL == pAttackCharacter
		|| NULL == pTargetMonster
		|| NULL == i_pAttParam) {
		return;
	}

	BYTE tmDamageKind = DAMAGEKIND_ADD_DAMAGE;		// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	if( NULL != pTargetMonster && TRUE == pTargetMonster->IsTriggerFunction() )
	{
		// 이 몬스터는 트리거 시스템과 연결되어 있다.
		mt_auto_lock mtAuto(&pTargetMonster->m_mtVectTriggerFunctionPtr);

		for(int i=0; i<pTargetMonster->m_mtVectTriggerFunctionPtr.size(); i++)
		{
			CTriggerFunction *pTriggerFunction = pTargetMonster->m_mtVectTriggerFunctionPtr[i];
			if( TRUE == pTriggerFunction->OnIsInvincible(pTargetMonster->MonsterInfoPtr->MonsterUnitKind, i_pAttackSocket) )
			{
				return ;
			}
			// 2013-01-23 by jhseol, 전쟁 시 크리스탈만 공격 불가능 하도록 수정
			if ( TRUE == pTriggerFunction->OnIsCrystal() 
				&& FALSE == ms_pFieldIOCP->IsBurningMap( pTriggerFunction->GetMapIndex() ) )	// 2014-04-10 by bckim, 버닝맵은 제외(전쟁시 크리스탈 공격 불가능)
			{
				// 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장 : 50번 공격할때마다 메세지 출력
				if ( ms_pFieldIOCP->m_InflWarManager.IsDoingInfluenceWar() )
				{
					i_pAttackSocket->m_nCrystalAttackCount++;
					if( 1 == i_pAttackSocket->m_nCrystalAttackCount )
					{
						i_pAttackSocket->SendString128(STRING_128_USER_NOTICE, STRMSG_121126_0001);
					}
					if( 50 <= i_pAttackSocket->m_nCrystalAttackCount )
					{
						i_pAttackSocket->m_nCrystalAttackCount = 0;
					}
					return;
				}
				else
				{
					i_pAttackSocket->m_nCrystalAttackCount = 0;
				}
				// end 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장 : 50번 공격할때마다 메세지 출력
			}
			// end 2013-01-23 by jhseol, 전쟁 시 크리스탈만 공격 불가능 하도록 수정
			// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
			else if ( FALSE == pTriggerFunction->OnIsPossibleBossAttack(pTargetMonster->MonsterInfoPtr->MonsterUnitKind) )
			{// 보스 몬스터가 공략 가능한 상태인지 체크
				i_AddAttackDamage = 0.0f;				// 대미지 강제 초기화
				tmDamageKind = DAMAGEKIND_NO_DAMAGE;	// 미스 판정
			}
			// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
		}
	}
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
	// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류), 밑과 같이 수정
//	pMsgShowDamage->AmountDamage	= i_pAttackSocket->GetParamAddAttack();
	pMsgShowDamage->AmountDamage	= i_AddAttackDamage;
	pMsgShowDamage->DamageKind		= tmDamageKind;			// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
	pMsgShowDamage->byIsPrimaryWeapon	= IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind);	// 2008-12-03 by cmkwon, 데미지 정보에 1형,2형 정보 추가 - 
	pMsgShowDamage->TargetIndex		= pTargetMonster->MonsterIndex;
	pMsgShowDamage->MultiTargetIndex	= i_pAttParam->MultiTargetIndex;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	i_pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

	i_pAttackSocket->InsertAttackTargetIndexVector(pTargetMonster->MonsterIndex);
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-21 by cmkwon, Aggro 추가
	vectActionInfo tmAggroList;
	i_pAttackSocket->GetAggroList(&tmAggroList);

	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리 - 밑과 같이 수정
	// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류), 밑과 같이 수정
//	float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter((float)i_pAttackSocket->GetParamAddAttack(), i_pAttackSocket, &tmAggroList);
//	float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter(i_AddAttackDamage, i_pAttackSocket, &tmAggroList);
	// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
	if( DAMAGEKIND_NO_DAMAGE != tmDamageKind )
	{
		pTargetMonster->ProcessingDamagedMonsterByCharacter(i_AddAttackDamage, i_pAttackSocket, &tmAggroList);	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리
	}
	// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
	float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHP(i_AddAttackDamage);
	i_pAttackSocket->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pTargetMonster, T_FN_MONSTER_CHANGE_HP);
	if (fMonCurHP <= 0.0f)
	{// 몬스터가 폭파된 경우
		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
		if(g_pFieldGlobal->IsArenaServer()
			&& INFINITY_STATE_PLAYING <= i_pAttackSocket->m_InfinityPlayingInfo.InfinityState
			&& FALSE == pTargetMonster->GetMonsterDeadFlag()) {
			// 인피 로그용
			i_pAttackSocket->m_InfinityPlayingInfo.KillCount++;
		}
		OnMonsterDead(i_pAttackSocket, pAttackCharacter, NULL, (CFieldMonster*)pTargetMonster, i_pAttParam->pWeaponItemInfo);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GetInfinityShopInfo(InfinityShopUID_t i_InfinityShopUID, INFINITY_SHOP_INFO * o_pInfinityShopItem)
/// \brief		인피니티 - 인피 상점
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GetInfinityShopInfo(InfinityShopUID_t i_InfinityShopUID, INFINITY_SHOP_INFO * o_pInfinityShopItem) {
	vectorInfinityShopInfo::iterator itrInfinityShopInfo = this->ms_pFieldIOCP->m_InfinityShopInfoList.begin();
	for(; itrInfinityShopInfo != this->ms_pFieldIOCP->m_InfinityShopInfoList.end(); itrInfinityShopInfo++) {
		if(i_InfinityShopUID == itrInfinityShopInfo->InfinityShopUID) {
			*o_pInfinityShopItem	= *itrInfinityShopInfo;
			return TRUE;
		}	
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CheckBuyShopItemInsertNoLock(ItemNum_t i_ItemNum, UID64_t i_Amount)
/// \brief		인피니티 - 인피 상점, 상점에서 아이템 구매 시 구매 될 아이템 체크 사항
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	대부분 CheckBuyShopItemDeleteNoLock()함수와 짝을 이루므로 함수 호출 전에 Lock을 잡는다.
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CheckBuyShopItemInsertNoLock(ItemNum_t i_ItemNum, UID64_t i_Amount) {
	if(i_Amount <= 0) {
		char szSystemLog[512];
		sprintf(szSystemLog, "[ERROR] Shop Buy Item Error, Char(%15s) ItemNum(%8d) ItemAmount(%8d)\r\n"
			, m_character.CharacterName, i_ItemNum, i_Amount);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);
		
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0070);
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, i_Amount);
		return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
	}
	
	ITEM *pBuyItemInfo = ms_pFieldIOCP->GetItemInfo(i_ItemNum);
	if (pBuyItemInfo == NULL) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, i_ItemNum);
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}
	
	if(IS_COUNTABLE_ITEM(pBuyItemInfo->Kind)) {
		// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인
		ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyItemInfo->ItemNum);
		if (NULL == pItemGeneralInven
			&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount()) {
			SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
		}
	}
	else if(IS_GENERAL_ITEM(pBuyItemInfo->Kind)) {
		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 아래와 같이 체크 수정
		i_Amount = min(i_Amount, MAX_ITEM_COUNTS_FOR_BUY);		// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 최대 구입 가능 개수 설정.
		if(m_ItemManager.GetInventoryItemCounts() + i_Amount > m_ItemManager.GetMaxInventoryCount()) {
			// 2008-07-16 by cmkwon, ITEM_GENERAL 관련 버그 체크 - 구입 할 개수 까지 포함해서 체크 한다.
			SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
		}
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2005-09-13 by cmkwon, 카운터블 아이템일 경우 최대(20억) 카운트 체크
	if(IS_COUNTABLE_ITEM(pBuyItemInfo->Kind)) {
		INT64 tmCurrentCount = i_Amount;
		
		ITEM_GENERAL *pMyItem = m_ItemManager.GetFirstItemGeneralByItemNum(pBuyItemInfo->ItemNum);
		if(pMyItem){				tmCurrentCount += pMyItem->CurrentCount;}
		if(tmCurrentCount > MAX_ITEM_COUNTS) {
			SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, 0, 0);
			return ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER;			
		}
		else if(tmCurrentCount >= MAX_NOTIFY_ITEM_COUNTS) {
			SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER);
			return ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER;
		}
	}	
	
	if (COMPARE_BIT_FLAG(pBuyItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM)) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return ERR_PROTOCOL_ITEM_CANNOT_TRANSFER;
	}
	
	// 최소 거래 단위 확인: MinTradeQuantity의 배수로만 구매 할 수 있음
	if (0 != i_Amount%pBuyItemInfo->MinTradeQuantity) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR, pBuyItemInfo->MinTradeQuantity);
		return ERR_PROTOCOL_MIN_TRADE_QUANTITY_ERROR;
	}	

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CheckBuyShopItemDeleteNoLock(ItemNum_t i_ItemNum, UID64_t i_Amount)
/// \brief		인피니티 - 인피 상점, 상점에서 아이템 구매 시 지불 될 아이템 체크 사항
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	대부분 CheckBuyShopItemInsertNoLock()함수와 짝을 이루므로 CheckBuyShopItemInsertNoLock()함수 호출 전에 Lock을 잡는다.
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CheckBuyShopItemDeleteNoLock(ItemNum_t i_ItemNum, UID64_t i_Amount) {
	if(i_Amount <= 0) {
		// 2009-09-09 ~ 2010-02-01 by dhjin, 인피니티 - 인피니티 상점 -값 체크
		char szSystemLog[512];
		sprintf(szSystemLog, "[ERROR] Shop Buy Item Error, Char(%15s) ItemNum(%8d) ItemAmount(%8d)\r\n"
			, m_character.CharacterName, i_ItemNum, i_Amount);
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);
		
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0070);
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, i_Amount);
		return ERR_PROTOCOL_INVENTORY_FULL_ITEM;
	}
	
	ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(i_ItemNum);
	if (NULL == pItemGeneralInven) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}
	
	if(i_Amount > pItemGeneralInven->CurrentCount) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CheckInfinityShopItem(INFINITY_SHOP_INFO * i_pInfinityShopItem, INT i_Amount)
/// \brief		인피니티 - 인피 상점, 아이템 체크 사항
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CheckInfinityShopItem(INFINITY_SHOP_INFO * i_pInfinityShopItem, INT i_Amount) {
	// Check BuyItem 
	Err_t errCode = this->CheckBuyShopItemInsertNoLock(i_pInfinityShopItem->BuyItemNum, (i_pInfinityShopItem->BuyItemCount * i_Amount));
	if(ERR_NO_ERROR != errCode) {
		return errCode;
	}
	if(0 != i_pInfinityShopItem->TradeItemNum1) {
		// Check TradeItem1
		errCode = this->CheckBuyShopItemDeleteNoLock(i_pInfinityShopItem->TradeItemNum1, (i_pInfinityShopItem->TradeItemCount1 * i_Amount));
		if(ERR_NO_ERROR != errCode) {
			return errCode;
		}
	}
	if(0 != i_pInfinityShopItem->TradeItemNum2) {
		// Check TradeItem2
		errCode = this->CheckBuyShopItemDeleteNoLock(i_pInfinityShopItem->TradeItemNum2, (i_pInfinityShopItem->TradeItemCount2 * i_Amount));	
		if(ERR_NO_ERROR != errCode) {
			return errCode;
		}
	}
	if(0 != i_pInfinityShopItem->TradeItemNum3) {
		// Check TradeItem3
		errCode = this->CheckBuyShopItemDeleteNoLock(i_pInfinityShopItem->TradeItemNum3, (i_pInfinityShopItem->TradeItemCount3 * i_Amount));
		if(ERR_NO_ERROR != errCode) {
			return errCode;
		}
	}
	if(0 != i_pInfinityShopItem->TradeItemNum4) {
		// Check TradeItem4
		errCode = this->CheckBuyShopItemDeleteNoLock(i_pInfinityShopItem->TradeItemNum4, (i_pInfinityShopItem->TradeItemCount4 * i_Amount));
		if(ERR_NO_ERROR != errCode) {
			return errCode;
		}
	}
	if(0 != i_pInfinityShopItem->TradeItemNum5) {
		// Check TradeItem5
		errCode = this->CheckBuyShopItemDeleteNoLock(i_pInfinityShopItem->TradeItemNum5, (i_pInfinityShopItem->TradeItemCount5 * i_Amount));
		if(ERR_NO_ERROR != errCode) {
			return errCode;
		}
	}	

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_SHOP_INFINITY_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 상점
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_SHOP_INFINITY_BUY_ITEM(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_SHOP_INFINITY_BUY_ITEM
		, MSG_FC_SHOP_INFINITY_BUY_ITEM, pRMsg);
	
	if(FALSE == IsValidCharacter()) {
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem()) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_SHOP_BUY_ITEM 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock()) {
		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_SECPASS_LOCKED);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 체크 사항들
	INFINITY_SHOP_INFO BuyInfinityItemInfo;
	if(FALSE == this->GetInfinityShopInfo(pRMsg->InfinityShopUID, &BuyInfinityItemInfo)) {
//		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	Err_t errCode = this->CheckInfinityShopItem(&BuyInfinityItemInfo, pRMsg->Amount);
	if(ERR_NO_ERROR != errCode) {
//		SendErrorMessage(T_FC_SHOP_INFINITY_BUY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}
	// 체크 사항들 완료
	///////////////////////////////////////////////////////////////////////////////
	
	///////////////////////////////////////////////////////////////////////////////
	// 구매 처리!
	m_ItemManager.InsertItemBaseByItemNum(BuyInfinityItemInfo.BuyItemNum, (BuyInfinityItemInfo.BuyItemCount * pRMsg->Amount), IUT_SHOP, FALSE, ITEM_IN_CHARACTER, TRUE, TRUE, 0, 0, 0, 0, GLOG_INFINITYOBSHOP);  // 2012-11-21 by khkim, GLog 2차 
	if(0 != BuyInfinityItemInfo.TradeItemNum1) {
		m_ItemManager.UpdateItemCountByPointer(m_ItemManager.GetFirstItemGeneralByItemNum(BuyInfinityItemInfo.TradeItemNum1), -(BuyInfinityItemInfo.TradeItemCount1 * pRMsg->Amount), IUT_SHOP);
	}
	if(0 != BuyInfinityItemInfo.TradeItemNum2) {
		m_ItemManager.UpdateItemCountByPointer(m_ItemManager.GetFirstItemGeneralByItemNum(BuyInfinityItemInfo.TradeItemNum2), -(BuyInfinityItemInfo.TradeItemCount2 * pRMsg->Amount), IUT_SHOP);
	}
	if(0 != BuyInfinityItemInfo.TradeItemNum3) {
		m_ItemManager.UpdateItemCountByPointer(m_ItemManager.GetFirstItemGeneralByItemNum(BuyInfinityItemInfo.TradeItemNum3), -(BuyInfinityItemInfo.TradeItemCount3 * pRMsg->Amount), IUT_SHOP);
	}
	if(0 != BuyInfinityItemInfo.TradeItemNum4) {
		m_ItemManager.UpdateItemCountByPointer(m_ItemManager.GetFirstItemGeneralByItemNum(BuyInfinityItemInfo.TradeItemNum4), -(BuyInfinityItemInfo.TradeItemCount4 * pRMsg->Amount), IUT_SHOP);
	}
	if(0 != BuyInfinityItemInfo.TradeItemNum5) {
		m_ItemManager.UpdateItemCountByPointer(m_ItemManager.GetFirstItemGeneralByItemNum(BuyInfinityItemInfo.TradeItemNum5), -(BuyInfinityItemInfo.TradeItemCount5 * pRMsg->Amount), IUT_SHOP);
	}

	// start 2012-01-16 by hskim, 통계 - 화패
	if( NULL != this->ms_pFieldIOCP->m_pStatisticsManager )
	{
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(BuyInfinityItemInfo.TradeItemNum1, (BuyInfinityItemInfo.TradeItemCount1 * pRMsg->Amount));
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(BuyInfinityItemInfo.TradeItemNum2, (BuyInfinityItemInfo.TradeItemCount2 * pRMsg->Amount));
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(BuyInfinityItemInfo.TradeItemNum3, (BuyInfinityItemInfo.TradeItemCount3 * pRMsg->Amount));
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(BuyInfinityItemInfo.TradeItemNum4, (BuyInfinityItemInfo.TradeItemCount4 * pRMsg->Amount));
		this->ms_pFieldIOCP->m_pStatisticsManager->Sub(BuyInfinityItemInfo.TradeItemNum5, (BuyInfinityItemInfo.TradeItemCount5 * pRMsg->Amount));
	}
	// end 2012-01-16 by hskim, 통계 - 화패

	// send log... 따로 만들까...
	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(BuyInfinityItemInfo.BuyItemNum);
	ITEM_GENERAL tmpItemForLog(pItemInfo);
	tmpItemForLog.UniqueNumber			= 0;
	tmpItemForLog.AccountUniqueNumber	= m_character.AccountUniqueNumber;
	tmpItemForLog.Possess				= m_character.CharacterUniqueNumber;
	tmpItemForLog.Wear					= WEAR_NOT_ATTACHED;
	tmpItemForLog.CurrentCount			= (BuyInfinityItemInfo.BuyItemCount * pRMsg->Amount);
	tmpItemForLog.ItemWindowIndex		= POS_INVALID_POSITION;
	tmpItemForLog.PrefixCodeNum			= 0;
	tmpItemForLog.SuffixCodeNum			= 0;
	tmpItemForLog.NumOfEnchants			= 0;
	CAtumLogSender::SendLogMessageITEMBuyITEM(this, &tmpItemForLog, (BuyInfinityItemInfo.BuyItemCount * pRMsg->Amount), 0);

	// 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가
	//enum ITEM_BUY_CASH_PRICE_TYPE{BUY_TYPE_SPI=1,BUY_TYPE_WARPOINT,BUY_TYPE_CASH,BUY_TYPE_INFINITY};
	CAtumLogSender::SendLogMessageITEMBuyCashPrice(this, &tmpItemForLog,(BuyInfinityItemInfo.BuyItemCount * pRMsg->Amount), 0, FALSE, BUY_TYPE_INFINITY, &BuyInfinityItemInfo); // INFINITY TYPE : 4
	// end 2012-10-16 by bckim, 캐쉬아이템 지불정보 Log 추가

	igLock.auto_unlock_cancel();	

	return RES_RETURN_TRUE;
}

ItemNum_t CFieldIOCPSocket::GetCurrentAttackItemNum() {
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 게임로그 추가
	return m_CurrentAttackItemNum;
}	


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN_CANCEL(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 인피 입장 취소
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_JOIN_CANCEL(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFINITY_JOIN_CANCEL
		, MSG_FC_INFINITY_JOIN_CANCEL, pRMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}
	
	if(ARENA_STATE_NONE != this->m_ArenaInfo.State) {
		SendErrorMessage(T_FC_INFINITY_JOIN_CANCEL, ERR_ARENA_STATE);
		return RES_BREAK;
	}
	if(INFINITY_STATE_NONE != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_JOIN_CANCEL, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}
	
	ClientIndex_t			MasterUserClientIdx;
	vectCFieldIOCPSocket 	InfinityMemberList;
	InfinityMemberList.clear();
	this->ms_pFieldIOCP->m_InfinityManager.GetPlayerListW(pRMsg->InfinityMode, pRMsg->InfinityCreateUID, &InfinityMemberList, &MasterUserClientIdx);
	CFieldIOCPSocket * MasterUserFISoc = this->ms_pFieldIOCP->GetFieldIOCPSocket(MasterUserClientIdx);
	if(NULL != MasterUserFISoc
		&& MasterUserFISoc->IsValidCharacter(FALSE)) {
		INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_JOIN_CANCEL_REQUEST_MASTERUSER, T_FC_INFINITY_JOIN_CANCEL_REQUEST_MASTERUSER, pMsg, Sendbuf);
		pMsg->JoinCancelClientIdx		= this->m_character.ClientIndex;
		MasterUserFISoc->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_INFINITY_JOIN_CANCEL_REQUEST_MASTERUSER));
	}
	
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - 
/// \author		cmkwon
/// \date		2010-01-18 ~ 2010-01-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM *CFieldIOCPSocket::CheckItemParamOverlap(ITEM *i_pToUseItemInfo, INT i_nExcludeItemNum/*=0*/)
{
	// 2010-01-18 by cmkwon, 사용 중 시간제한 아이템 체크
	ITEM *pUsingItemInfo = m_ItemManager.CheckItemParamOverlapOfUsingItem(i_pToUseItemInfo, i_nExcludeItemNum);
	if(pUsingItemInfo)
	{
		return pUsingItemInfo;
	}

	// 2010-01-18 by cmkwon, 장착 아이템 체크
	return this->CheckItemParamOverlapOfAttachedItems(i_pToUseItemInfo, i_nExcludeItemNum);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - 
/// \author		cmkwon
/// \date		2010-01-18 ~ 2010-01-18
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM *CFieldIOCPSocket::CheckItemParamOverlapOfAttachedItems(ITEM *i_pToUseItemInfo, INT i_nExcludeItemNum)
{
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral 

	for(int i=0; i < SIZE_MAX_POS; i++)
	{
		ITEM_GENERAL *pAttchedItemG = GetAttachItemGeneralByPosition(i);
		if(NULL == pAttchedItemG
			|| i_nExcludeItemNum == pAttchedItemG->ItemInfo->ItemNum)
		{
			continue;
		}

		if(FALSE == i_pToUseItemInfo->CheckParamOverlap(pAttchedItemG->ItemInfo))
		{
			return pAttchedItemG->ItemInfo;
		}
	}
	
	return NULL;
}   

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_RESTART_BY_DISCONNECT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 팅긴 유저 재접속 처리, C->AFS
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_RESTART_BY_DISCONNECT(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	// 팅긴 유저가 플레이했던 인피 방이 존재하는지 체크한다
	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.DisConnectUserReStart(this->m_character.CharacterName, &this->m_InfinityPlayingInfo);
	if(ERR_NO_ERROR != errCode)
	{
		this->ms_pFieldIOCP->m_InfinityManager.DeleteDisConnectUserInfo(this->m_character.CharacterName);
		SendErrorMessage(T_FC_INFINITY_RESTART_BY_DISCONNECT, errCode);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity] 'T_FC_INFINITY_RESTART_BY_DISCONNECT' %s Error = %s \r\n", GetCharacterString(GetCharacter(), string()), GetErrorString(errCode));
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_START, T_FtoA_INFINITY_START, pSMsg, SendBuf);
	pSMsg->AccountUID		= this->m_character.AccountUniqueNumber;
	pSMsg->MFSCharacterUID	= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pSMsg->MFSClientIndex	= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pSMsg->AFSCharacterUID	= this->m_character.CharacterUniqueNumber;
	pSMsg->AFSClientIndex	= this->m_character.ClientIndex;	
	if(FALSE == this->InfinitySendAddDataFromAFS2MFS(SendBuf, MSG_SIZE(MSG_FtoA_INFINITY_START)))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR][Infinity][DisConnectUser] MFS NULL, %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_BREAK;
	}
	this->m_InfinityPlayingInfo.InfinityState = INFINITY_STATE_ENTERING;		// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 시작 버튼 누른 상태 추가
	this->m_SkillManager.ResetDebuffSkill();	// 2013-03-27 by jhseol, 인피시작시 디버프 및 도트 정보 리셋
	this->m_SkillManager.ResetDotSkill();	// 2013-03-27 by jhseol, 인피시작시 디버프 및 도트 정보 리셋
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - 팅긴 유저 재접속 처리
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT(const char* pPacket, int nLength, int &nBytesUsed) {
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}
	
	if(FALSE == IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	// 2009-09-09 ~ 2010-01-29 by dhjin, 인피니티 - 인피니티 시작 버튼 누른 상태 추가
//	if(INFINITY_STATE_READY != this->m_InfinityPlayingInfo.InfinityState) {
	if(INFINITY_STATE_ENTERING != this->m_InfinityPlayingInfo.InfinityState) {
		SendErrorMessage(T_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT, ERR_INFINITY_STATE);
		return RES_BREAK; 
	}

	this->ms_pFieldIOCP->m_InfinityManager.ReStartDisConnectUserW(this->m_InfinityPlayingInfo.InfinityCreateUID, this->m_InfinityPlayingInfo.ModeTypeNum, this);
	this->ms_pFieldIOCP->m_InfinityManager.DeleteDisConnectUserInfo(this->m_character.CharacterName);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::InfinityFinCharacterRoutine()
/// \brief		인피니티 - 팅긴 유저 재접속 처리, 인피니티에서 유저 종료 시 처리 되어야 되는 것들
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::InfinityFinCharacterRoutine() {
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GAMEEND_OK, T_FC_CHARACTER_GAMEEND_OK, pMsgGameEndOK, pMsgGameEndOKBuf);
	pMsgGameEndOK->ClientIndex = m_character.ClientIndex;
	
	vectCFieldIOCPSocket vectCFISockList;	// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
	
	// 파티원이면 파티원 리스트에서 삭제
	CFieldParty *ptmFParty = m_pFieldParty;
	if ( NULL != ptmFParty)
	{		
		mt_auto_lock pslock(&ms_pFieldIOCP->m_MapParties);
		mt_auto_lock pmlock(&ptmFParty->m_ListPartyMember);		// lock m_ListPartyMember
		
		// 파티원들에게 GAMEEND 전송
		ptmFParty->SendMsgToMembersMap(pMsgGameEndOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GAMEEND_OK), m_pCurrentFieldMapChannel, m_character.CharacterUniqueNumber);
		
		FieldPartyMember tmpMember;
		if (ptmFParty->DeleteByCharacterUniqueNumber(m_character.CharacterUniqueNumber, tmpMember))
		{
			// 성공적으로 지워진 경우
			// 2007-09-14 by cmkwon, 필요 없어서 주석 처리함
			//			assert(this == tmpMember.PM_CharacterSocket);
		}
		else
		{
			// 이러면 안 되는데...
			g_pFieldGlobal->WriteSystemLogEX(TRUE, STRMSG_S_F2NOTIFY_0132, GetCharacterString(&m_character, string()));
		}
		
		ptmFParty->GetAllMembers(&vectCFISockList);		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
		
		// 파티원이 없어지면 삭제
		if (ptmFParty->empty())
		{
			ms_pFieldIOCP->m_MapParties.deleteLock(ptmFParty->m_PartyID);
			pmlock.auto_unlock_cancel();
			ms_pFieldIOCP->DeleteFieldParty(ptmFParty);			
		}
	}
	m_pFieldParty = NULL;
	
	CFieldIOCPSocket::ArrangeAllPartyMember(&vectCFISockList);		// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
	this->CleanPartyMemberList();									// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::CharacterGameEndRoutine(), 게임 종료시 처리
	
	///////////////////////////////////////////////////////////////////////////
	// 자신의 정보를 맵 Block에서 삭제 한다.
	if (m_pCurrentFieldMapChannel != NULL)
	{
		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
		{
			char szTemp[256];
			sprintf(szTemp, "[Error] DeleteBlockPosition_3 Error, MapChannel(%s) UnitIndex(%5d) XZ(%5.0f, %5.0f) \r\n"
				, GET_MAP_STRING(m_pCurrentFieldMapChannel->m_MapChannelIndex), m_character.ClientIndex
				, m_character.PositionVector.x, m_character.PositionVector.z);
			DBGOUT(szTemp);
			g_pFieldGlobal->WriteSystemLog(szTemp);
		}
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다
	this->DeleteMeFromMonsterAttackedList();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SendMFSInfinityStateChange(eINFINITY_STATE i_byInfintiyState)
/// \brief		인피니티 - 인피 상태 값을 메인서버로 전송한다.
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SendMFSInfinityStateChange(eINFINITY_STATE i_byInfintiyState)
{
	INIT_MSG_WITH_BUFFER(MSG_FtoA_INFINITY_STATE_CHANGE, T_FtoA_INFINITY_STATE_CHANGE, pSendMsg, SendBuf);;
	pSendMsg->MFSClientIndex	= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pSendMsg->MFSCharacterUID	= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pSendMsg->AccountUID		= this->m_character.AccountUniqueNumber;
	pSendMsg->AFSClientIndex	= this->m_character.ClientIndex;
	pSendMsg->AFSInfinityState	= i_byInfintiyState;
	
	if(FALSE == this->InfinitySendAddDataFromAFS2MFS(SendBuf, MSG_SIZE(MSG_FtoA_INFINITY_STATE_CHANGE)))
	{
		SendErrorMessage(T_FC_CONNECT_ARENASERVER_LOGIN, ERR_NO_SUCH_FIELDSERVER);
		return FALSE;
	}	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::SendInfinityModeInfo()
/// \brief		인피니티 - 소스 체크, 모드 관련 정보 전송(입장 가능 여부 체크하여 전송)
///				// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::SendInfinityModeInfo()
{	
	vectorInfinityModeInfo tmInfinityModeList;
	ms_pFieldIOCP->m_InfinityManager.GetInfinityModeInfo(&tmInfinityModeList);
	
	if(0 >= tmInfinityModeList.size())
	{
		return ERR_INFINITY_NO_SUCH_MODE_LIST;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_INFINITY_MODE_LIST_OK, T_FC_INFINITY_MODE_LIST_OK, pSendMsg, SendBuf);
	int	nRecodeCnt = 0;
	INFINITY_MODE_INFO * pInfinityModeInfo = (INFINITY_MODE_INFO*)(SendBuf+MSG_SIZE(MSG_FC_INFINITY_MODE_LIST_OK));
	vectorInfinityModeInfo::iterator itr = tmInfinityModeList.begin();
	for(; itr != tmInfinityModeList.end(); itr++)
	{
		if(SIZE_MAX_PACKET < MSG_SIZE(MSG_FC_INFINITY_MODE_LIST_OK) + sizeof(INFINITY_MODE_INFO) * (nRecodeCnt+1))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::SendInfinityModeInfo# PacketSize error !! InfinityModeInfoCount(%d) curRecodeCnt(%d)\r\n"
				, tmInfinityModeList.size(), nRecodeCnt);
			break;
		}
		INFINITY_MODEINFO *pInfiModeInfo	= itr;

		pInfinityModeInfo[nRecodeCnt].InfinityMapIdx	= pInfiModeInfo->MapIdx;
		pInfinityModeInfo[nRecodeCnt].InfinityModeUID	= pInfiModeInfo->InfinityModeUID;
		pInfinityModeInfo[nRecodeCnt].InfinityMode		= pInfiModeInfo->ModeTypeNum;
		pInfinityModeInfo[nRecodeCnt].MinLv				= pInfiModeInfo->MinLv;
		pInfinityModeInfo[nRecodeCnt].MaxLv				= pInfiModeInfo->MaxLv;
		pInfinityModeInfo[nRecodeCnt].Join				= TRUE;
		pInfinityModeInfo[nRecodeCnt].TimePenaltyValue	= pInfiModeInfo->TimePenaltyValue;		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 사망시 패널티 추가
		pInfinityModeInfo[nRecodeCnt].MinMemberCount	= pInfiModeInfo->MinAdmissionCount;		// 2009-09-09 ~ 2010-01-22 by dhjin, 인피니티 - 최소,최대인원 정보 추가
		pInfinityModeInfo[nRecodeCnt].MaxMemberCount	= pInfiModeInfo->MaxAdmissionCount;		// 2009-09-09 ~ 2010-01-22 by dhjin, 인피니티 - 최소,최대인원 정보 추가
		pInfinityModeInfo[nRecodeCnt].HPPenaltyValue	= pInfiModeInfo->HPPenaltyValue;		// 2011-06-14 by hskim, 인피니티 3차 - 패널티 기능 추가 (HP 및 시간 동시 지원을 위해)

		if(FALSE == IS_IN_RANGE(pInfiModeInfo->MinLv, m_character.Level, pInfiModeInfo->MaxLv))
		{// 레벨 체크
			pInfinityModeInfo[nRecodeCnt].Join = FALSE;
		}
		nRecodeCnt++;
	}
	pSendMsg->InfinityModeListCount	= nRecodeCnt;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFINITY_MODE_LIST_OK) + nRecodeCnt * sizeof(INFINITY_MODE_INFO));
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::ApplyInvokingItem(ITEM_GENERAL * i_pItemG) 
/// \brief		인피니티 - 발동류장착아이템 적용
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::ApplyInvokingItem(ITEM_GENERAL * i_pItemG) {
	if(NULL == i_pItemG) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	if (NULL == i_pItemG->ItemInfo->pInvokingDestParamList
		&& NULL ==  i_pItemG->ItemInfo->pInvokingDestParamByUseList) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	if( 0 < i_pItemG->CoolingTimeStamp) {
		// 쿨타임 설정
		this->m_ItemManager.AddInvokingItemList(i_pItemG->UniqueNumber);
	}

	this->m_InvokingItemManager.ApplyInvokingItemDestParamByEquip(i_pItemG);

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::EnchantApplyInvokingItem(ITEM_GENERAL * i_pTargetItemG, ITEM * i_pEnchantItem); 
/// \brief		인피니티 - 발동류장착아이템 인첸트 적용
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::EnchantApplyInvokingItem(ITEM_GENERAL * i_pTargetItemG, ITEM * i_pEnchantItem) {
	if(NULL == i_pTargetItemG
		|| NULL == i_pEnchantItem) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}
		
	if (NULL == i_pEnchantItem->pInvokingDestParamList) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}
	
	this->m_InvokingItemManager.ApplyEnchantInvokingItemDestParamByEquip(i_pTargetItemG->UniqueNumber, i_pEnchantItem);	
	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendApplyDestParamInfo(ClientIndex_t i_ApplyClientIdx, INVOKING_ITEM_DESTPARAM_TYPE * i_pApplyDestParamInfo)
/// \brief		인피니티 - 발동류장착아이템, 발동 관련 데스파람 적용 정보 전송
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendApplyDestParamInfo(ClientIndex_t i_ApplyClientIdx, INVOKING_ITEM_DESTPARAM_TYPE * i_pApplyDestParamInfo) {
	if(NULL == i_pApplyDestParamInfo) {
		return;
	}
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_DESTPARAM, T_FC_INFO_APPLY_DESTPARAM, pMsg, pBuf);
	pMsg->ApplyClientIdx	= i_ApplyClientIdx;
	pMsg->ApplyDestParam	= i_pApplyDestParamInfo->InvokingDestParam;
	pMsg->ApplyEffectIdx	= i_pApplyDestParamInfo->InvokingEffectIdx;
	pMsg->ApplyItemUID		= i_pApplyDestParamInfo->InvokingItemUID;
	this->SendInRangeMessageAroundMe(pBuf, MSG_SIZE(MSG_FC_INFO_APPLY_DESTPARAM), TRUE);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendApplyDestParamListInfo(CFieldIOCPSocket * i_pApplyFISoc, InvokingItemDestParamTypeList * i_pInvokingItemDestParamTypeList)
/// \brief		인피니티 - 발동류장착아이템, 발동 관련 데스파람 적용 정보 전송
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendApplyDestParamListInfo(CFieldIOCPSocket * i_pApplyFISoc, InvokingItemDestParamTypeList * i_pInvokingItemDestParamTypeList) {
	if(NULL == i_pApplyFISoc
		|| NULL == i_pInvokingItemDestParamTypeList) {
		return;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_APPLY_DESTPARAM_LIST, T_FC_INFO_APPLY_DESTPARAM_LIST, pMsg, pBuf);
	pMsg->ApplyClientIdx	= i_pApplyFISoc->m_character.ClientIndex;
	pMsg->ApplyItemUID		= i_pInvokingItemDestParamTypeList->begin()->InvokingItemUID;
	int	ApplyDestParamCount = 0;
	APPLY_DESTPARAM_INFO * pApplyDestParamInfo = (APPLY_DESTPARAM_INFO*)(pBuf+MSG_SIZE(MSG_FC_INFO_APPLY_DESTPARAM_LIST));
	InvokingItemDestParamTypeList::iterator itrDP = i_pInvokingItemDestParamTypeList->begin();
	for(; itrDP != i_pInvokingItemDestParamTypeList->end(); itrDP++) {
		if(SIZE_MAX_PACKET < MSG_SIZE(MSG_FC_INFO_APPLY_DESTPARAM_LIST) + sizeof(APPLY_DESTPARAM_INFO) * (ApplyDestParamCount+1)) {
			break;
		}
		pApplyDestParamInfo[ApplyDestParamCount].ApplyDestParam		= itrDP->InvokingDestParam;
		pApplyDestParamInfo[ApplyDestParamCount].ApplyEffectIdx		= itrDP->InvokingEffectIdx;
		ApplyDestParamCount++;
	}
	pMsg->ApplyDestParamCnt = ApplyDestParamCount;
	if(0 < ApplyDestParamCount) {
		i_pApplyFISoc->SendInRangeMessageAroundMe(pBuf, MSG_SIZE(MSG_FC_INFO_APPLY_DESTPARAM_LIST) + ApplyDestParamCount * sizeof(APPLY_DESTPARAM_INFO), TRUE);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::ApplyInvokingItemByUse(ITEM_GENERAL *i_pItemG)
/// \brief		인피니티 - 발동류장착아이템 사용
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::ApplyInvokingItemByUse(ITEM_GENERAL *i_pItemG) {
	if(NULL == i_pItemG) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	if(NULL == i_pItemG->ItemInfo->pInvokingDestParamByUseList) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	// 적용 데스파람 목록 생성
	this->m_InvokingItemManager.ApplyInvokingItemDestParamByUse(i_pItemG);
	
	// lock
	m_mapEnchant.lock();
	mtmapUID2EnchantVector::iterator itrEnchantList	= m_mapEnchant.find(i_pItemG->UniqueNumber);
	if (m_mapEnchant.end() != itrEnchantList) {
		vectENCHANT &vecECH = itrEnchantList->second;
		
		for (int i = 0; i < vecECH.size(); i++) {
			ENCHANT &tmpEnchant = vecECH[i];
			ITEM *pEnchantItemInfo = ms_pFieldIOCP->GetItemInfo(tmpEnchant.EnchantItemNum);
			if (pEnchantItemInfo != NULL
				&& NULL != pEnchantItemInfo->pInvokingDestParamByUseList) {
				this->m_InvokingItemManager.ApplyEnchantInvokingItemDestParamByUse(i_pItemG->UniqueNumber, pEnchantItemInfo);
			}
		}
	}
	m_mapEnchant.unlock();
	
	InvokingItemDestParamTypeList	CopyInvokingItemDestParamTypeList;
	this->m_InvokingItemManager.GetParamListByUse(i_pItemG->UniqueNumber, &CopyInvokingItemDestParamTypeList);
	if(0 >= CopyInvokingItemDestParamTypeList.size()) {
		return ERR_PROTOCOL_NO_SUCH_ITEM;
	}

	// 발동 적용.
	InvokingItemDestParamTypeList::iterator itrDP = CopyInvokingItemDestParamTypeList.begin();
	for(; itrDP != CopyInvokingItemDestParamTypeList.end(); itrDP++) {
		SetParamFactor(itrDP->InvokingDestParam, itrDP->InvokingDestParamValue);
	}	

	// 전송	
	this->SendApplyDestParamListInfo(this, &CopyInvokingItemDestParamTypeList);

	// 쿨타임 설정
	this->m_ItemManager.AddInvokingItemList(i_pItemG->UniqueNumber);

	return ERR_NO_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GameEndAllInvokingEquipItem()
/// \brief		인피니티 - 발동류장착아이템, 게임 종료시 처리
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GameEndAllInvokingEquipItem()
{
	mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);

	for (int i = 0; i < SIZE_MAX_POS; i++)
	{
		ITEM_GENERAL *pItemG = GetAttachItemGeneralByPosition(i);
		if(pItemG)
		{
			this->m_ItemManager.StopInvokingItemList(pItemG);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ApplyInvokingItemDrain(float i_fRetDamage, CFieldIOCPSocket *i_pAttackFISoc, CFieldIOCPSocket *i_pTargetFISoc/*=NULL*/, CFieldMonster * i_pTargetMonster/*=NULL*/)
/// \brief		인피니티 - 발동류장착아이템, 드레인 처리
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyInvokingItemDrain(float i_fRetDamage, CFieldIOCPSocket *i_pAttackFISoc, CFieldIOCPSocket *i_pTargetFISoc/*=NULL*/, CFieldMonster * i_pTargetMonster/*=NULL*/) {
	if(NULL == i_pAttackFISoc || FALSE == i_pAttackFISoc->IsValidCharacter()) {
		return;
	}

	INVOKING_ITEM_DESTPARAM_TYPE InvokingItemRate;
	MEMSET_ZERO(&InvokingItemRate, sizeof(INVOKING_ITEM_DESTPARAM_TYPE));
	if(FALSE == i_pAttackFISoc->m_InvokingItemManager.GetPossibleInvokingItem(DES_PAIR_DRAIN_1_RATE, i_pAttackFISoc, &InvokingItemRate)) {
		return;
	}

	// 해당 발동류 아이템 처리
	INVOKING_ITEM_DESTPARAM_TYPE InvokingItem;
	if(NULL == i_pAttackFISoc->m_InvokingItemManager.GetParamTypeInfoByEquip(&InvokingItem, InvokingItemRate.InvokingItemUID, DES_PAIR_DRAIN_2_HP_DP_UP_RATE))
	{
		return;
	}

	// 쿨타임 설정
	i_pAttackFISoc->m_ItemManager.AddInvokingItemList(InvokingItem.InvokingItemUID);

	if(NULL == i_pTargetFISoc) {
		// 몬스터나 잘못된 피격 유저면 무시
		// 드레인 발동 정보 전송.
		this->SendApplyDestParamInfo(this->m_character.ClientIndex, &InvokingItem);
		i_pAttackFISoc->IncreaseCurrentHPDP(i_fRetDamage*(InvokingItem.InvokingDestParamValue));
		return;
	}

	INVOKING_ITEM_DESTPARAM_TYPE AntiInvokingItemRate;
	MEMSET_ZERO(&AntiInvokingItemRate, sizeof(INVOKING_ITEM_DESTPARAM_TYPE));
	if(FALSE == i_pTargetFISoc->m_InvokingItemManager.GetPossibleInvokingItem(DES_ANTI_DRAIN_RATE, i_pTargetFISoc, &AntiInvokingItemRate)) {
		// 사용 가능한 안티 드레인 모듈이 없다. 드레인 발동 정보 전송.
		this->SendApplyDestParamInfo(this->m_character.ClientIndex, &InvokingItem);
		i_pAttackFISoc->IncreaseCurrentHPDP(i_fRetDamage*(InvokingItem.InvokingDestParamValue));
		return;
	}

	// 쿨타임 설정
	i_pTargetFISoc->m_ItemManager.AddInvokingItemList(AntiInvokingItemRate.InvokingItemUID);

	// 안티 드레인 모듈 성공 전송
	i_pTargetFISoc->SendApplyDestParamInfo(i_pTargetFISoc->m_character.ClientIndex, &AntiInvokingItemRate);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ApplyInvokingItemReflection(float i_fRetDamage, CFieldIOCPSocket *i_pTargetFISoc, CFieldIOCPSocket *i_pAttackFISoc=NULL, CFieldMonster * i_pAttackMonster=NULL)
/// \brief		인피니티 - 발동류장착아이템, 데미지 반사 처리
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyInvokingItemReflection(float i_fRetDamage, CFieldIOCPSocket *i_pTargetFISoc, CFieldIOCPSocket *i_pAttackFISoc/*=NULL*/, CFieldMonster * i_pAttackMonster/*=NULL*/) {
	if(NULL == i_pTargetFISoc || FALSE == i_pTargetFISoc->IsValidCharacter()) {
		return;
	}

	if(NULL == i_pAttackFISoc
		&& NULL == i_pAttackMonster) {
		return;
	}

	INVOKING_ITEM_DESTPARAM_TYPE InvokingItemRate;
	MEMSET_ZERO(&InvokingItemRate, sizeof(INVOKING_ITEM_DESTPARAM_TYPE));
	if(FALSE == i_pTargetFISoc->m_InvokingItemManager.GetPossibleInvokingItem(DES_PAIR_REFLECTION_1_RATE, i_pTargetFISoc, &InvokingItemRate, FALSE)) {
		return;
	}

	// 해당 발동류 아이템 처리
	INVOKING_ITEM_DESTPARAM_TYPE InvokingItem;
	if(NULL == i_pTargetFISoc->m_InvokingItemManager.GetParamTypeInfoByUse(&InvokingItem, InvokingItemRate.InvokingItemUID, DES_PAIR_REFLECTION_2_DAMAGE_RATE))
	{
		return;
	}

	// 쿨타임 설정
	i_pTargetFISoc->m_ItemManager.AddInvokingItemList(InvokingItem.InvokingItemUID);

	i_fRetDamage = i_fRetDamage*(InvokingItem.InvokingDestParamValue);

	if(NULL != i_pAttackMonster) {

		// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
		BYTE tmDamageKind = DAMAGEKIND_REFLECTION;
		if( NULL != i_pAttackMonster && TRUE == i_pAttackMonster->IsTriggerFunction() )
		{	// 트리거와 관련이 있는 몬스터 일 경우
// 			mt_auto_lock mtAuto(&i_pAttackMonster->m_mtVectTriggerFunctionPtr);
// 			
// 			for(int i=0; i<i_pAttackMonster->m_mtVectTriggerFunctionPtr.size(); i++)
// 			{
// 				CTriggerFunction *pTriggerFunction = i_pAttackMonster->m_mtVectTriggerFunctionPtr[i];
// 				if ( FALSE == pTriggerFunction->OnIsPossibleBossAttack(i_pAttackMonster->MonsterInfoPtr->MonsterUnitKind) )
// 				{// 보스 몬스터가 공략 가능한 상태인지 체크
// 					i_fRetDamage = 0.0f;					// 대미지 강제 초기화
// 					tmDamageKind = DAMAGEKIND_NO_DAMAGE;	// 미스 판정
// 				}
// 			}
		}
		// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인

		// 공격자가 몬스터!
		// 미러링 발동 정보 전송.
		this->SendApplyDestParamInfo(i_pTargetFISoc->m_character.ClientIndex, &InvokingItem);
		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
		pMsgShowDamage->TargetIndex		= i_pAttackMonster->MonsterIndex;
		pMsgShowDamage->AmountDamage	= i_fRetDamage;
		pMsgShowDamage->DamageKind		= tmDamageKind;		// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
		pMsgShowDamage->MultiTargetIndex	= 0;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		i_pTargetFISoc->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

		vectActionInfo tmAggroList;
		i_pTargetFISoc->GetAggroList(&tmAggroList);
		
		// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리 - 밑과 같이 수정
//		float	fMonCurHP = i_pAttackMonster->DecreaseMonsterCurrentHPByCharacter(i_fRetDamage, i_pTargetFISoc, &tmAggroList);	// 2006-07-21 by cmkwon, Aggro 적용
		// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
		if( DAMAGEKIND_NO_DAMAGE != tmDamageKind )
		{
			i_pAttackMonster->ProcessingDamagedMonsterByCharacter(i_fRetDamage, i_pTargetFISoc, &tmAggroList);	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리
		}
		// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
		float	fMonCurHP = i_pAttackMonster->DecreaseMonsterCurrentHP(i_fRetDamage);
		i_pTargetFISoc->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(i_pAttackMonster, T_FN_MONSTER_CHANGE_HP);
		if (fMonCurHP <= 0.0f)
		{// 몬스터가 폭파된 경우
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(g_pFieldGlobal->IsArenaServer()
				&& INFINITY_STATE_PLAYING <= i_pTargetFISoc->m_InfinityPlayingInfo.InfinityState
				&& FALSE == i_pAttackMonster->GetMonsterDeadFlag()) {
				// 인피 로그용
				i_pTargetFISoc->m_InfinityPlayingInfo.KillCount++;
			}
			OnMonsterDead(i_pTargetFISoc, (CHARACTER*)i_pTargetFISoc, NULL, (CFieldMonster*)i_pAttackMonster, NULL);
		}
		return;
	}

	INVOKING_ITEM_DESTPARAM_TYPE AntiInvokingItemRate;
	MEMSET_ZERO(&AntiInvokingItemRate, sizeof(INVOKING_ITEM_DESTPARAM_TYPE));
	if(FALSE == i_pAttackFISoc->m_InvokingItemManager.GetPossibleInvokingItem(DES_ANTI_REFLECTION_RATE, i_pAttackFISoc, &AntiInvokingItemRate)) {
		// 안티 미러링 발동 실패로 미러링 발동
		this->SendApplyDestParamInfo(i_pTargetFISoc->m_character.ClientIndex, &InvokingItem);
		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
		pMsgShowDamage->TargetIndex		= i_pAttackFISoc->m_character.ClientIndex;
		pMsgShowDamage->AmountDamage	= i_fRetDamage;
		pMsgShowDamage->DamageKind		= DAMAGEKIND_REFLECTION;
		pMsgShowDamage->MultiTargetIndex	= 0;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		i_pAttackFISoc->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
		i_pTargetFISoc->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
		i_pAttackFISoc->DecreaseCharacterHPDP(i_fRetDamage, DAMAGE_BY_PK, TRUE, NULL, i_pTargetFISoc);
		return;
	}
	
	// 쿨타임 설정
	i_pAttackFISoc->m_ItemManager.AddInvokingItemList(AntiInvokingItemRate.InvokingItemUID);

	// 안티 미러링 모듈 성공 전송
	i_pAttackFISoc->SendApplyDestParamInfo(i_pAttackFISoc->m_character.ClientIndex, &AntiInvokingItemRate);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::IncreaseCurrentHPDP(float i_fChangeVal)
/// \brief		인피니티 - 발동류장착아이템, HP -> DP 회복
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::IncreaseCurrentHPDP(float i_fChangeVal) {
	if (0.0f >= i_fChangeVal){
		return;
	}

	float fOldCurHP = m_character.CurrentHP;
	float fOldCurDP = m_character.CurrentDP;

	if(fOldCurHP == m_character.HP
		&& fOldCurDP == m_character.DP) {
		// 만피 만DP
		return;
	}
	else if(fOldCurHP == m_character.HP
			&& fOldCurDP < m_character.DP) {
		// 만피다 DP나 채우자.
		m_character.CurrentDP = min(m_character.CurrentDP+i_fChangeVal, m_character.DP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
	}
	else if(fOldCurHP < m_character.HP
			&& fOldCurDP == m_character.DP) {
		// 만DP다 HP나 채우자.
		m_character.CurrentHP = min(m_character.CurrentHP+i_fChangeVal, m_character.HP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);		
	}
	else if(fOldCurHP < m_character.HP
			&& fOldCurDP < m_character.DP) {
		// HP, DP 채우자.
		m_character.CurrentHP = min(m_character.CurrentHP+i_fChangeVal, m_character.HP);
		m_character.CurrentDP = min(m_character.CurrentDP+(i_fChangeVal-(m_character.CurrentHP - fOldCurHP)), m_character.DP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);			
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckDestParamEnchantItemNoLock(ITEM_GENERAL * i_pEnchantItemG, ITEM_GENERAL * i_pTargetItemG)
/// \brief		인피니티 - 발동류장착아이템, 인첸트시 데스파람이 만족하는지 체크
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckDestParamEnchantItemNoLock(ITEM_GENERAL * i_pEnchantItemG, ITEM_GENERAL * i_pTargetItemG) {
	if(NULL == i_pEnchantItemG
		|| NULL == i_pTargetItemG) {
		return FALSE;
	}

	// 인첸트 아이템 목록 작성
	vector<DestParam_t>	EnchantItemDestParamList;		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
	EnchantItemDestParamList.clear();
	for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++) {
		if(0 != i_pEnchantItemG->ItemInfo->ArrDestParameter[i]) {
			EnchantItemDestParamList.push_back(i_pEnchantItemG->ItemInfo->ArrDestParameter[i]);
		}
	}
	if(0 != i_pEnchantItemG->ItemInfo->InvokingDestParamID) {
		InvokingWearItemDestParamList::iterator itrInvokingItemDP = i_pEnchantItemG->ItemInfo->pInvokingDestParamList->begin();
		for(; itrInvokingItemDP != i_pEnchantItemG->ItemInfo->pInvokingDestParamList->end(); itrInvokingItemDP++) {
			EnchantItemDestParamList.push_back(itrInvokingItemDP->InvokingDestParam);
		}	
	}
	if(0 != i_pEnchantItemG->ItemInfo->InvokingDestParamIDByUse) {
		InvokingWearItemDestParamList::iterator itrInvokingItemDPByUse = i_pEnchantItemG->ItemInfo->pInvokingDestParamByUseList->begin();
		for(; itrInvokingItemDPByUse != i_pEnchantItemG->ItemInfo->pInvokingDestParamByUseList->end(); itrInvokingItemDPByUse++) {
			EnchantItemDestParamList.push_back(itrInvokingItemDPByUse->InvokingDestParam);
		}
	}
	if(0 >= EnchantItemDestParamList.size()) {
		return FALSE;
	}
	// 인첸트 아이템 목록 작성 완료

	// 대상 아이템 목록 작성
	vector<DestParam_t>	TargetItemDestParamList;		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
	TargetItemDestParamList.clear();
	for(i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++) {
		if(0 != i_pTargetItemG->ItemInfo->ArrDestParameter[i]) {
			TargetItemDestParamList.push_back(i_pTargetItemG->ItemInfo->ArrDestParameter[i]);
		}
	}
	if(0 != i_pTargetItemG->ItemInfo->InvokingDestParamID) {
		InvokingWearItemDestParamList::iterator itrInvokingItemDP = i_pTargetItemG->ItemInfo->pInvokingDestParamList->begin();
		for(; itrInvokingItemDP != i_pTargetItemG->ItemInfo->pInvokingDestParamList->end(); itrInvokingItemDP++) {
			TargetItemDestParamList.push_back(itrInvokingItemDP->InvokingDestParam);
		}	
	}
	if(0 != i_pTargetItemG->ItemInfo->InvokingDestParamIDByUse) {
		InvokingWearItemDestParamList::iterator itrInvokingItemDPByUse = i_pTargetItemG->ItemInfo->pInvokingDestParamByUseList->begin();
		for(; itrInvokingItemDPByUse != i_pTargetItemG->ItemInfo->pInvokingDestParamByUseList->end(); itrInvokingItemDPByUse++) {
			TargetItemDestParamList.push_back(itrInvokingItemDPByUse->InvokingDestParam);
		}
	}
	if(0 >= TargetItemDestParamList.size()) {
		return FALSE;
	}
	// 대상 아이템 목록 작성 완료

	int CheckCount = EnchantItemDestParamList.size();
	vector<DestParam_t>::iterator itrEnchantItem = EnchantItemDestParamList.begin();		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
	for(; itrEnchantItem != EnchantItemDestParamList.end(); itrEnchantItem++) {
		vector<DestParam_t>::iterator itrTargetItem = TargetItemDestParamList.begin();		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
		for(; itrTargetItem != TargetItemDestParamList.end(); itrTargetItem++) {
			if(*itrTargetItem == *itrEnchantItem) {
				CheckCount--;
				break;
			}
		}
	}

	if(0 != CheckCount) {
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
/// \author		cmkwon
/// \date		2010-03-23 ~ 2010-03-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
EntranceCount_t CFieldIOCPSocket::InfinityGetEntranceCount(InfiModeUID_t i_infiModeUID)
{
	mt_auto_lock mtImpute(&m_mtVecInfiImpute);
// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
// 	mt_vectorInfinityImpute::iterator itr = m_mtVecInfiImpute.begin();
// 	for(; itr != m_mtVecInfiImpute.end(); itr++)
// 	{
// 		INFINITY_IMPUTE *pInfiImpute = itr;
// 		if(i_infiModeUID == pInfiImpute->InfinityModeUID)
// 		{
// 			return pInfiImpute->EntranceCount;
// 		}
// 	}
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 
	INFINITY_IMPUTE *pImputeInfo = InfinityGetImputeInfoNoLock(i_infiModeUID);
	if(pImputeInfo)
	{
		return pImputeInfo->EntranceCount;
	}

	return 0;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
/// \author		cmkwon
/// \date		2010-03-23 ~ 2010-03-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::Check8SendAFSUpdateItem(ITEM_GENERAL * i_pItemG)
{
	if(0 == this->m_AFSClientIndex
		|| NULL == i_pItemG)			// 2010-05-13 by cmkwon, 인피2차 재입장카드 버그 수정 - NULL 체크
	{
		return;
	}

	if(i_pItemG->ItemInfo->IsExistDesParam(DES_INFINITY_REENTRY_TICKET))
	{
		INIT_MSG_WITH_BUFFER(MSG_FtoA_UPDATE_ITEM_NOTI, T_FtoA_UPDATE_ITEM_NOTI, pSendMsg, SendBuf);
		pSendMsg->AFSClientIdx		= this->m_AFSClientIndex;
		pSendMsg->ItemNum			= i_pItemG->ItemNum;
		ms_pFieldIOCP->m_pArenaFieldWinSocket->Write(SendBuf, MSG_SIZE(MSG_FtoA_UPDATE_ITEM_NOTI));
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INVOKING_WEAR_ITEM(const char* pPacket, int nLength, int &nBytesUsed) 
/// \brief		인피니티 - 발동류장착아이템
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INVOKING_WEAR_ITEM(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_INVOKING_WEAR_ITEM,
									MSG_FC_ITEM_USE_INVOKING_WEAR_ITEM, pRMsg);
	if(FALSE == IsValidCharacter()) {
		SendErrorMessage(T_FC_ITEM_USE_INVOKING_WEAR_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->InvokingWearItemUID);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo) {
		SendErrorMessage(T_FC_ITEM_USE_INVOKING_WEAR_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->InvokingWearItemUID);
		return RES_BREAK;
	}
	
	if(WEAR_NOT_ATTACHED == pItemG->Wear) {
		// 1. 장착중인 아이템인지 체크
		SendErrorMessage(T_FC_ITEM_USE_INVOKING_WEAR_ITEM, ERR_PROTOCOL_NOT_WEARING_STATE);
		return RES_BREAK;
	}

	// 2. 쿨타임 체크
	if(TRUE == this->m_ItemManager.CheckCoolingTimeInvokingItem(pItemG->UniqueNumber)) {
		SendErrorMessage(T_FC_ITEM_USE_INVOKING_WEAR_ITEM, ERR_PROTOCOL_COOLING_TIME_INVOKING_ITEM);
		return RES_BREAK;		
	}
	
	// 3. 적용
	Err_t errCode = this->ApplyInvokingItemByUse(pItemG);
	if(ERR_NO_ERROR != errCode) {
		SendErrorMessage(T_FC_ITEM_USE_INVOKING_WEAR_ITEM, errCode);
		return RES_BREAK;
	}

	if(0 < pItemG->ItemInfo->Time) {
		// 버프 올리세요
		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_INVOKING_WEAR_ITEM_BUFF, T_FC_ITEM_USE_INVOKING_WEAR_ITEM_BUFF, pMsg, pBuf);
		pMsg->ItemUID	= pItemG->UniqueNumber;
		this->SendAddData(pBuf, MSG_SIZE(MSG_FC_ITEM_USE_INVOKING_WEAR_ITEM_BUFF));
	}
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM(const char* pPacket, int nLength, int &nBytesUsed) 
/// \brief		인피니티 - 발동류장착아이템 지속 시간 완료
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM,
		MSG_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM, pRMsg);

	if(FALSE == IsValidCharacter(FALSE)) {
		SendErrorMessage(T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->InvokingWearItemUID);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo) {
		SendErrorMessage(T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->InvokingWearItemUID);
		return RES_BREAK;
	}
	
	if(WEAR_NOT_ATTACHED == pItemG->Wear) {
		// 1. 장착중인 아이템인지 체크
		SendErrorMessage(T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM, ERR_PROTOCOL_NOT_WEARING_STATE);
		return RES_BREAK;
	}

	this->m_InvokingItemManager.ReleaseInvokingItemDestParamByUse(pItemG);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_END_COOLINGTIME_ITEM(const char* pPacket, int nLength, int &nBytesUsed) 
/// \brief		인피니티 - 발동류장착아이템, 쿨타임 종료
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_END_COOLINGTIME_ITEM(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_END_COOLINGTIME_ITEM,
		MSG_FC_ITEM_END_COOLINGTIME_ITEM, pRMsg);
	if(FALSE == IsValidCharacter(FALSE)) {
		SendErrorMessage(T_FC_ITEM_END_COOLINGTIME_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 쿨타임 체크후 정지
	if(TRUE == this->m_ItemManager.CheckCoolingTimeInvokingItem(pRMsg->ItemUID)) {
		SendErrorMessage(T_FC_ITEM_END_COOLINGTIME_ITEM, ERR_PROTOCOL_COOLING_TIME_INVOKING_ITEM);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_GET_COOLINGTIME_INFO(const char* pPacket, int nLength, int &nBytesUsed) 
/// \brief		인피니티 - 발동류장착아이템, 쿨타임 정보 요청 C->F
/// \author		dhjin
/// \date		2009-09-09 ~ 2010-02-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_GET_COOLINGTIME_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(FALSE == IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_ITEM_GET_COOLINGTIME_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	for (int i = 0; i < SIZE_MAX_POS; i++)
	{
		mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);	// 2010-03-23 by cmkwon, 추가
		ITEM_GENERAL *pItemG = GetAttachItemGeneralByPosition(i);
		if(pItemG)
		{
			this->m_ItemManager.CheckCoolingTimeInvokingItem(pItemG->UniqueNumber, TRUE);
		}
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
/// \author		cmkwon
/// \date		2010-03-23 ~ 2010-03-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_INFINITY_START_CHECK_ACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_INFINITY_START_CHECK_ACK,
		MSG_FtoA_INFINITY_START_CHECK_ACK, pRMsg);


	eINFINITY_STATE infiRoomState = INFINITY_STATE_NONE;
	BOOL bAllRecved = ms_pFieldIOCP->m_InfinityManager.CheckInfinityStartCheckAckW(&infiRoomState, pRMsg);

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::Process_FtoA_INFINITY_START_CHECK_ACK# 10000 ! AccUID(%d) AFSClientIndex(%d) ErrCode(%d) AllRecvd(%d) \r\n"
//		, pRMsg->InfinityCreateUID, pRMsg->AccountUID, pRMsg->AFSClientIndex, pRMsg->ErrorCode, bAllRecved);

	if(FALSE == bAllRecved)
	{
		return RES_BREAK;
	}

	CFieldIOCPSocket * pMasterAFISoc	= ms_pFieldIOCP->m_InfinityManager.GetMasterPlayerW(pRMsg->InfinityMode, pRMsg->InfinityCreateUID);
	if(NULL == pMasterAFISoc
		|| FALSE == pMasterAFISoc->IsValidCharacter(FALSE))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::Process_FtoA_INFINITY_START_CHECK_ACK# 20000 Master is invalid !! Character(%s) InfiRoomState(%d) \r\n"
			, pRMsg->InfinityCreateUID, (pMasterAFISoc==NULL?"NULL":GetCharacterString(pMasterAFISoc->GetCharacter(), string())), infiRoomState);
		return RES_BREAK;
	}

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] [Infinity][%I64d] CFieldIOCPSocket::Process_FtoA_INFINITY_START_CHECK_ACK# 20000 ! AccUID(%d) AFSClientIndex(%d) ErrCode(%d) %s %d \r\n"
//		, pRMsg->InfinityCreateUID, pRMsg->AccountUID, pRMsg->AFSClientIndex, pRMsg->ErrorCode, GetCharacterString(pMasterAFISoc->GetCharacter(), string()), infiRoomState);
	
	if(INFINITY_STATE_READY_ENTER_CHECK != infiRoomState)
	{
		ms_pFieldIOCP->m_InfinityManager.SetAllPlayerStateW(pRMsg->InfinityMode, pRMsg->InfinityCreateUID, INFINITY_STATE_READY);
		pMasterAFISoc->SendErrorMessage(T_FC_INFINITY_START, ERR_INFINITY_CANNOT_ALL_START, 21000, infiRoomState);
		return RES_BREAK;
	}

	Err_t errCode = this->ms_pFieldIOCP->m_InfinityManager.StartInfinity(pRMsg->InfinityMode, pRMsg->InfinityCreateUID, pMasterAFISoc);
	if(ERR_NO_ERROR != errCode)
	{
		ms_pFieldIOCP->m_InfinityManager.SetAllPlayerStateW(pRMsg->InfinityMode, pRMsg->InfinityCreateUID, INFINITY_STATE_READY);
		pMasterAFISoc->SendErrorMessage(T_FC_INFINITY_START, errCode, 30000, infiRoomState);

		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Infinity][%I64d] CFieldIOCPSocket::Process_FtoA_INFINITY_START_CHECK_ACK# 30000 StartInfinity returned error !! Master(%s) InfiRoomState(%d) errCode(%d) \r\n"
			, pRMsg->InfinityCreateUID, GetCharacterString(pMasterAFISoc->GetCharacter(), string()), infiRoomState, errCode);
		return RES_BREAK;
	}

	// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - 귀속처리
	ms_pFieldIOCP->m_InfinityManager.ImputeInfinityW(pRMsg->InfinityMode, pRMsg->InfinityCreateUID);	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
/// \author		cmkwon
/// \date		2010-03-23 ~ 2010-03-23
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FtoA_UPDATE_ITEM_NOTI(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FtoA_UPDATE_ITEM_NOTI, MSG_FtoA_UPDATE_ITEM_NOTI, pRMsg);
	if(FALSE == g_pFieldGlobal->IsArenaServer()) {
		// 2007-12-27 by dhjin, 아레나 서버가 아니면 오류
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ArenaServer is not !! %s \r\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;
	}

	CFieldIOCPSocket * FISoc = ms_pFieldIOCP->GetFieldIOCPSocket(pRMsg->AFSClientIdx);
	if(NULL == FISoc
		|| FALSE == FISoc->IsValidCharacter(FALSE)) {
		return RES_BREAK;
	}

	ITEM * ItemInfo = ms_pFieldIOCP->GetItemInfo(pRMsg->ItemNum);
	if(NULL == ItemInfo)
	{
		return RES_BREAK;
	}

	if(ItemInfo->IsExistDesParam(DES_INFINITY_REENTRY_TICKET))
	{
		FISoc->m_InfinityPlayingInfo.bHaveReentryTicket = TRUE;
	}

	return RES_RETURN_TRUE;
}


/********************************************************************************************************************
**
**	인티니티 방의 난이도 변경 요청 처리. ( 아레나 서버만 처리. )
**
**	Create Info :	2010. 05. 24. by hsLee.
**
*********************************************************************************************************************/
ProcessResult CFieldIOCPSocket :: Process_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL ( const char* pPacket , int nLength , int &nByteUsed )
{

	DECLARE_MESSAGE_AND_CHECK_SIZE ( pPacket , nLength , nByteUsed , 
									T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL , MSG_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL , pRMsg );

	if ( FALSE == g_pFieldGlobal->IsArenaServer() ) 
	{
		g_pFieldGlobal->WriteSystemLogEX( TRUE , "[ERROR] ArenaServer is not\r\n" );
		return RES_RETURN_FALSE;
	}
	
	if ( FALSE == IsValidCharacter( FALSE ) ) 
	{
		return RES_BREAK;
	}

	if ( ARENA_STATE_NONE != this->m_ArenaInfo.State ) 
	{
		SendErrorMessage( T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL , ERR_ARENA_STATE );
		return RES_BREAK;
	}

	if ( INFINITY_STATE_NONE == this->m_InfinityPlayingInfo.InfinityState ) 
	{
		SendErrorMessage( T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL , ERR_INFINITY_STATE );
		return RES_BREAK; 
	}

	CFieldIOCPSocket *i_pcFdIocpSocket = this->ms_pFieldIOCP->GetFieldIOCPSocket ( this->m_character.ClientIndex );

	if ( NULL == i_pcFdIocpSocket )
	{
		return RES_BREAK;
	}

	Err_t ErrorCode = this->ms_pFieldIOCP->m_InfinityManager.ChangeInfinityDifficultyLevel ( pRMsg->InfinityDifficultyLevel , this->m_InfinityPlayingInfo.ModeTypeNum , 
																							this->m_InfinityPlayingInfo.InfinityCreateUID , i_pcFdIocpSocket );

	if ( ErrorCode != ERR_NO_ERROR )
	{
		SendErrorMessage ( T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL , ErrorCode );
		return RES_BREAK;
	}
	
	return RES_RETURN_TRUE;

}


			// 인피니티 엔딩 시네마 스킵 요청 C->F // 2010. 07. 27 by hsLee 인피니티 2차 거점 방어 시네마 연출 스킵 처리.
ProcessResult CFieldIOCPSocket :: Process_FC_INFINITY_SKIP_ENDINGCINEMA ( const char* pPacket , int nLength , int &nByteUsed )
{

	DECLARE_MESSAGE_AND_CHECK_SIZE ( pPacket , nLength , nByteUsed , 
									T_FC_INFINITY_SKIP_ENDING_CINEMA , MSG_FC_INFINITY_SKIP_ENDING , pRMsg );

	if ( FALSE == g_pFieldGlobal->IsArenaServer() ) 
	{
		g_pFieldGlobal->WriteSystemLogEX( TRUE , "[ERROR] ArenaServer is not\r\n" );
		return RES_RETURN_FALSE;
	}
	
	if ( FALSE == IsValidCharacter( FALSE ) ) 
	{
		SendErrorMessage( T_FC_INFINITY_SKIP_ENDING_CINEMA , ERR_INVALID_CHARACTER );
		return RES_BREAK;
	}
	
	if ( ARENA_STATE_NONE != this->m_ArenaInfo.State ) 
	{
		SendErrorMessage( T_FC_INFINITY_SKIP_ENDING_CINEMA , ERR_ARENA_STATE );
		return RES_BREAK;
	}
	
	if ( INFINITY_STATE_PLAYING > this->m_InfinityPlayingInfo.InfinityState ) 
	{
		SendErrorMessage( T_FC_INFINITY_SKIP_ENDING_CINEMA , ERR_INFINITY_PLAYING_STATE );
		return RES_BREAK; 
	}

	if ( this->m_InfinityPlayingInfo.InfinityCreateUID != pRMsg->InfinityCreateUID )
	{
		SendErrorMessage ( T_FC_INFINITY_SKIP_ENDING_CINEMA , ERR_INFINITY_MISMATCH_CREATEUID );
		return RES_BREAK;
	}

	Err_t rtn_Error = this->ms_pFieldIOCP->m_InfinityManager.InfinitySkipEndingCinema ( this->m_InfinityPlayingInfo.ModeTypeNum , this->m_InfinityPlayingInfo.InfinityCreateUID , this , pRMsg->bNormalEnding );
	
	if ( rtn_Error != ERR_NO_ERROR )
	{
		SendErrorMessage( T_FC_INFINITY_SKIP_ENDING_CINEMA , rtn_Error );
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;

}


///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::SendInfinityDifficulty_Info()
/// \brief		인피니티 - 난이도 체크및 전송
///				// 2010-05-13 by shcho, 인피니티 난이도 조절 -
/// \author		shcho
/// \date		2010-05-13 ~
/// \warning	아레나 서버만 처리 !!!
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::SendInfinityDifficulty_Info()
{	
	//컨테이너에서 난이도 리스트를 가져온다.
	vectorInfinity_DifficultyInfo_Bonus tmInfinityDifficultyList;
	ms_pFieldIOCP->m_InfinityManager.Get_Difficulty_BonusInfo_ListData( &tmInfinityDifficultyList);//인피니티 매니저에서 리스트 정보 가져옴
	//정보가 없다면 에러
	if(0 >= tmInfinityDifficultyList.size())
	{
		return ERR_INFINITY_DIFFICLUTY_NOT_FIND;
	}
	
	//가져온 정보를 패킷으로 만들어준다. 가변형 패킷....
	INIT_MSG_WITH_BUFFER(MSG_INFINITY_DIFFICULTY_LIST_OK, T_FC_INFINITY_DIFFICULTY_LIST_OK, pSendMsg, SendBuf);
	int	nRecodeCnt = 0; //카운트를 담는다.
	vectorInfinity_DifficultyInfo_Bonus::iterator iter; //데이터를 찾을 반복자
	//리스트 데이터의 시작지점
	INFINITY_DIFFICULTY_BONUS_INFO* DList 
		= (INFINITY_DIFFICULTY_BONUS_INFO*)(SendBuf+MSG_SIZE(MSG_INFINITY_DIFFICULTY_LIST_OK));
	for(iter = tmInfinityDifficultyList.begin() ;iter!=tmInfinityDifficultyList.end(); iter++)
	{
		DList[nRecodeCnt].iIncreaseStep			= iter->iIncreaseStep; //난이도 넘버
		DList[nRecodeCnt].iExp					= iter->iExp; //경험치 확률
		DList[nRecodeCnt].iDrop_Item_Persent	= iter->iDrop_Item_Persent; //아이템 드랍 확률
		DList[nRecodeCnt].iItem_EA_persent		= iter->iItem_EA_persent; //아이템 갯수 확률
		nRecodeCnt++;//한번 읽어 올때 마다 카운팅 한다.
	}
	pSendMsg->Difficulty_List_count = nRecodeCnt; //카운트를 넣는다.
	this->SendAddData(SendBuf, MSG_SIZE(MSG_INFINITY_DIFFICULTY_LIST_OK) + nRecodeCnt * sizeof(INFINITY_DIFFICULTY_BONUS_INFO));
	return ERR_NO_ERROR;
}

// 2010-08-05 by dhjin, 버닝맵 - 
Err_t CFieldIOCPSocket::CheckPossibleBurningMapWarp(MapIndex_t i_nMapIdx)
{	// 버닝맵 워프가 가능한지 조건 체크
	BURNING_MAP_INFO * tmBurningMapInfo = NULL;
	tmBurningMapInfo = this->ms_pFieldIOCP->GetBurningMapInfo(i_nMapIdx);
	if(NULL == tmBurningMapInfo)
	{// 버닝맵이 아니다.
		return ERR_NO_ERROR;
	}

	if(FALSE == COMPARE_BIT_FLAG(this->m_character.UnitKind, tmBurningMapInfo->ReqUnitKind))
	{
		return ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED;
	}

	if(tmBurningMapInfo->ReqMinLv > this->m_character.Level 
		|| tmBurningMapInfo->ReqMaxLv < this->m_character.Level)
	{
		return ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED;
	}

	return ERR_NO_ERROR;
}

BOOL CFieldIOCPSocket::IsGetOutBurningMap(MapIndex_t i_nMapIdx)
{	// 버닝맵에서 나가버렷~!!
	BURNING_MAP_INFO * tmBurningMapInfo = NULL;
	tmBurningMapInfo = this->ms_pFieldIOCP->GetBurningMapInfo(i_nMapIdx);
	if(NULL == tmBurningMapInfo)
	{	// 버닝맵 아니다.
		return FALSE;
	}

	if(tmBurningMapInfo->ReqMinLv > this->m_character.Level 
		|| tmBurningMapInfo->ReqMaxLv < this->m_character.Level)
	{
		return TRUE;
	}

	return FALSE;
}
// end, 2010-08-05 by dhjin, 버닝맵 - 



/////////////////////////////////////////////////////////////
// start 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_PET_SET_NAME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_PET_SET_NAME, MSG_FC_ITEM_PET_SET_NAME, pRMsg);

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
#else
	SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_COMMON_DISABLE_CONTENT);
	return RES_BREAK;
#endif

	if( FALSE == IsValidCharacter(FALSE) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if( NULL == pItemGeneral )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(pRMsg->ItemUniqueNumber);

	if( NULL == pPetInfo )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;		
	}

	if( WEAR_ATTACHED != pItemGeneral->Wear )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_PET_NOT_EQUIPPED, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	const tPET_BASE_ALL_DATA *pPetBaseData = ms_pFieldIOCP->m_cPetDataManager.GetPetData(pPetInfo->PetIndex);

	if( pPetBaseData == NULL || FALSE == pPetBaseData->BaseData.EnableName)
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_PET_NOT_ALLOW_CHANGE_NAME, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;					
	}

	if( 0 == pRMsg->PetName[0] )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_NAME, ERR_PET_EMPTY_NAME, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	QPARAM_PET_SET_NAME *pQParam = new QPARAM_PET_SET_NAME;
	pQParam->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	STRNCPY_MEMSET(pQParam->PetName, pRMsg->PetName, SIZE_MAX_PET_NAME);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetName, this, m_character.AccountUniqueNumber, pQParam);

	STRNCPY_MEMSET(pPetInfo->PetName, pRMsg->PetName, SIZE_MAX_PET_NAME);


	INIT_MSG_OF_SIZE(MSG_FC_ITEM_PET_SET_NAME_OK, T_FC_ITEM_PET_SET_NAME_OK, pSMsg, pSendBuf);
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	STRNCPY_MEMSET(pSMsg->PetName, pRMsg->PetName, SIZE_MAX_PET_NAME);
	SendAddData(pSendBuf, MSG_SIZE(MSG_FC_ITEM_PET_SET_NAME_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_PET_SET_EXP_RATIO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE (pPacket, nLength, nBytesUsed, T_FC_ITEM_PET_SET_EXP_RATIO, MSG_FC_ITEM_PET_SET_EXP_RATIO, pRMsg);

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
#else
	SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_COMMON_DISABLE_CONTENT);
	return RES_BREAK;
#endif

	if( FALSE == IsValidCharacter(FALSE) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if( NULL == pItemGeneral )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(pRMsg->ItemUniqueNumber);

	if( NULL == pPetInfo )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;		
	}

	if( WEAR_ATTACHED != pItemGeneral->Wear )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_PET_NOT_EQUIPPED, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	const tPET_BASE_ALL_DATA *pPetBaseData = ms_pFieldIOCP->m_cPetDataManager.GetPetData(pPetInfo->PetIndex);

	if( pPetBaseData == NULL || FALSE == pPetBaseData->BaseData.EnableLevel )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_PET_NOT_ALLOW_LEVEL_UP, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;					
	}

	if( FALSE == IS_IN_RANGE(0, pRMsg->ExpRatio, 100) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_EXP_RATIO, ERR_PET_NUMERIC_VALUE_OUT_OF_RANGE, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	QPARAM_PET_SET_EXP_RATIO *pQParam = new QPARAM_PET_SET_EXP_RATIO;
	pQParam->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	pQParam->ExpRatio = pRMsg->ExpRatio;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetExpRatio, this, m_character.AccountUniqueNumber, pQParam);

	pPetInfo->PetExpRatio = pRMsg->ExpRatio;
	
	INIT_MSG_OF_SIZE(MSG_FC_ITEM_PET_SET_EXP_RATIO_OK, T_FC_ITEM_PET_SET_EXP_RATIO_OK, pSMsg, pSendBuf);
	pSMsg->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	pSMsg->ExpRatio = pRMsg->ExpRatio;
	SendAddData(pSendBuf, MSG_SIZE(MSG_FC_ITEM_PET_SET_EXP_RATIO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_PET_SET_SOCKET(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_PET_SET_SOCKET, MSG_FC_ITEM_PET_SET_SOCKET, pRMsg);

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
#else
	SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_COMMON_DISABLE_CONTENT);
	return RES_BREAK;
#endif

	if( FALSE == IsValidCharacter(FALSE) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if( NULL == pItemGeneral )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(pRMsg->ItemUniqueNumber);

	if( NULL == pPetInfo )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;		
	}

	if( WEAR_ATTACHED != pItemGeneral->Wear )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PET_NOT_EQUIPPED, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	// 현재 Open 되어있는 소켓인가?

	if( pRMsg->SocketIndex < 0 || pPetInfo->PetEnableSocketCount < (pRMsg->SocketIndex + 1) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PET_NOT_ALLOW_SOCKET_INDEX, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 현재 소켓에 아이템이 박혀 있는가?

	if( 0 != pPetInfo->PetSocketItemUID[pRMsg->SocketIndex] )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PET_ALREADY_USE_SOCKET, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 현재 캐릭터에 사용할 소켓 아이템이 있는가?

	ITEM_GENERAL *pItemSocket = m_ItemManager.GetItemGeneralByUID(pRMsg->PetSocketItemUID);
	if( NULL == pItemSocket )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 주어진 소켓이 PET_SOCKET_ITEM 속성을 가지고 있는가?

	if( FALSE == IS_DES_PET_SOCKET_ITEM(pItemSocket->ItemInfo) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_SOCKET, ERR_PET_INVALID_SOCKET, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	const tPET_BASE_ALL_DATA *pPetBaseData = ms_pFieldIOCP->m_cPetDataManager.GetPetData(pPetInfo->PetIndex);

	pPetInfo->PetSocketItemUID[pRMsg->SocketIndex] = pRMsg->PetSocketItemUID;

	QPARAM_PET_SET_SOCKET *pQParam = new QPARAM_PET_SET_SOCKET;
	pQParam->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	memcpy(pQParam->PetSocketItemUID, pPetInfo->PetSocketItemUID, sizeof(pQParam->PetSocketItemUID));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetSocket, this, m_character.AccountUniqueNumber, pQParam);

	// 아이템 숨김 처리

	pItemSocket->ItemWindowIndex	= POS_HIDDEN_ITEM;
	pItemSocket->Wear = WEAR_NOT_ATTACHED;

	QPARAM_CHANGE_ITEM_WINDOW_POSITION *pQParamChangeWindowPosition	= new QPARAM_CHANGE_ITEM_WINDOW_POSITION;

	pQParamChangeWindowPosition->AccountUID			= m_character.AccountUniqueNumber;
	pQParamChangeWindowPosition->CharacterUID		= m_character.CharacterUniqueNumber;
	pQParamChangeWindowPosition->ItemUID1			= pItemSocket->UniqueNumber;
	pQParamChangeWindowPosition->ItemWindowIndex1	= pItemSocket->ItemWindowIndex;
	pQParamChangeWindowPosition->ItemWear1			= pItemSocket->Wear;
	pQParamChangeWindowPosition->ItemUID2			= 0;
	pQParamChangeWindowPosition->ItemWindowIndex2	= POS_INVALID_POSITION;
	pQParamChangeWindowPosition->ItemWear2			= WEAR_NOT_ATTACHED;

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeItemPosition, this, m_character.AccountUniqueNumber, pQParamChangeWindowPosition);

	m_ItemManager.CalcInventoryHiddenItemCounts();

	// 숨겨진 아이템 정보 클라이언트 전송

	INIT_MSG_OF_SIZE(MSG_FC_ITEM_NOTIFY_WINDOW_POSITION, T_FC_ITEM_NOTIFY_WINDOW_POSITION, pMsgNotify, pMsgNotifyBuf);
	pMsgNotify->UniqueNumber		= pItemSocket->UniqueNumber;
	pMsgNotify->ItemWindowIndex		= pItemSocket->ItemWindowIndex;
	pMsgNotify->Wear				= pItemSocket->Wear;
	SendAddData(pMsgNotifyBuf, MSG_SIZE(MSG_FC_ITEM_NOTIFY_WINDOW_POSITION));

	// 완료 메시지

	INIT_MSG_OF_SIZE(MSG_FC_ITEM_PET_SET_SOCKET_OK, T_FC_ITEM_PET_SET_SOCKET_OK, pSMsg, pSendBuf);
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	pSMsg->SocketIndex = pRMsg->SocketIndex;
	pSMsg->PetSocketItemUID = pRMsg->PetSocketItemUID;
	SendAddData(pSendBuf, MSG_SIZE(MSG_FC_ITEM_PET_SET_SOCKET_OK));

	igLock.auto_unlock_cancel();

	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemSocket);		// 소켓 아이템 사용 (이름 변경 해야할듯)
	//this->m_ItemManager.DeleteItemFromCharacterByUID(pRMsg->PetSocketItemUID, IUT_USE_ITEM, ITEM_IN_CHARACTER);		// 인벤의 아이템 삭제

	return RES_RETURN_TRUE;
};

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_PET_SET_KIT_SLOT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_PET_SET_KIT_SLOT, MSG_FC_ITEM_PET_SET_KIT_SLOT, pRMsg);

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
#else
	SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_COMMON_DISABLE_CONTENT);
	return RES_BREAK;
#endif

	if( FALSE == IsValidCharacter(FALSE) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if( NULL == pItemGeneral )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(pRMsg->ItemUniqueNumber);

	if( NULL == pPetInfo )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;		
	}

	if( WEAR_ATTACHED != pItemGeneral->Wear )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_NOT_EQUIPPED, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	// 현재 Open 되어있는 소켓인가?

	if( pRMsg->SocketIndex < 0 || pPetInfo->PetEnableSocketCount < (pRMsg->SocketIndex + 1) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_NOT_ALLOW_SOCKET_INDEX, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 소켓 번호와 박혀있는 아이템이 서버와 동일한가?

	if( pPetInfo->PetSocketItemUID[pRMsg->SocketIndex] != pRMsg->PetSocketItemUID )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_NOT_MATCH_SOCKET, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	const tPET_BASE_ALL_DATA *pPetBaseData = ms_pFieldIOCP->m_cPetDataManager.GetPetData(pPetInfo->PetIndex);
	const tPET_LEVEL_DATA *pPetLevelData = ms_pFieldIOCP->m_cPetDataManager.GetPetLevelData(pPetInfo->PetIndex, pPetInfo->PetLevel);

	if( NULL == pPetLevelData || NULL == pPetBaseData )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_NO_SUCH_INFO, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 각 적용 비율값은 0 =< x =< 100 사이에 있는가? && 각 단계별 적용 가능한 키트인가?

	if( FALSE == ms_pFieldIOCP->m_cPetDataManager.IsAvailableAutoKit(DES_PET_SLOT_ITEM_AUTOKIT_HP, pPetInfo->PetLevel, &pRMsg->PetKitHP) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_INVALID_AUTOKIT, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	if( FALSE == ms_pFieldIOCP->m_cPetDataManager.IsAvailableAutoKit(DES_PET_SLOT_ITEM_AUTOKIT_SHIELD, pPetInfo->PetLevel, &pRMsg->PetKitShield) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_INVALID_AUTOKIT, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	if( FALSE == ms_pFieldIOCP->m_cPetDataManager.IsAvailableAutoKit(DES_PET_SLOT_ITEM_AUTOKIT_SP, pPetInfo->PetLevel, &pRMsg->PetKitSP) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_KIT_SLOT, ERR_PET_INVALID_AUTOKIT, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 관련 처리

	memcpy(&pPetInfo->PetKitHP, &pRMsg->PetKitHP, sizeof(pPetInfo->PetKitHP));
	memcpy(&pPetInfo->PetKitShield, &pRMsg->PetKitShield, sizeof(pPetInfo->PetKitShield));
	memcpy(&pPetInfo->PetKitSP, &pRMsg->PetKitSP, sizeof(pPetInfo->PetKitSP));

	QPARAM_PET_SET_KIT_SLOT *pQParam = new QPARAM_PET_SET_KIT_SLOT;
	pQParam->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	memcpy(&pQParam->PetKitHP, &pRMsg->PetKitHP, sizeof(pQParam->PetKitHP));
	memcpy(&pQParam->PetKitShield, &pRMsg->PetKitShield, sizeof(pQParam->PetKitShield));
	memcpy(&pQParam->PetKitSP, &pRMsg->PetKitSP, sizeof(pQParam->PetKitSP));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetKitSlot, this, m_character.AccountUniqueNumber, pQParam);

	INIT_MSG_OF_SIZE(MSG_FC_ITEM_PET_SET_KIT_SLOT_OK, T_FC_ITEM_PET_SET_KIT_SLOT_OK, pSMsg, pSendBuf);
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	pSMsg->SocketIndex = pRMsg->SocketIndex;
	pSMsg->PetSocketItemUID = pRMsg->PetSocketItemUID;
	memcpy(&pSMsg->PetKitHP, &pRMsg->PetKitHP, sizeof(pSMsg->PetKitHP));
	memcpy(&pSMsg->PetKitShield, &pRMsg->PetKitShield, sizeof(pSMsg->PetKitShield));
	memcpy(&pSMsg->PetKitSP, &pRMsg->PetKitSP, sizeof(pSMsg->PetKitSP));
	SendAddData(pSendBuf, MSG_SIZE(MSG_FC_ITEM_PET_SET_KIT_SLOT_OK));

	return RES_RETURN_TRUE;
};

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_PET_SET_AUTOSKILL_SLOT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, MSG_FC_ITEM_PET_SET_AUTOSKILL_SLOT, pRMsg);

	int a = 0;

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
#else
	SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_COMMON_DISABLE_CONTENT);
	return RES_BREAK;
#endif

	if( FALSE == IsValidCharacter(FALSE) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if( NULL == pItemGeneral )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(pRMsg->ItemUniqueNumber);

	if( NULL == pPetInfo )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;		
	}

	if( WEAR_ATTACHED != pItemGeneral->Wear )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PET_NOT_EQUIPPED, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;			
	}

	// 현재 Open 되어있는 소켓인가?

	if( pRMsg->SocketIndex < 0 || pPetInfo->PetEnableSocketCount < (pRMsg->SocketIndex + 1) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PET_NOT_ALLOW_SOCKET_INDEX, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 소켓 번호와 박혀있는 아이템이 서버와 동일한가?

	if( pPetInfo->PetSocketItemUID[pRMsg->SocketIndex] != pRMsg->PetSocketItemUID )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PET_NOT_MATCH_SOCKET, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}
	
	const tPET_BASE_ALL_DATA *pPetBaseData = ms_pFieldIOCP->m_cPetDataManager.GetPetData(pPetInfo->PetIndex);
	const tPET_LEVEL_DATA *pPetLevelData = ms_pFieldIOCP->m_cPetDataManager.GetPetLevelData(pPetInfo->PetIndex, pPetInfo->PetLevel);

	if( NULL == pPetLevelData || NULL == pPetBaseData )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PET_NO_SUCH_INFO, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	// 현재 기어에 맞춰서 사용 가능한 스킬인가?

	if( FALSE == ms_pFieldIOCP->m_cPetDataManager.IsAvailableAutoSkill(m_character.UnitKind, &pRMsg->PetAutoSkill) )
	{
		SendErrorMessage(T_FC_ITEM_PET_SET_AUTOSKILL_SLOT, ERR_PET_INVALID_AUTOSKILL, pRMsg->ItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}

	memset(&pPetInfo->PetAutoSkill, 0, sizeof(pPetInfo->PetAutoSkill));
	for(a=0; a<pPetLevelData->SlotCountSkill; a++) pPetInfo->PetAutoSkill.ItemNum[a] = pRMsg->PetAutoSkill.ItemNum[a];		// 허용된 슬롯에 맞는 숫자만큼 복사

	QPARAM_PET_SET_AUTOSKILL_SLOT *pQParam = new QPARAM_PET_SET_AUTOSKILL_SLOT;
	pQParam->ItemUniqueNumber = pRMsg->ItemUniqueNumber;
	memset(&pQParam->PetAutoSkill, 0, sizeof(pQParam->PetAutoSkill));
	for(a=0; a<pPetLevelData->SlotCountSkill; a++) pQParam->PetAutoSkill.ItemNum[a] = pRMsg->PetAutoSkill.ItemNum[a];		// 허용된 슬롯에 맞는 숫자만큼 복사
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetAutoSkillSlot, this, m_character.AccountUniqueNumber, pQParam);

	INIT_MSG_OF_SIZE(MSG_FC_ITEM_PET_SET_AUTOSKILL_SLOT_OK, T_FC_ITEM_PET_SET_AUTOSKILL_SLOT_OK, pSMsg, pSendBuf);
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	pSMsg->SocketIndex = pRMsg->SocketIndex;
	pSMsg->PetSocketItemUID = pRMsg->PetSocketItemUID;
	memset(&pSMsg->PetAutoSkill, 0, sizeof(pSMsg->PetAutoSkill));
	for(a=0; a<pPetLevelData->SlotCountSkill; a++) pSMsg->PetAutoSkill.ItemNum[a] = pRMsg->PetAutoSkill.ItemNum[a];		// 허용된 슬롯에 
	SendAddData(pSendBuf, MSG_SIZE(MSG_FC_ITEM_PET_SET_AUTOSKILL_SLOT_OK));

	return RES_RETURN_TRUE;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

BOOL CFieldIOCPSocket::PetChangeLevel(int Level, float PercentageOfExp /*=NULL*/)
{
	Experience_t Exp = 0, ExpNext = 0, ExpSum = 0;
	UID64_t UniqueNumber = 0;						// 펫의 UID
	ITEM_GENERAL *pItemGeneral = NULL;				// 펫의 td_Store 포인터
	tPET_CURRENTINFO *pPetCurrentInfo = NULL;		// 펫의 td_Pet 포인터
	CPetDataManager *pPetDataManager = NULL;		// 펫의 DataManager 포인터
	const tPET_LEVEL_DATA *pPetLevelData = NULL;
	const tPET_LEVEL_DATA *pPetLevelDataNext = NULL;

	if( Level < 1 )
	{
		return FALSE;
	}

	if( PercentageOfExp < 0 || PercentageOfExp > 100 )
	{
		return FALSE;
	}

	pItemGeneral = (ITEM_GENERAL *)m_ItemPet.ItemNum;

	if( NULL == pItemGeneral )
	{
		return FALSE;
	}

	UniqueNumber = pItemGeneral->UniqueNumber;

	pPetCurrentInfo = m_ItemManager.GetItemPetByUID(UniqueNumber);
	pPetDataManager = &ms_pFieldIOCP->m_cPetDataManager;

	if( NULL == pPetCurrentInfo)
	{
		return FALSE;
	}

	// 경험치 계산

	if( 1 == Level )
	{
		pPetLevelData = pPetDataManager->GetPetLevelData(pPetCurrentInfo->PetIndex, Level);

		if( NULL == pPetLevelData )
		{
			return FALSE;
		}

		Exp = 0;
		ExpNext = pPetLevelData->NeedExp;
	}
	else
	{
		pPetLevelData = pPetDataManager->GetPetLevelData(pPetCurrentInfo->PetIndex, Level - 1);
		pPetLevelDataNext = pPetDataManager->GetPetLevelData(pPetCurrentInfo->PetIndex, Level);

		if( NULL == pPetLevelData || NULL == pPetLevelDataNext )
		{
			return FALSE;
		}

		Exp = pPetLevelData->NeedExp;
		ExpNext = pPetLevelDataNext->NeedExp;
	}

	ExpSum = (INT64)(Exp + ((ExpNext - Exp) * PercentageOfExp / 100.0f));		// 소수점은 버리긔

	// 적용

	PetChangeExperience(ExpSum, TRUE);

	return TRUE;
}

BOOL CFieldIOCPSocket::PetChangeExperience(Experience_t PetExperience, BOOL bAbs/*= FALSE*/)
{
	UID64_t UniqueNumber = 0;						// 펫의 UID
	ITEM *pItem = GetAttachedItem(POS_PET);			// 펫의 ti_Item 포인터
	ITEM_GENERAL *pItemGeneral = NULL;				// 펫의 td_Store 포인터
	tPET_CURRENTINFO *pPetCurrentInfo = NULL;		// 펫의 td_Pet 포인터
	CPetDataManager *pPetDataManager = NULL;		// 펫의 DataManager 포인터

	if( pItem == NULL || pItem->ItemNum == 0)
	{
		return FALSE;
	}

	pItemGeneral = (ITEM_GENERAL *)m_ItemPet.ItemNum;

	if( NULL == pItemGeneral )
	{
		return FALSE;
	}

	UniqueNumber = pItemGeneral->UniqueNumber;		// UID 가 없으면 현재 펫의 UID 로 적용
	pPetCurrentInfo = m_ItemManager.GetItemPetByUID(UniqueNumber);
	pPetDataManager = &ms_pFieldIOCP->m_cPetDataManager;

	if( NULL == pPetCurrentInfo)
	{
			return FALSE;
	}

	const tPET_BASE_ALL_DATA *pPetBaseData = pPetDataManager->GetPetData(pPetCurrentInfo->PetIndex);
	const tPET_LEVEL_DATA *pPetLevelData = pPetDataManager->GetPetLevelData(pPetCurrentInfo->PetIndex, pPetCurrentInfo->PetLevel);

	if( NULL == pPetLevelData || NULL == pPetBaseData )
	{
		return FALSE;
	}

	// 조건 검사

	if( FALSE == pPetBaseData->BaseData.EnableLevel )		// 레벨업 가능한 파트너 인가?
	{
		return FALSE;
	}

	if( FALSE == bAbs && pPetLevelData->Level >= PET_LEVEL_MAX)		// 상대 값 증가인 경우에는 만랩인지 확인
	{
		return FALSE;
	}

	// 경험치 적용

	if( FALSE == bAbs )
	{
		pPetCurrentInfo->PetExp += PetExperience;		// 기존 경험치에 증가
	}
	else
	{
		pPetCurrentInfo->PetExp = PetExperience;		// 현재 경험치 적용
	}

	SendPetInfo(T_FC_ITEM_PET_CHANGE_EXP, pPetCurrentInfo);

	if( TRUE == bAbs || pPetLevelData->NeedExp <= pPetCurrentInfo->PetExp )		// 현재 레벨보다 경험치가 높을 경우
	{
		tPET_LEVEL_DATA *pPetCurrentLevel = pPetDataManager->GetPetLevel(pPetCurrentInfo->PetIndex, pPetCurrentInfo->PetExp);

		if( NULL == pPetCurrentLevel )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] Partner-Level Data Error !!\r\n");

			return TRUE;		// 파트너가 경험치를 먹었으니 TRUE 리턴
		}

		if( pPetCurrentInfo->PetLevel != pPetCurrentLevel->Level )		// 이전 레벨과 현재 레벨이 같지 않다면?
		{
			INT FromPetLevel = 0;

			FromPetLevel = pPetCurrentInfo->PetLevel;

			pPetCurrentInfo->PetLevel = pPetCurrentLevel->Level;
			pPetCurrentInfo->PetEnableSocketCount =  pPetCurrentLevel->SlotCountSocket;

			SendPetInfo(T_FC_ITEM_PET_CHANGE_LEVEL, pPetCurrentInfo);

			QPARAM_PET_SET_LEVEL *pQParam = new QPARAM_PET_SET_LEVEL;
			pQParam->ItemUniqueNumber = pPetCurrentInfo->CreatedPetUID;
			pQParam->Level = pPetCurrentInfo->PetLevel;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetLevel, this, m_character.AccountUniqueNumber, pQParam);

			CAtumLogSender::SendLogMessagePetLEVEL(this, pPetCurrentInfo->CreatedPetUID, pPetCurrentInfo->PetExp, PetExperience, FromPetLevel, pPetCurrentInfo->PetLevel);		// 2012-10-04 by hskim, 한국 자체 서비스 (가비아 IDC) - 파트너 로그 보안
		}
	}

	QPARAM_PET_SET_EXP *pQParam = new QPARAM_PET_SET_EXP;
	pQParam->ItemUniqueNumber = pPetCurrentInfo->CreatedPetUID;;
	pQParam->Exp = pPetCurrentInfo->PetExp;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_PetSetExp, this, m_character.AccountUniqueNumber, pQParam);

	return TRUE;
}

void CFieldIOCPSocket::SendPetInfo(MessageType_t msgType, tPET_CURRENTINFO *pPetCurrentInfo)
{
	int		nUsedBytes = 0;
	BYTE	buffer[SIZE_MAX_PACKET];

	*(MessageType_t*)buffer = msgType;
	nUsedBytes = SIZE_FIELD_TYPE_HEADER;

	switch(msgType)
	{
		case T_FC_ITEM_PET_CHANGE_EXP:
		{
			MSG_FC_ITEM_PET_CHANGE_EXP	*pExp = NULL;
			pExp = (MSG_FC_ITEM_PET_CHANGE_EXP *)(buffer + nUsedBytes);
			pExp->ItemUniqueNumber = pPetCurrentInfo->CreatedPetUID;
			pExp->Experience = pPetCurrentInfo->PetExp;
			nUsedBytes += sizeof(MSG_FC_ITEM_PET_CHANGE_EXP);
		}

		break;

		case T_FC_ITEM_PET_CHANGE_LEVEL:
		{
			MSG_FC_ITEM_PET_CHANGE_LEVEL	*pLevel = NULL;
			pLevel = (MSG_FC_ITEM_PET_CHANGE_LEVEL *)(buffer + nUsedBytes);
			pLevel->ItemUniqueNumber = pPetCurrentInfo->CreatedPetUID;
			pLevel->Level = pPetCurrentInfo->PetLevel;
			nUsedBytes += sizeof(MSG_FC_ITEM_PET_CHANGE_LEVEL);
		}

		break;

		default:
		{
			DBGOUT2(DO2_ALL, "ERROR: SendPetInfo(%s) NOT IMPLEMENTED!!\r\n", GetProtocolTypeString(msgType));
			ASSERT_NOT_IMPLEMENTED_YET();
			return;
		}
	}

	SendAddData(buffer, nUsedBytes);
}

// end 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현

// START 2011-11-03 by shcho, yedang 셧다운제 구현 - 체크 함수 추가
///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckCharacterUIDFormSHOTDOWNMINS(UID32_t i_CharactUID)
/// \brief		2011-11-03 by shcho, yedang 셧다운제 구현 -
/// \author		shcho
/// \date		2011-11-07 ~ 
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckCharacterUIDFormSHOTDOWNMINS(UID32_t i_CharactUID)
{
	mt_auto_lock mta(&m_mtvectAllCharacterInfo);

	FC_CONNECT_LOGIN_INFO * tmpLoginInfo = GetFC_CONNECT_LOGIN_INFONoLock(i_CharactUID);
	if(NULL == tmpLoginInfo) // 값이 없다.
	{
		return FALSE;
	}
	else
	{
		if(TRUE == tmpLoginInfo->ShutDownMINS)
		{	// 셧다운 적용 대상자 이다.
			return TRUE;
		}
		else
		{	// 셧다운 적용 대상자가 아니다.
			return FALSE;
		}
	}
}
// END 2011-11-03 by shcho, yedang 셧다운제 구현 - 체크 함수 추가

// start 2012-01-16 by hskim, 통계 - 화패
SSTATISTICS_MONEY_UNIT CFieldIOCPSocket::GetCurrentMoney()
{
	SSTATISTICS_MONEY_UNIT MoneyOrg;
	memset(&MoneyOrg, 0, sizeof(MoneyOrg));

	mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_SYSTEM_ORB);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.System = pItemG->CurrentCount;
	}

	pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_QUASAR_ORB);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.Quasar = pItemG->CurrentCount;
	}

	pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_CLUSTER_ORB);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.Cluster = pItemG->CurrentCount;
	}

	pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_GALAXY_ORG);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.Galaxy = pItemG->CurrentCount;
	}

	pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(ITEM_NUM_UNIVERSE_ORB);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.Universe = pItemG->CurrentCount;
	}

	pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	if (NULL != pItemG && NULL != pItemG->ItemInfo)
	{
		MoneyOrg.SPI = pItemG->CurrentCount;
	}

	return MoneyOrg;
}

void CFieldIOCPSocket::StatisticsInfinityStart()
{
	memset(&m_StatisticsInfinityMoney, 0, sizeof(m_StatisticsInfinityMoney));

	m_StatisticsInfinityMoney = GetCurrentMoney();
}

SSTATISTICS_MONEY_UNIT CFieldIOCPSocket::StatisticsInfinityEnd()
{
	SSTATISTICS_MONEY_UNIT TempMoneyOrg;
	memset(&TempMoneyOrg, 0, sizeof(TempMoneyOrg));

	TempMoneyOrg = GetCurrentMoney();
	TempMoneyOrg -= m_StatisticsInfinityMoney;

	memset(&m_StatisticsInfinityMoney, 0, sizeof(m_StatisticsInfinityMoney));

	return TempMoneyOrg;
}
// end 2012-01-16 by hskim, 통계 - 화패

///////////////////////////////////////////////////////////////////////////////////////////////////
// 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 업데이트 내용을 메인 필드서버에게 전달 함수
void CFieldIOCPSocket::ArenaPlayInfoUpdataToMF()
{
#ifndef SC_ARENA_EX_1ST_JHSEOL_MSPARK
	return;
#endif
	CIOCPSocket	*MFSSock = this->ms_pFieldIOCP->GetMFSSockForArenaServer(this->m_AfsNeedMfsInfo.MFSServerID);
	
	if(NULL == MFSSock) 
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] [Arena] CFieldIOCPSocket::ArenaPlayInfoUpdataToMF MainFieldSocket is NULL! MFSServerID(%4d) %s \r\n", this->m_AfsNeedMfsInfo.MFSServerID, GetCharacterString(GetCharacter(), string()));
		return;
	}
	/// 에러정보 남기는거 추가하고 MF로 업데이트 요청
	INIT_MSG_WITH_BUFFER(MSG_FtoA_ARENA_CHARACTERARENAINFO_UPDATA, T_FtoA_ARENA_CHARACTERARENAINFO_UPDATA, pUpdataMsg, SendBuf);
	pUpdataMsg->AccountUID			= this->m_character.AccountUniqueNumber;
	pUpdataMsg->MFSCharacterUID		= this->m_AfsNeedMfsInfo.MFSCharacterUID;
	pUpdataMsg->MFSClientIndex		= this->m_AfsNeedMfsInfo.MFSClientIdx;
	pUpdataMsg->AFSClientIndex		= this->m_character.ClientIndex;
	pUpdataMsg->ArenaInfo			= this->m_character.ArenaPlayInfo;
	MFSSock->SendAddData(SendBuf, MSG_SIZE(MSG_FtoA_ARENA_CHARACTERARENAINFO_UPDATA));
}
// end 2012-04-12 by jhseol, 아레나 추가개발 - 보상 : 아레나 플레이 정보 업데이트 내용을 메인 필드서버에게 전달 함수
// 2012-10-17 by bhsohn XignCode작업
// 2009-05-27 by jhahn Xigncode 한국 적용
BOOL WINAPI CFieldIOCPSocket::XignCodeSendProc(xpvoid uid, PVOID meta, LPCSTR buf, DWORD size)
{
#if defined(YEDANG_KOR)
	UID32_t	CharacterUniqueNumber = (UID32_t)uid;
	CFieldIOCPSocket* pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(CharacterUniqueNumber);
	if(!pSocket || ( pSocket&& !pSocket->IsValidCharacter(FALSE)) )
	{
		return FALSE;
	}
	DBGOUT("CFieldIOCPSocket::XignCodeSendProc [%d] \r\n", CharacterUniqueNumber);
	{
		INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_XIGNCODE_ACK_PACKET, T_FC_CHARACTER_XIGNCODE_S_ACK_PACKET, pSMsg, pSendBuf);
		memcpy(pSMsg->byXigndAckMsg, buf, max(XC_PACKET_SIZE, size));
		
		pSocket->SendAddData(pSendBuf, MSG_SIZE(MSG_FC_CHARACTER_XIGNCODE_ACK_PACKET));
	}	
#endif
	
	return TRUE;

}

void WINAPI CFieldIOCPSocket::XignCodeVerifyProc(xpvoid s, PVOID meta, int code, const char* report)
{
#if defined(YEDANG_KOR)
	UID32_t	CharacterUniqueNumber = (UID32_t)s;
	CFieldIOCPSocket* pSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(CharacterUniqueNumber);
	if(!pSocket || ( pSocket&& !pSocket->IsValidCharacter(FALSE)) )
	{
		return ;
	}
	DBGOUT("CFieldIOCPSocket::XignCodeVerifyProc [%d] \r\n", CharacterUniqueNumber);

	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[XignCode] XignCodeVerifyProc() SocketClose (%s)", GetCharacterString(pSocket->GetCharacter(), string()));
	
	CAtumLogSender::SendLogMessageHackingLog(pSocket, ERR_SECURITY_HACKING_CLIENT);
	pSocket->Close(0x14041, FALSE, 3000);
#endif
}
//end 2009-05-27 by jhahn Xigncode 한국 적용

// 2012-10-17 by bhsohn XignCode작업
// 2012-10-17 by hskim, XignCode작업
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_XIGNCODE_C_ACK_PACKET(const char* pPacket, int nLength, int &nBytesUsed)
{
#if defined(YEDANG_KOR)
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_XIGNCODE_C_ACK_PACKET, MSG_FC_CHARACTER_XIGNCODE_ACK_PACKET, pRMsg);
	
	DBGOUT("T_FC_CHARACTER_XIGNCODE_C_ACK_PACKET CharacterUniqueNumber[%d] m_bXignCodeClient[%d] \r\n", 
		this->m_character.CharacterUniqueNumber, m_bXignCodeClient);

	if(m_bXignCodeClient)
	{
		CFieldIOCPSocket::m_XignCodeServer->OnReceive((xpvoid)this->m_character.CharacterUniqueNumber, (xpcch)pRMsg->byXigndAckMsg, XC_PACKET_SIZE);		
	}
#endif

	return RES_RETURN_TRUE;
};

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_XIGNCODE_C_ACK_CODE(const char* pPacket, int nLength, int &nBytesUsed)
{
#if defined(YEDANG_KOR)
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_XIGNCODE_C_ACK_CODE, MSG_FC_CHARACTER_XIGNCODE_C_ACK_CODE, pRMsg);
	{
		ULONG nErrocode = pRMsg->Code;	

		DBGOUT("T_FC_CHARACTER_XIGNCODE_C_ACK_CODE CharacterUniqueNumber[%d] nErrocode[%x] \r\n", 
			this->m_character.CharacterUniqueNumber, nErrocode);

		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[XignCode] Process_FC_CHARACTER_XIGNCODE_C_ACK_CODE (%s) ACK_CODE (%x)\r\n", GetCharacterString(GetCharacter(), string()), nErrocode);

//		switch(nErrocode)
// 		{
// 		case ZCWAVE_E_INVALID_CALL :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"[%s] [%s] 윈도우 커널 내부 함수를 임의적으로 호출한 경우에 발생합니다.", pChar->GetCharname(), ((ASUserObject*)pChar->GetOwner())->m_strUsername);
// 			}
// 			break;
// 		case ZCWAVE_E_INVALID_SDT :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"SDT 주소를 구할 수 없는 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_KERNEL_CODE_CHANGED :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"XIGNCODE 드라이버 코드가 변경된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_DEBUGGER :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"디버거를 탐지한 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_IDT_MODIFIED :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"디버거 인터럽트가 변경된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_MAL_DRIVER :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"악성 드라이버가 검출된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_DX_HOOK:
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"DirectX 훅 코드가 검출된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_MAL_INI :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"악성  ini 파일이 검출된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_MAL_NET_IO :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"방화벽에 의해서 차단된 행위가 발생한 경우입니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_SPEED_HACK :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"스피드핵이 탐지된 경우입니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_BLACKCODE :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"[%s] [%s] 패턴에 추가된 악성 해킹툴이 탐지된 경우입니다.", 
// 					pChar->GetUserObject()->m_szAddr, pChar->GetUserObject()->m_strUsername);
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_UNKNOWN_OS :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"XIGNCODE가 동작할 수 없는 운영체제에서 실행 된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_ALREADY_HOOKED :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"XIGNCODE와 동시에 실행할 수 없는 프로그램이 이미 동작 중인 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_VM :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"가상 홖경에서 실행된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_COMPAT_9X :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"윈도우  95, 98, ME 호홖 모드로 실행된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_DETECT_ALREADY_RUNNING :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"게임 클라이언트가 중복 실행된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_CANT_LOAD_DRIVER :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, 
// 					"드라이버를 로딩하지 못한 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_CLIENT_CHANGED :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, "게임 클라이언트가 변경된 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_CANT_CREATE_FILE :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, "파일 생성을 할 수 없는 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_UPDATE_FAIL :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, "업데이트에 실패한 경우에 발생합니다. ");
// 			}
// 			break;
// 		case ZCWAVE_E_ALREADY_UPDATING :
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, "동일 클라이언트의 다른 인스턴스가 업데이트 중인 경우에 발생합니다.");
// 			}
// 			break;
// 		default:
// 			{
// 				GetGameMain()->WriteLog(LOG_SYSTEM, LOG_TYPE_GAMEGUARD, "%s", nErrocode);
// 			}
// 			break;
// 		}
	}
#endif

	return RES_RETURN_TRUE;
};
// end 2012-10-17 by hskim, XignCode작업

// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 패킷 받기
///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_COLLECTION_SHAPE_CHANGE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아머 컬렉션에서 외형을 바꿀때 클라이언트에서 전송하는 패킷 MSG안에 ShapeNum 값이 0 이면 외형 초기화, 0이 아니면 외형 변경
/// \author		jhseol,bckim
/// \date		2013-05-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_COLLECTION_SHAPE_CHANGE(const char* pPacket, int nLength, int &nBytesUsed)
{
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - Process_FC_COLLECTION_SHAPE_CHANGE 함수
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		// 아레나 서버에선 사용 불가 에러
		SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_COLLECTION_SHAPE_CHANGE
		, MSG_FC_COLLECTION_SHAPE_CHANGE, pRMsg);

	ITEM_GENERAL *pTargetItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->TargetItemUID);

	if ( NULL == pTargetItemG )
	{
		// 아이템이 없음 에러
		SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_INVALID_ARMOR_ITEM);
		return RES_BREAK;
	}

	if ( FALSE == IS_ENABLE_CHANGE_ShapeItemNum(pTargetItemG->Kind) )
	{
		// 외형변경이 불가능한 아이템임 에러
		SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_INVALID_ITEM_KIND);
		return RES_BREAK;
	}

	switch(pRMsg->CollectionType)
	{
	case COLLECTION_TYPE_ARMOR:	// 아머 컬렉션
		{
			if ( ITEMKIND_DEFENSE != pTargetItemG->Kind )
			{
				// 에러
				SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_INVALID_ITEM_KIND);
				return RES_BREAK;
			}

			// 2013-11-26 by jhseol, 아머 컬렉션 스텟 중첩버그
			if ( WEAR_ATTACHED == pTargetItemG->Wear)
			{
				SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION);
				return RES_BREAK;
			}
			// end 2013-11-26 by jhseol, 아머 컬렉션 스텟 중첩버그
			
			// 외형 변경 요청이면 미리 컬렉션 정보도 확인한다.
			COLLECTION_INFO *CollectionInfoPtr = NULL;
			if ( 0 != pRMsg->ShapeNum )
			{
				CollectionInfoPtr = m_ArmorCollection.GetCollectionInfoPtr(pRMsg->ShapeNum);
				if ( NULL == CollectionInfoPtr )
				{
					// 컬렉션 정보가 없음
					SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_INVALID_ITEMNUM);
					return RES_BREAK;
				}
				ITEM *tmShapeKitItem = ms_pFieldIOCP->GetItemInfo(CollectionInfoPtr->ShapeItemNum);
				if ( NULL == tmShapeKitItem )
				{
					// 적용할 킷이 없음 에러
					SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_INVALID_ITEMNUM);
					return RES_BREAK;
				}
				if ( FALSE == IS_SAME_UNITKIND(pTargetItemG->ItemInfo->ReqUnitKind, tmShapeKitItem->ReqUnitKind) ||		// 아이템과 외형의 기어타입이 맞지 않거나
					 FALSE == IS_SAME_UNITKIND(m_character.UnitKind, tmShapeKitItem->ReqUnitKind) )						// 캐릭터와 외형이 기어타입이 맞지 않으면 에러
				{
					// 기어 타입이 다름 에러
					SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0010);
					SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED);
					return RES_BREAK;
				}
				if ( pTargetItemG->ShapeItemNum == CollectionInfoPtr->ShapeNum && SHAPE_STAT_INIT_LEVEL < pTargetItemG->FixedTermShape.nStatLevel )
				{
					// 이미 아머에 적용된 컬렉션 정보와 같은 컬렉션을 반복하여 적용 요청을 하는 경우. 그냥 종료
					SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_INVALID_ARMOR_ITEM);
					return RES_BREAK;
				}
				if ( 0 < CollectionInfoPtr->ActivedCount )
				{
					ATUM_DATE_TIME atCurrentTime(TRUE);
					if ( 0 >= CollectionInfoPtr->EndTime.GetTimeDiffTimeInSeconds(atCurrentTime) && CollectionInfoPtr->EnchantLevel < SHAPE_STAT_FIXED_TIME_LIMITE_LEVEL )	// 2013-08-02 by jhseol, 아머 컬렉션 무제한 외형 적용 안되는 버그 수정
					{
						// 사용 가능한 시간이 없음.
						SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_OVER_COUNT);
						return RES_BREAK;
					}
				}
				else
				{
					if ( 0 >= CollectionInfoPtr->RemainSeconds  && CollectionInfoPtr->EnchantLevel < SHAPE_STAT_FIXED_TIME_LIMITE_LEVEL )	// 2013-08-02 by jhseol, 아머 컬렉션 무제한 외형 적용 안되는 버그 수정
					{
						// 사용 가능한 시간이 없음.
						SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_OVER_COUNT);
						return RES_BREAK;
					}
				}
			}
			else
			{
				if ( 0 == pTargetItemG->ShapeItemNum )
				{
					// 적용된 외형이 없는 아머에 외형 해제를 하는 경우이다. 그냥 종료
					SendErrorMessage(T_FC_COLLECTION_SHAPE_CHANGE, ERR_INVALID_ARMOR_ITEM);
					return RES_BREAK;
				}
			}
			
			// 기존의 외형이 있든 없든 삭제 해준다
			m_ItemManager.ReturnShapeChangeKitItem(pTargetItemG);
			if ( SHAPE_STAT_INIT_LEVEL < pTargetItemG->FixedTermShape.nStatLevel )
			{
				m_ArmorCollection.ChangeActivedCount(pTargetItemG->ShapeItemNum, FALSE);
			}
			
			if( 0 != pTargetItemG->FixedTermShape.TimerUID && 0 != pTargetItemG->ShapeItemNum )
			{
				m_TimerManager.StopTimerField(pTargetItemG->FixedTermShape.TimerUID);
				
				CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pTargetItemG, pTargetItemG->ShapeItemNum, pTargetItemG->FixedTermShape);
			}
			MSG_FL_LOG_COLLECTION_SHAPE_CHANGE pShapeChangeLog;
			MEMSET_ZERO(&pShapeChangeLog, sizeof(MSG_FL_LOG_COLLECTION_SHAPE_CHANGE));
			pShapeChangeLog.AccountUID		= m_character.AccountUniqueNumber;
			pShapeChangeLog.CharacterUID	= m_character.CharacterUniqueNumber;
			pShapeChangeLog.CollectionType	= COLLECTION_TYPE_ARMOR;
			pShapeChangeLog.ItemUID			= pTargetItemG->UniqueNumber;
			pShapeChangeLog.BeforeShapeNum	= pTargetItemG->ShapeItemNum;

			pTargetItemG->ShapeItemNum						= 0;
			pTargetItemG->FixedTermShape.bActive			= FALSE;
			pTargetItemG->FixedTermShape.StartDate.Reset();
			pTargetItemG->FixedTermShape.EndDate.Reset();
			pTargetItemG->FixedTermShape.TimerUID			= 0;
			pTargetItemG->FixedTermShape.nStatLevel			= SHAPE_STAT_INIT_LEVEL;
			pTargetItemG->FixedTermShape.nStatShapeItemNum	= 0;
			
			QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
			pQParamFT->ItemUID = pTargetItemG->UniqueNumber;
			pQParamFT->TermType = FIXED_TERM_SHAPE;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);
			
			//변경할 외형이 있으면 외형을 변경한다.
			if ( NULL != CollectionInfoPtr )
			{
				BOOL bShapeActvied = FALSE;
				if ( SHAPE_STAT_FIXED_TIME_LIMITE_LEVEL <= CollectionInfoPtr->EnchantLevel )
				{
					bShapeActvied = TRUE;										// 영구제 이면 사용시간의 여부와 관계 없이 외형 적용
				}
				else if ( 0 < CollectionInfoPtr->RemainSeconds )
				{
					bShapeActvied = TRUE;
					pTargetItemG->FixedTermShape.bActive			= TRUE;		// 영구제가 아니고 사용 기간이 남아있으면 기간제로 체크
				}

				if ( TRUE == bShapeActvied )
				{
					m_ArmorCollection.ChangeActivedCount(pRMsg->ShapeNum, TRUE);
					
					pTargetItemG->ShapeItemNum						= CollectionInfoPtr->ShapeNum;
					pTargetItemG->FixedTermShape.StartDate.SetCurrentDateTime();
					pTargetItemG->FixedTermShape.EndDate			= CollectionInfoPtr->EndTime;
					pTargetItemG->FixedTermShape.TimerUID			= 0;
					pTargetItemG->FixedTermShape.nStatLevel			= CollectionInfoPtr->EnchantLevel;
					pTargetItemG->FixedTermShape.nStatShapeItemNum	= CollectionInfoPtr->ShapeItemNum;
					ATUM_DATE_TIME atCurrentTime(TRUE);

					if( CollectionInfoPtr->EndTime.GetTimeDiffTimeInSeconds(atCurrentTime) < MANAGE_MAX_TIME_FIXED_TERM_MINUTELY*60 && TRUE == pTargetItemG->FixedTermShape.bActive )
					{
						pTargetItemG->FixedTermShape.TimerUID = m_TimerManager.StartTimerField(TE_TYPE_FIXED_TERM_SHAPE, CollectionInfoPtr->EndTime.GetTimeDiffTimeInSeconds(atCurrentTime) * TIMER_DECREASE_SP_INTERVAL, 0, 0);
						CAtumLogSender::SendLogMessageFixedTermShapeStart(this, pTargetItemG, CollectionInfoPtr->ShapeItemNum);
					}
				}
			}
			
			QPARAM_SHAPE_STATLEVEL	*pQParamSS = new QPARAM_SHAPE_STATLEVEL;
			pQParamSS->ItemKind				= pTargetItemG->ItemInfo->Kind;
			pQParamSS->ItemUID				= pTargetItemG->UniqueNumber;
			pQParamSS->nStatLevel			= pTargetItemG->FixedTermShape.nStatLevel;
			pQParamSS->nStatShapeItemNum	= pTargetItemG->FixedTermShape.nStatShapeItemNum;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertShapeStatLevel, this, m_character.AccountUniqueNumber, pQParamSS);

			// 변경된 정보를 저장하고 클라에게 보내준다
			QPARAM_UPDATE_SHAPEITEMNUM *pQParam = new QPARAM_UPDATE_SHAPEITEMNUM;
			pQParam->ItemUID							= pTargetItemG->UniqueNumber;
			pQParam->nShapeItemNum						= pTargetItemG->ShapeItemNum;
			pQParam->FixedTermShape.bActive				= pTargetItemG->FixedTermShape.bActive;
			pQParam->FixedTermShape.StartDate			= pTargetItemG->FixedTermShape.StartDate;
			pQParam->FixedTermShape.EndDate				= pTargetItemG->FixedTermShape.EndDate;
			pQParam->FixedTermShape.TimerUID			= pTargetItemG->FixedTermShape.TimerUID;
			pQParam->FixedTermShape.nStatLevel			= pTargetItemG->FixedTermShape.nStatLevel;
			pQParam->FixedTermShape.nStatShapeItemNum	= pTargetItemG->FixedTermShape.nStatShapeItemNum;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateShapeItemNum, this, m_character.AccountUniqueNumber, pQParam);
			SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0007);

			pShapeChangeLog.AfterShapeNum		= pTargetItemG->ShapeItemNum;
			CAtumLogSender::SendLogMessageCollectionShapeChange(&pShapeChangeLog);

			// 2013-04-18 by jhseol,bckim 이달의 아머 - 외형 변경 후 이달의 아머 이벤트 확인
#ifdef S_MONTHL_ARMOR_EVENT_JHSEOL_BCKIM		// 외형 변경 후 이달의 아머 이벤트 확인
			m_ArmorCollection.CheckMonthlyArmorEvent(pTargetItemG);		// 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경
#endif
			// end 2013-04-18 by jhseol,bckim 이달의 아머 - 외형 변경 후 이달의 아머 이벤트 확인

		}
		break;
	default:
		break;
	}
#endif
	return RES_RETURN_TRUE;
}
// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 패킷 받기


// 2013-08-07 by bckim, 미션프리패스 아이템
Err_t CFieldIOCPSocket::QuestMisstionFreePass(ITEM* i_pItemInfo)
{
	if( NULL == i_pItemInfo)
	{
		return ERR_PROTOCOL_CANNOT_USE_ITEM;
	}

	CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();
	if( NULL == pFCharQuest || ( pFCharQuest->QuestState != QUEST_STATE_IN_PROGRESS) )
	{
		// 퀘스트 진행중이 아니거나 완료된 퀘스트 입니다. 
		return ERR_PROTOCOL_QUEST_NOT_IN_PROGRESS;
	}
	
	int nMinLv = i_pItemInfo->GetParameterValue(DES_QUEST_MISSION_FREE_PASS_MIN_LV);
	int nMaxLv = i_pItemInfo->GetParameterValue(DES_QUEST_MISSION_FREE_PASS_MAX_LV);
	// 범위체크 
	if( nMinLv <= pFCharQuest->m_pQuestInfo->ReqLevel.Min && pFCharQuest->m_pQuestInfo->ReqLevel.Min <= nMaxLv)
	{
		// 아이템을 사용할수 있는 퀘스트의 레벨
		CQuest * pQuestInfo = ms_pFieldIOCP->GetQuestInfo(pFCharQuest->QuestIndex);
		if( NULL != pQuestInfo && QUEST_END_TYPE_SELECT_INFLUENCE == pQuestInfo->QuestEndType )
		{	
			return ERR_PROTOCOL_QUEST_FREEPASS_CANNOT_BE_USED;		// 아이템을 사용할수 있는 퀘스트의 레벨
		}

		MSG_FC_QUEST_REQUEST_SUCCESS	pRequestSuccessQuest;
		pRequestSuccessQuest.QuestIndex = pFCharQuest->QuestIndex;
			
		CheckQuestRequestSuccessAndSendResult(pFCharQuest,&pRequestSuccessQuest,TRUE,0,0,0,FALSE,TRUE);
		return ERR_NO_ERROR;
	}
	else
	{
		return ERR_PROTOCOL_QUEST_FREEPASS_NOT_LEVEL_IN_RANGE; 		// 아이템을 사용할수 있는 퀘스트 레벨이 아님. 			
	}
}
// End. 2013-08-07 by bckim, 미션프리패스 아이템

// 2014-01-27 by bckim, 버그 트랩
ProcessResult CFieldIOCPSocket::Process_FC_BUGTRAP_ACCEPT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BUGTRAP_ACCEPT,
		MSG_FC_BUGTRAP_ACCEPT, pMsgAccept);

	this->m_bExceptionUser = TRUE;
	g_pFieldGlobal->WriteSystemLogEX(TRUE, " $$$$$$$$$$ m_bExceptionUser = TRUE $$$$$$$$$$ \r\n");
	return RES_RETURN_TRUE;
}
// End. 2014-01-27 by bckim, 버그 트랩