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


#include "stdafx.h"
#include "AtumSJ.h"						// 2011-11-15 by hskim, EP4 [트리거 시스템] - 버닝맵 경험치 추가
#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 "TriggerMapBuffManager.h"		// 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍
#include "TriggerFunction.h"			// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
#include "MapTriggerManager.h"			// 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점

#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차패스워드 구현 -



#define EFFECTIVE_ATTACK_RANGE_MULTIPLIER		1.5f
#define MIN_ATTACK_DECREASE_FACTOR				0.3f	// 최소 공격 감소 비율

#define BONUS_STAT_PER_A_LEVEL					1

#define RESPAWN_UNBEATABLE_TIME_BY_SECOND		5		// 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간

// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
#define BONUS_EXP_RATE_FRIEND_COUNT				0.015f
#define BONUS_EXP_RATE_FRIEND_MAX				0.7f
#define BONUS_EXP_RATE_REST_DEFAULT				0.35f
// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

// 2012-11-15 by bckim, 이벤트 로드크레아시아 몬스터 아이템 지급 구현 
#define EVENT_MAP_INDEX_VCN							3002		// 바이제니유 맵( 스톤즈루인 )
#define EVENT_MAP_INDEX_ANI							3018		// 알링턴		(레이나드해변)
#define EVENT_MONSTER_INDEX_IN_MAP_VCN				2117300		// 바이제니유 지역의 몬스터 
#define EVENT_MONSTER_INDEX_IN_MAP_ANI				2117400		// 알링턴지역의 몬스터 
#define EVENT_MONSTER_DROP_ITEM_INDEX				7039810		// 지급 아이템 
#define EVENT_MONSTER_DROP_ITEM_COUNT				1			// 지급 아이템 수량 		
// 2012-11-15 by bckim, 이벤트 로드크레아시아 몬스터 아이템 지급 구현. End

CFieldIOCP			*CFieldIOCPSocket::ms_pFieldIOCP = NULL;

// 2008-03-17 by cmkwon, Gameforge4D_Eng 빌링 모듈 연동하기 - 
HANDLE				CFieldIOCPSocket::ms_hBillingLibrary = NULL;

// 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)
PGFBILLINGREQUEST	CFieldIOCPSocket::ms_pGFBillingRequest = NULL;
#endif // END - 

// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
BOOL				CFieldIOCPSocket::ms_bUsingXignCode		= FALSE;

///////////////////////////////////////////////////////////////////////////////
// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
BOOL				CFieldIOCPSocket::ms_XTrapUsingFlag		= FALSE;
#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으로 변경 - 
BYTE				CFieldIOCPSocket::ms_XTrapMap[XTRAP_CSFILE_NUM][XTRAP_CS4_BUFSIZE_MAP];
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFieldIOCPSocket::CFieldIOCPSocket() :
	m_ItemProw(m_arrAttachItems[POS_PROW]),
	m_ItemProwIn(m_arrAttachItems[POS_PROWIN]),
	m_ItemProwOut(m_arrAttachItems[POS_PROWOUT]),
	m_ItemWingIn(m_arrAttachItems[POS_WINGIN]),			// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
	m_ItemWingOut(m_arrAttachItems[POS_WINGOUT]),
	m_ItemCenter(m_arrAttachItems[POS_CENTER]),
	m_ItemRear(m_arrAttachItems[POS_REAR]),

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	/*m_ItemAttachment*/m_ItemAccessoryUnLimited(m_arrAttachItems[POS_ACCESSORY_UNLIMITED/*POS_ATTACHMENT*/]),

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	/*m_ItemPet*/m_ItemAccessoryTimeLimit(m_arrAttachItems[POS_ACCESSORY_TIME_LIMIT /*POS_PET*/]),
	
	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	m_ItemPet( m_arrAttachItems[POS_PET] )
{
	InitializeCriticalSection(&m_criticalLevelAndExperience);

	m_pFieldMapProjectForNPC		= NULL;

	m_mtvectAttackTargetMonsterIndex.reserve(20);
	m_nLastMonsterIndexAttack2Me	= 0;		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	m_nTargetMonsterIndex			= 0;		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	m_pRacingFieldMapChannel		= NULL;

	m_mtvectCharacterCache.reserve(3);
	m_mtvectAllCharacterInfo.reserve(3);

	m_GalaNetAccountIDNum			= 0;
	m_AccountRegisteredDate.Reset();
	MEMSET_ZERO(m_AccountPasswordFromDB, SIZE_MAX_PASSWORD_MD5_STRING);
	m_nGameContinueTimeInSecondOfToday	= 0;		// 2006-11-15 by cmkwon
	m_nGameContinueTimeInSecondOfToday4Viet	= 0;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - CFieldIOCPSocket 생성자 초기화
	m_atimeLastGameEndDate.Reset();					// 2006-11-15 by cmkwon
	m_bIsAdult							= FALSE;	// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 게임 종료시만 초기화		
	m_dwSendPlayTimeInfoLastTick		= 0;		// 2007-06-28 by cmkwon, 중국 방심취관련(게임 시간 알림 구현)

	m_Security_bCheckVersion		= FALSE;	// 2006-06-05 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//	MEMSET_ZERO(m_Security_pbyGuidReqInfo, SIZEOF_GUIDREQINFO);
//	
//	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 
//	//m_Security_plCRCInfo			= NULL;
//	MEMSET_ZERO(&m_Security_ClientContext, sizeof(m_Security_ClientContext));	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 

	m_Security_bSendCRCReqMsg		= FALSE;	// 2006-06-05 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//	MEMSET_ZERO(m_Security_pbyReqInfo, SIZEOF_REQINFO);
//	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 'ANTICPSVR_CHECK_ENGINE_FILE' 옵션이 없어지고 'ANTICPSVR_CHECK_NANOENGINE_FILE'로 옵션 변경
//	//m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_ENGINE_FILE;		// 2007-04-02 by cmkwon, ANTICPSVR_CHECK_ENGINE_FILE 추가함
//	m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_NANOENGINE_FILE;
	m_hAhnHSClientHandle			= ANTICPX_INVALID_HANDLE_VALUE;		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 

	m_bInitSecurityClient			= FALSE;		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 

	m_bUnlockSecondaryPassword		= FALSE;							// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 멤버변수 생성자에서 초기화
	MEMSET_ZERO(m_szSecondaryPassword, SIZE_MAX_PASSWORD_MD5_STRING);	// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 멤버변수 생성자에서 초기화

	MEMSET_ZERO(&m_giveTargetCharacter, sizeof(m_giveTargetCharacter));	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 
	m_mtvectNotifyMsgList.clearLock();			// 2007-11-28 by cmkwon, 통지시스템 구현 -

	m_mtvectCouponEventList.clearLock();		// 2008-01-17 by cmkwon, S_F: 쿠폰시스템 버그 수정 - 초기화

	m_bXignCodeReceivedReqScanInitOK	= FALSE;	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	m_hXignCodeAntiCheatHandle			= NULL;		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 

	// 2012-10-17 by bhsohn XignCode작업
	m_bXignCodeClient = FALSE;			
	// END 2012-10-17 by bhsohn XignCode작업

// 2005-09-23 by cmkwon
//	m_mtvectClientIdxForSend.reserve(100);
//	m_mtvectClientIdxForExcludeSend.reserve(20);

	// member 변수 초기화
	ResetAllVariables(RVT_CONSTRUCTOR);

	m_RequestHandler.InitGeneralRequestHandler(this);

	m_bazaarManager.SetFieldIOCPSocket(this);				// 2006-07-31 by cmkwon

	m_bIsPCBangClient				= FALSE;									// 2006-08-22 by dhjin
	m_bPreServerAuthenticated		= FALSE;				// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - PreServer 인증 플래그 변수 초기화

	m_mtvectObersverCharacter.reserve(4); // 2007-03-27 by dhjin

	m_nDeletedPacketCount		= 0;	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 임시용

	m_LetterManager.InitLetterManager(this);	// 2008-04-23 by dhjin, EP3 편지 시스템 - 

	m_dwMSTermSystem = timeGetTime();	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안

	m_pLastSelectedPrefixRareItemInfo		= NULL;		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - // 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
	m_pLastSelectedSuffixRareItemInfo		= NULL;		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - // 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 

	m_bMissionMaster	= FALSE;				// 2008-12-09 by dhjin, 미션마스터
	m_VecMissionMasterIOCPSocket.clear();		// 2008-12-22 by dhjin, 미션마스터

	m_mtVecInfiImpute.clearLock();						// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - // 2009-09-09 ~ 2010 by dhjin, 인피니티 -  인피니티 귀속 정보
	MEMSET_ZERO(&m_InfinityPlayingInfo, sizeof(INFINITY_PLAYING_INFO));		// 2009-09-09 ~ 2010 by dhjin, 인피니티 -  인피니티 중일때 필요한 정보 저장	
	m_InfinityUpdateAllItemCount = 0;		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 종료로 Main서버에서 업데이트 해야될 아이템 수

	m_InvokingItemManager.Init();		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	m_AFSClientIndex = 0;				// 2010-03-31 by dhjin, 인피니티 입장 캐쉬 아이템 구현 - 
	m_InfCurrentAllEXP =0;				// 2010-06-25 by shcho, 인피니티 관련로그 찍기 - 초기화

	m_nMapMoveCount = 0;				// 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	memset(&m_StatisticsInfinityMoney, 0, sizeof(m_StatisticsInfinityMoney));		// 2012-01-16 by hskim, 통계 - 화패

	m_nPlayCharacterType	= ARENA_PLAY_TYPE_ATT;	// 2012-06-08 by jhseol, 아레나 추가개발part2 - 케릭터 : 타입 복사

	// 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
	MEMSET_ZERO(&m_atimeArenaNoDamage, sizeof(ATUM_DATE_TIME));
	m_bArenaNoDamage = FALSE;
	// end 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
	
	m_nRestExperienceCount = 0;		// 2012-10-07 by hskim, 휴식 경험치
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
	m_nKillCount = 0;
	m_nGuildBonusExpRate = 0;
	m_nInSamePartyCount = 0;
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

	m_nArenaCharacterUID = 0;	// 2012-10-21 by jhseol, 아레나 버그수정 - 아레나 종료시 케릭터 정보 리셋.

	m_bProcessingStoreGetItem = FALSE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	m_nCrystalAttackCount = 0;				// 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장

	ResetCashAuthenticationKey();				// 2013-03-13 by hskim, 웹 캐시 상점
	// 2013-11-25 by jhseol&bckim, 거래소
	m_CopyMarketListPtr.clear();
	m_nLatelyMarketPacketRecvTick_BuyPage = 0;
	m_nLatelyMarketPacketRecvTick_SellPage = 0;
	m_nLatelyMarketPacketRecvTick_MyListPage = 0;
	m_nLatelyMarketPacketRecvTick_GetRequeste = 0;
	m_nLatelyMarketListSortingType = 0;
	// end 2013-11-25 by jhseol&bckim, 거래소
	
	BOOL				m_bExceptionUser = FALSE;			// 2014-01-27 by bckim, 버그 트랩	
	m_nExtUserSerial = 0;							// 2014-02-10 by jhseol&bckim, 체널링 - 한국 유저 정보 추가저장
	MEMSET_ZERO(m_szExtCertifyCode, USER_CI_SIZE);	// 2014-02-10 by jhseol&bckim, 체널링 - 한국 유저 정보 추가저장

	// 2014-06-10 by bckim, 세력변경 아이템		-- 사용유무 확인 변수 초기화
	m_NumberOfChangeInfl	= 0;
	// End. 2014-06-10 by bckim, 세력변경 아이템
	m_newNProtectPacketCnt = 0; // 2015-01-19 by shchoi GameForge 게임가드 nProtect로 변경
	m_InvincibleTime = timeGetTime();	// 2015-01-27 by shchoi 워프 시 일시 무적
	m_bPortalInvincible = FALSE;		// 2015-01-27 by shchoi 워프 시 일시 무적
	m_defaultaddInvTime = 3000;			// 2015-01-27 by shchoi 워프 시 일시 무적


}

CFieldIOCPSocket::~CFieldIOCPSocket()
{
	// 2012-10-17 by bhsohn XignCode작업
// 2009-05-27 by jhahn Xigncode 한국 적용
	//싸인코드 종료
// 	if(m_XignCodeServer)
// 	{
// 		m_XignCodeServer->OnEnd();
// 		m_XignCodeServer->Release();
// 	}
//end 2009-05-27 by jhahn Xigncode 한국 적용
	// END 2012-10-17 by bhsohn XignCode작업
	DeleteCriticalSection(&m_criticalLevelAndExperience);

}

void CFieldIOCPSocket::InitFieldIOCPSocket(void)
{
	m_ItemManager.InitFieldDataManager(this);
	m_SkillManager.InitFieldDataManager(this);
	m_TimerManager.InitFieldDataManager(this);
	m_ArmorCollection.InitFieldDataManager(this);	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - m_ArmorCollection init 함수 호출
}

void CFieldIOCPSocket::ResetAllVariables(EnumResetVarType type)
{
//	DBGOUT("ResetAllVariables(%d)\r\n", type);

	/*/////////////////////////////////////////////////////////////////////////
	+ EnumResetVarType - Reset All Variables의 Type
		- RVT_CONSTRUCTOR = 0,
		- RVT_GAME_END = 1,
		- RVT_ON_CLOSE = 2
	/////////////////////////////////////////////////////////////////////////*/

	switch(type)
	{
	case RVT_ON_CLOSE:
		{
			m_GalaNetAccountIDNum		= 0;			// 2006-06-01 by cmkwon
			m_AccountRegisteredDate.Reset();
			MEMSET_ZERO(m_AccountPasswordFromDB, SIZE_MAX_PASSWORD_MD5_STRING);
			m_nGameContinueTimeInSecondOfToday	= 0;		// 2006-11-15 by cmkwon
			m_nGameContinueTimeInSecondOfToday4Viet	= 0;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - CFieldIOCPSocket::ResetAllVariables() 에서  초기화
			m_atimeLastGameEndDate.Reset();					// 2006-11-15 by cmkwon


			m_Security_bCheckVersion		= FALSE;	// 2006-06-05 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//			MEMSET_ZERO(m_Security_pbyGuidReqInfo, SIZEOF_GUIDREQINFO);
//			
//			// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 
//			//m_Security_plCRCInfo			= NULL;
//			MEMSET_ZERO(&m_Security_ClientContext, sizeof(m_Security_ClientContext));		// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 

			m_Security_bSendCRCReqMsg		= FALSE;	// 2006-06-05 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//			MEMSET_ZERO(m_Security_pbyReqInfo, SIZEOF_REQINFO);
//			// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 'ANTICPSVR_CHECK_ENGINE_FILE' 옵션이 없어지고 'ANTICPSVR_CHECK_NANOENGINE_FILE'로 옵션 변경
//			//m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_ENGINE_FILE;		// 2007-04-02 by cmkwon, ANTICPSVR_CHECK_ENGINE_FILE 추가함
//			m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_NANOENGINE_FILE;

			// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 아래에서 this->SecurityClientClean() 호출로 처리
			//m_hAhnHSClientHandle			= ANTICPX_INVALID_HANDLE_VALUE;		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 

			m_bIsAdult						= FALSE;		// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 게임 종료시만 초기화		
			MEMSET_ZERO(m_szSecondaryPassword, SIZE_MAX_PASSWORD_MD5_STRING);		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 멤버변수 생성자에서 초기화

			this->SetPreServerAuthenticated(FALSE);		// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - PreServer 인증 플래그 변수 초기화
			m_nDeletedPacketCount		= 0;	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 임시용

			// 2008-12-04 by cmkwon, 대만 XignCode 버그 수정 - 소켓 종료시에만 초기화 해야함.
			m_bXignCodeReceivedReqScanInitOK	= FALSE;
		}
		break;
	}


	if (type != RVT_GAME_END)
	{
		// RVT_GAME_END일때는 제거하지 않는다. Process_FC_CHARACTER_GET_CHARACTER()에서 m_character의 AccountUniqueNumber를 비교하기 때문이다.
		memset(&m_character, 0x00, sizeof(CHARACTER));
		m_nNumCharacters			= 0;
		SetClientState(CS_NOTCONNECT);
		m_bFlagDBStore				= TRUE;
		m_bFieldServerChangeFlag	= FALSE;
		m_dwConnectTime				= 0;
		m_nGameStartTimeInSeconds	= 0;
		m_bNotifyCloseFlag			= TRUE;
		m_pCurrentEventInfo			= NULL;
		m_nCurrentWarpAreaIndex		= 0xFFFF;
		m_PeerSocketType	= ST_INVALID_TYPE;
		// 2008-05-15 by dhjin, EP3 - 채팅 시스템 변경
		// m_enableChatFlag8	= (BitFlag8_t)0xFF;
		m_enableChatFlag16	= (BitFlag16_t)0xFFFF;

		this->SetSelectableInfluenceMask(INFLUENCE_TYPE_UNKNOWN);
	}

	if (type == RVT_CONSTRUCTOR)
	{
		m_character.ClientIndex = 0;
	}
	else
	{
		m_character.ClientIndex = this->GetClientArrayIndex();
	}
	m_GuildRank = GUILD_RANK_PRIVATE_NULL;

	MEMSET_ZERO(m_szCharacterMent, SIZE_STRING_32);
	m_bStealthState					= FALSE;
	m_bStealthStateBySkill			= FALSE;		// 2013-05-09 by hskim, 세력 포인트 개선	
	m_nPlusHP						= 0;
	m_nPlusDP						= 0;
	m_bDeadReasonByPK				= FALSE;
	m_byCityWarTeamType				= CITYWAR_TEAM_TYPE_NORMAL;
	m_ExperienceDelayStore			= 0.0f;

	// 파티 초기화
	m_pFieldParty					= NULL;

	// Trade Reset
	m_peerTraderCharacterUniqueNumber = INVALID_UNIQUE_NUMBER;
	m_bOKTradeChecked			= FALSE;
	m_mapTradeItem.clearLock();

	m_mtvectCharacterCache.clearLock();
	
	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 ) );

	// ItemManager
	m_ItemManager.ResetAllCharacterItems();

	// SkillManager
	m_SkillManager.ResetSkillData();

	// TimerManager
	m_TimerManager.ResetTimerData();

	m_nInsertingStoreItemCounts			= 0;
	m_dwLastTickInsertingStoreItem		= 0;

	// enchants
	m_mapEnchant.clearLock();

	// quests
	m_mapQuest.clearLock();

	m_mtvectAttackTargetMonsterIndex.clearLock();
	SetLastMonsterIndexAttack2Me(0);			// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
	SetTargetMonsterIndex(0);					// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 

	// param factor reset
	m_ParamFactor.Reset();
	this->SetPartyFormationSkillNum(0);		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 

	// Drop Mine 리스트 초기화
	ClearAllCharacterMines();

	m_STRING_128_print_level = STRING_128_USER_ERR;
	m_bSendMessgeTypeDBG = FALSE;

	if (ms_pFieldIOCP != NULL)
	{
		m_nOldTimeStampDBG = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();
	}

	m_backupRace = 0;

	m_bNoDamage = FALSE;

	m_uiDummyItemFieldIndex			= 0;		// 2006-12-04 by dhjin
	m_bDummyCheck					= FALSE;	// 2006-12-04 by dhjin

	SetCurrentFieldMapChannel(NULL);

	m_bPKMode = FALSE;

	m_peerP2PPKClientIndex = INVALID_CLIENT_INDEX;
	m_bP2PPKStarted = FALSE;

	m_pCurrentBuildingNPC = NULL;

	m_dwSendCountsMoveOK		= 0;
	m_dwSendCountsAttack		= 0;

	// 스피드핵 체크
	m_dwLastTickSpeedHackCheck	= 0;
	MEMSET_ZERO(m_arrSpeedHackCheck, sizeof(m_arrSpeedHackCheck[0])*ARRAYSIZE_SPEED_HACK_DATA);

	memset(&m_UnitRenderInfo, 0x00, sizeof(CHARACTER_RENDER_INFO));

// 2007-03-29 by cmkwon, 필요없음	m_bJoinedRacingBit			= FALSE;
	if(m_pRacingFieldMapChannel)
	{
		m_pRacingFieldMapChannel->OutRacingSystem(this);
	}

	m_countdownChecker.ResetCountdownChecker();

	m_uidAttackerGuildUID		= 0;
	m_dwLastTickRolling			= 0;

// 2005-09-23 by cmkwon
//	m_mtvectClientIdxForSend.clearLock();
//	m_mtvectClientIdxForExcludeSend.clearLock();

	m_pGiveKillMarkItemPtr2Killer	= NULL;			// 2006-02-09 by cmkwon

	m_nOnlineEachOtherFriendCnts	= 0;			// 2006-07-19 by cmkwon, 서로 등록한 온라인 친구 카운트
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
	m_nKillCount = 0;
	m_nGuildBonusExpRate = 0;
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

	m_mtvectActionInfoAggroList.clearLock();		// 2006-07-21 by cmkwon, Aggro 적용

	m_bazaarManager.ResetBazaarManager();			// 2006-07-26 by cmkwon

	m_bQuestRequestWarp					= FALSE;		// 2006-10-16 by cmkwon
	m_dwLastQuestRequestWarpTick		= 0;			// 2006-10-16 by cmkwon
	m_beforeMapChannIdxQuestRequestWarp	= MAP_CHANNEL_INDEX(0, 0);			// 2006-10-16 by cmkwon

	m_bIsInvisibleCharacter				= FALSE;		// 2006-11-08 by cmkwon

	m_mtvectObersverCharacter.clearLock();		// 2007-03-27 by dhjin

	MEMSET_ZERO(&m_ArenaInfo, sizeof(SARENA_INFO));			// 2007-04-17 by dhjin
	m_ArenaInfo.DeathMatchRoomNum		= -1;
	m_ArenaInfo.TeamNum					= -1;

	m_mtvectSAttackParameterList.clearLock();			// 2007-06-08 by cmkwon
	m_dwSendPlayTimeInfoLastTick		= 0;			// 2007-06-28 by cmkwon, 중국 방심취관련(게임 시간 알림 구현)

	m_bUnlockSecondaryPassword			= FALSE;		// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - 게임 종료시 초기화

	MEMSET_ZERO(&m_giveTargetCharacter, sizeof(m_giveTargetCharacter));	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 
	m_mtvectNotifyMsgList.clearLock();			// 2007-11-28 by cmkwon, 통지시스템 구현 -

	m_mtvectCouponEventList.clearLock();		// 2008-01-17 by cmkwon, S_F: 쿠폰시스템 버그 수정 - 초기화	

	MEMSET_ZERO(&m_AfsNeedMfsInfo, sizeof(SAFS_NEED_MFSINFO));		// 2008-01-03 by dhjin, 아레나 통합 - MFS와 AFS 케릭터 정보 매칭 저장

	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 아래에서 this->SecurityClientClean() 호출로 처리
	//m_Security_bSendCRCReqMsg		= FALSE;							// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 
	//m_hAhnHSClientHandle			= ANTICPX_INVALID_HANDLE_VALUE;		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 

	m_LetterManager.InitLetterManager(this);	// 2008-04-23 by dhjin, EP3 편지 시스템 - 

	m_mtmapBackMapIndex.clearLock();			// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 

	m_dwMSTermSystem	= timeGetTime();		// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	m_pLastSelectedPrefixRareItemInfo		= NULL;		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - // 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
	m_pLastSelectedSuffixRareItemInfo		= NULL;		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - // 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 

	this->SecurityClientClean();				// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 

	m_bMissionMaster	= FALSE;				// 2008-12-09 by dhjin, 미션마스터
	m_VecMissionMasterIOCPSocket.clear();		// 2008-12-22 by dhjin, 미션마스터

	this->CleanPartyMemberList();				// 2008-12-30 by cmkwon, 파티원 Move 처리 시스템 수정 - CFieldIOCPSocket::ResetAllVariables()

	m_mtVecInfiImpute.clearLock();				// 2010-04-05 by cmkwon, 인피 재입장 카드 관련 시스템 수정 - // 2009-09-09 ~ 2010 by dhjin, 인피니티 -  인피니티 귀속 정보
	MEMSET_ZERO(&m_InfinityPlayingInfo, sizeof(INFINITY_PLAYING_INFO));		// 2009-09-09 ~ 2010 by dhjin, 인피니티 -  인피니티 중일때 필요한 정보 저장
	m_InfinityUpdateAllItemCount = 0;		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 종료로 Main서버에서 업데이트 해야될 아이템 수
	
	m_GameStartEXP						= 0;		// 2010-06-01 by shcho, GLogDB 관련 -
	m_StartStayedMapTime.Reset();					// 2010-06-01 by shcho, GLogDB 관련 -

	m_nMapMoveCount = 0;							// 2011-10-10 by hskim, EP4 [트리거 시스템] - 화산재 / 모래 폭풍

	memset(&m_StatisticsInfinityMoney, 0, sizeof(m_StatisticsInfinityMoney));		// 2012-01-16 by hskim, 통계 - 화패

	m_nRestExperienceCount = 0;						// 2012-10-07 by hskim, 휴식 경험치

	m_bProcessingStoreGetItem = FALSE;				// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	m_MemoryHackHistory.Clear();					// 2012-12-14 by hskim, 메모리핵 자동 블럭 기능 구현
	m_SpeedHackHistory.Clear();						// 2013-01-29 by hskim, 스피드핵 자동 블럭 기능 구현

// 2014-03-12 by jekim, 주민번호당 아이템 지급 - 주석처리 함
// 	m_atAccountLastBuyDate.Reset();					// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
// 	m_atCharacterLastBuyDate.Reset();				// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
// end 2014-03-12 by jekim, 주민번호당 아이템 지급

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

//////////////////////////////////////////////////////////////////////
// Property Functions
//////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetCurrentFieldMapChannel(CFieldMapChannel *i_pCurrentFieldMapChannel)
{
	if (i_pCurrentFieldMapChannel == NULL)
	{
		return;
	}

	m_pCurrentFieldMapChannel = i_pCurrentFieldMapChannel;
	m_character.MapChannelIndex = i_pCurrentFieldMapChannel->m_MapChannelIndex;
}

CFieldMapChannel* CFieldIOCPSocket::GetCurrentFieldMapChannel()
{
	return m_pCurrentFieldMapChannel;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			CFieldMapProject * CFieldIOCPSocket::GetCurrentFieldMapProject(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-02 ~ 2005-12-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CFieldMapProject * CFieldIOCPSocket::GetCurrentFieldMapProject(void)
{
	if(NULL == this->GetCurrentFieldMapChannel())
	{
		return NULL;
	}
	return this->GetCurrentFieldMapChannel()->m_pFieldMapProject;
}

CFieldMapChannel* CFieldIOCPSocket::GetFieldMapChannel(MAP_CHANNEL_INDEX *i_pMapChannelIndex, BOOL i_bFindOtherChannel /* = FALSE */, BOOL i_bFindDefaultMapChannel /* = FALSE */)
{
	CFieldMapProject *pFieldMapProject
		= (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(i_pMapChannelIndex->MapIndex);
	if (pFieldMapProject == NULL)
	{
		if (i_bFindDefaultMapChannel)
		{
			return ms_pFieldIOCP->m_pDefaultMapProject->GetRandomFieldMapChannel(TRUE);
		}
		else
		{
			return NULL;
		}
	}

	CFieldMapChannel *pFieldMapChannel
		= pFieldMapProject->GetFieldMapChannelByIndex(i_pMapChannelIndex->ChannelIndex, TRUE);

	if (pFieldMapChannel == NULL)
	{
		if (i_bFindOtherChannel)
		{
			pFieldMapChannel = pFieldMapProject->GetRandomFieldMapChannel(TRUE);
		}

		if (pFieldMapChannel == NULL)
		{
			// All Channel Unavailable
			if (i_bFindDefaultMapChannel)
			{
				return ms_pFieldIOCP->m_pDefaultMapProject->GetRandomFieldMapChannel(TRUE);
			}
			else
			{
				return NULL;
			}
		}
	}

	return pFieldMapChannel;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetSelectableInfluenceMask(BYTE i_byMask)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-07 ~ 2005-12-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetSelectableInfluenceMask(BYTE i_byMask)
{
	if(COMPARE_INFLUENCE(i_byMask, INFLUENCE_TYPE_NORMAL))
	{// 2006-02-08 by cmkwon, 일반세력 일때는 설정하지 않는다 - 운영자, 관리자 명령어('/세력변경')로 세력 변경시만 가능함
		return;
	}
	m_bySelectableInfluenceMask = i_byMask;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BYTE CFieldIOCPSocket::GetSelectableInfluenceMask(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-07 ~ 2005-12-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BYTE CFieldIOCPSocket::GetSelectableInfluenceMask(void)
{
	return m_bySelectableInfluenceMask;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SetAccountInfo(MSG_FP_CONNECT_AUTH_USER_OK *i_pFPAuthUserOK)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-02 ~ 2006-06-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SetAccountInfo(MSG_FP_CONNECT_AUTH_USER_OK *i_pFPAuthUserOK)
{
	m_AccountRegisteredDate	= i_pFPAuthUserOK->AccountRegisteredDate;
	STRNCPY_MEMSET(m_AccountPasswordFromDB, i_pFPAuthUserOK->PasswordFromDB, SIZE_MAX_PASSWORD_MD5_STRING);
	this->GalaNetSetAccountIDNum(i_pFPAuthUserOK->GalaNetAccountIDNum);

	// 2006-11-16 by cmkwon
	m_nGameContinueTimeInSecondOfToday	= i_pFPAuthUserOK->GameContinueTimeInSecondOfToday;	// 2006-11-16 by cmkwon
	m_nGameContinueTimeInSecondOfToday4Viet	= i_pFPAuthUserOK->GameContinueTimeInSecondOfToday;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - 기존값 설정
	m_atimeLastGameEndDate				= i_pFPAuthUserOK->LastGameEndDate;					// 2006-11-16 by cmkwon

	// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 미성년자 관련
	// 2007-06-28 by cmkwon, 중국 방심취관련(출생년월일 FielServer로 가져오기)
	this->SetAdults(i_pFPAuthUserOK->Birthday);

	// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 - PreServer로 부터받은 패스워드를 CFieldIOCPSocket의 멤버 변수에 할 당 한다.
	this->SetSecondaryPassword(i_pFPAuthUserOK->SecondaryPassword);
}


// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
float CFieldIOCPSocket::GetPlusRateExp(INT nInSamePartyCount/*=1*/)
// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
{
	///////////////////////////////////////////////////////////////////////////////
	// 경치 이벤트 가져오기
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetExp = ms_pFieldIOCP->m_gameEventManager.GetExperienceRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetExp = 1.0f + ms_pFieldIOCP->m_gameEventManager.GetExperiencePlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -


// 2006-10-16 by cmkwon, 멤버쉽서비스와 액세사리 아이템 함께 사용 가능
//	///////////////////////////////////////////////////////////////////////////////
//	// 상용화 경치 추가 혹은 액세사리 경치 추가 가져오기
//	if(0.0f >= m_ItemManager.m_cashPremiumCardInfo.fExpRate
//		|| m_ParamFactor.pfm_DROP_EXP > m_ItemManager.m_cashPremiumCardInfo.fExpRate)
//	{// 2006-03-30 by cmkwon, 액세사리 경치 추가
//		return fRetExp + m_ParamFactor.pfm_DROP_EXP;
//	}

	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
#ifdef S_BONUSEXPSYSTEM_RENEWAL

	// 친구 경험치 수정
	fRetExp += min((float)(BONUS_EXP_RATE_FRIEND_COUNT * m_nOnlineEachOtherFriendCnts), BONUS_EXP_RATE_FRIEND_MAX);
	// 여단 경험치 추가
	fRetExp += ((float)m_nGuildBonusExpRate) / 100.0f;
	// 편대 경험치 처리
	fRetExp += CAtumSJ::GetPartyBonusExpWeight(nInSamePartyCount) - 1.0f;


	// 휴식 경험치 관련 추가
	//휴식 경험치 카운트가 있다면.
	if(m_nRestExperienceCount > 0)
	{
		fRetExp += BONUS_EXP_RATE_REST_DEFAULT;
	}
#else
	// 친구 경험치 추가
	fRetExp += 0.005f * m_nOnlineEachOtherFriendCnts;
#endif
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼


	return fRetExp + m_ParamFactor.pfm_DROP_EXP + m_ItemManager.m_cashPremiumCardInfo.fExpRate;
}
float CFieldIOCPSocket::GetPlusRateSPI(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 스피 이벤트 가져오기
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetSPI = ms_pFieldIOCP->m_gameEventManager.GetSPIRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetSPI = 1.0f + ms_pFieldIOCP->m_gameEventManager.GetSPIPlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

// 2006-10-16 by cmkwon, 멤버쉽서비스와 액세사리 아이템 함께 사용 가능
//	///////////////////////////////////////////////////////////////////////////////
//	// 상용화 경치 추가 혹은 액세사리 경치 추가 가져오기
//	if(0.0f >= m_ItemManager.m_cashPremiumCardInfo.fSPIRate
//		|| m_ParamFactor.pfm_DROP_SPI > m_ItemManager.m_cashPremiumCardInfo.fSPIRate)
//	{// 2006-03-30 by cmkwon, 액세사리 경치 추가
//		return fRetSPI + m_ParamFactor.pfm_DROP_SPI;
//	}

	return fRetSPI + m_ParamFactor.pfm_DROP_SPI + m_ItemManager.m_cashPremiumCardInfo.fSPIRate;
}
float CFieldIOCPSocket::GetPlusRateDropItem(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 아이템레어드랍 이벤트 가져오기
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetDropRate = ms_pFieldIOCP->m_gameEventManager.GetDropItemRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetDropRate = 1.0f + ms_pFieldIOCP->m_gameEventManager.GetDropItemPlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

// 2006-10-16 by cmkwon, 멤버쉽서비스와 액세사리 아이템 함께 사용 가능
//	///////////////////////////////////////////////////////////////////////////////
//	// 상용화 DropItem 추가 혹은 액세사리 드랍아이템 추가 가져오기
//	if(0.0f >= m_ItemManager.m_cashPremiumCardInfo.fDropRate
//		|| m_ParamFactor.pfm_DROP_ITEM > m_ItemManager.m_cashPremiumCardInfo.fDropRate)
//	{// 2006-03-30 by cmkwon, 액세사리 경치 추가
//		return fRetDropRate + m_ParamFactor.pfm_DROP_ITEM;
//	}

	return fRetDropRate + m_ParamFactor.pfm_DROP_ITEM + m_ItemManager.m_cashPremiumCardInfo.fDropRate;
}

float CFieldIOCPSocket::GetPlusRateDropRareItem(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 아이템레어드랍 이벤트 가져오기
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetDropRareRate = ms_pFieldIOCP->m_gameEventManager.GetDropRareItemRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetDropRareRate = 1.0f + ms_pFieldIOCP->m_gameEventManager.GetDropRareItemPlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

	///////////////////////////////////////////////////////////////////////////////
	// 상용화 DropRareItem 추가 가져오기	
	
	// 238,2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
	//return fRetDropRareRate+ m_ItemManager.m_cashPremiumCardInfo.fDropRareRate;
	DbgOut("Default_rareItemDrop = [%f]\r\n",fRetDropRareRate + m_ItemManager.m_cashPremiumCardInfo.fDropRareRate);	
	DbgOut("rareItemDrop = [%f]\r\n",fRetDropRareRate + m_ParamFactor.pfm_DP_REPAIR_RATE + m_ItemManager.m_cashPremiumCardInfo.fDropRareRate);	
	return fRetDropRareRate+ m_ParamFactor.pfm_DP_REPAIR_RATE + m_ItemManager.m_cashPremiumCardInfo.fDropRareRate;
}

float CFieldIOCPSocket::GetPlusRateExpRepair(void)
{
	///////////////////////////////////////////////////////////////////////////////
	// 경험치 복구 이벤트 가져오기
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetExpRepairRate = ms_pFieldIOCP->m_gameEventManager.GetExpRepairRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetExpRepairRate = ms_pFieldIOCP->m_gameEventManager.GetExpRepairPlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

	///////////////////////////////////////////////////////////////////////////////
	// 상용화 DropItem 추가 가져오기	
	return min(1.0f, fRetExpRepairRate+m_ItemManager.m_cashPremiumCardInfo.fExpRepairRate);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::GetHPRepairTimeSubtractRate(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-20 ~ 2006-04-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::GetHPRepairTimeSubtractRate(void)
{
	return ms_pFieldIOCP->m_InflWarManager.GetHPRepairAddRateByInflTy(m_character.InfluenceType);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::GetHPRepairRateFlighting(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-30 ~ 2006-03-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::GetHPRepairRateFlighting(void)
{
	float fInflRate = ms_pFieldIOCP->m_InflWarManager.GetHPRepairAddRateByInflTy(m_character.InfluenceType);
	if(0.0f >= fInflRate)
	{
		return m_ParamFactor.pfm_HP_REPAIR_RATE_FLIGHTING;
	}
	
	return m_ParamFactor.pfm_HP_REPAIR_RATE_FLIGHTING + fInflRate;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::GetDPRepairTimeSubtractRate(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-30 ~ 2006-03-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::GetDPRepairTimeSubtractRate(void)
{
	float fInflRate = ms_pFieldIOCP->m_InflWarManager.GetDPRepairAddRateByInflTy(m_character.InfluenceType);
	if(0.0f >= fInflRate)
	{
		return m_ParamFactor.pfm_DP_REPAIR_RATE;
	}

	return m_ParamFactor.pfm_DP_REPAIR_RATE + fInflRate;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::GetSPRepairTimeSubtractRate(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-30 ~ 2006-03-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::GetSPRepairTimeSubtractRate(void)
{
	float fInflRate = ms_pFieldIOCP->m_InflWarManager.GetSPRepairAddRateByInflTy(m_character.InfluenceType);
	if(0.0f >= fInflRate)
	{
		return m_ParamFactor.pfm_SP_REPAIR_RATE;
	}
	return m_ParamFactor.pfm_SP_REPAIR_RATE+fInflRate;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::GetPlusWarPointRate(void)
/// \brief		워포인트 이벤트로 워포인트 증가량
/// \author		dhjin
/// \date		2007-06-26 ~ 2007-06-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::GetPlusWarPointRate(void)
{
// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - 아래와 같이 함수가 수정됨
//	float fRetWP = ms_pFieldIOCP->m_gameEventManager.GetWarPointRate(m_character.InfluenceType, m_bIsPCBangClient);
	float fRetWP = 1.0f + ms_pFieldIOCP->m_gameEventManager.GetWarPointPlusRate(m_character.InfluenceType, m_bIsPCBangClient, m_character.Level, m_character.MapChannelIndex.MapIndex);	// 2012-06-16 by hskim, [트리거 시스템] - 크리스탈 시스템 2차 : 특정 맵에서만 해피아워 이벤트 적용 - // 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

#ifdef	SC_UNBALANCED_FORCES_ADJUST_RATIO		// 2014-06-17 by bckim, 세력 불균형 ( 역전의 기회 WP획득량,몬스터 공격력확률,몬스터공격력)
	float tmBuffPenalty = 0.0f;
	float tmBuffPercent	= 0.0f;
	// 전투력 최소 15.0f;			// 전투력 최대 30.0f;		// 워포 지급비율 최소 30%		// 워포 지급비율 최소 100%*/
	ms_pFieldIOCP->m_InflWarManager.GetPVPBuffPercent( m_character.InfluenceType,&tmBuffPenalty);
	tmBuffPercent = TURN_AROUND_BUFF_SKILL_100P_VALUE*tmBuffPenalty;	
	//if( 15.0f <= tmBuffPercent )		// 15% 이상이면,					// 2014-08-25 by bckim, 세력불균형 지급비율 버그수정 
	tmBuffPercent = abs(tmBuffPercent);
	if( 0.0f < tmBuffPercent )	
	{
		//fRetWP += ( 0.3f + 0.7f*(tmBuffPercent/15.0f - 1.0f) );
		fRetWP += min((0.3f + 0.7f*( (tmBuffPercent-1.0f)/15.0f)), 1.0f) ;	// 2014-08-25 by bckim, 세력불균형 지급비율 버그수정 
	}	
#endif	// 2014-06-17 by bckim, 세력 불균형 ( 역전의 기회 WP획득량,몬스터 공격력확률,몬스터공격력)


	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-18 by cmkwon, WarPoint 증가 아이템 구현(일본요청) - 
	if(0.0001f < m_ParamFactor.pfm_PLUS_WARPOINT_RATE)
	{
		fRetWP	+= m_ParamFactor.pfm_PLUS_WARPOINT_RATE;

		// 2010-05-19 by cmkwon, 이 아이템은 한번 사용되고 삭제되어야 한다.
		this->m_ItemManager.DeleteUsingTimeLimitedItemListByDestParameter(DES_PLUS_WARPOINT_RATE);
	}

	return fRetWP;
}

// 2006-08-21 by cmkwon, BOOL i_bCheckValidGameUser=TRUE 추가함
// 2007-03-06 by cmkwon, 리턴값 추가(경험치 변화량을 리턴한다)
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
Experience_t CFieldIOCPSocket::ChangeExperience(Experience_t fChangeValue, BOOL i_bApplyPartner /*=FALSE*/, BOOL i_bApplyPlusRate/*=TRUE*/, BOOL i_bCheckValidGameUser/*=TRUE*/, INT nInSamePartyMember/*=1*/, CFieldMonster* pTargetMonster/*=NULL*/) // 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
{
	BOOL bSendHappyHourEventInfo = FALSE;	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 

	// 2015-08-11 by jwlee 만렙 확장으로 인해 얻을 수 있는 경험치 제한 10억으로 변경 
	// start 2012-01-16 by hskim, EP4 - 경험치 버그 예방 : 3억 이상이면 경험치 못먹도록 방지
	// if( fChangeValue >= 300000000 )
	if( fChangeValue >= 1000000000 )
	// end 2015-08-11 by jwlee 만렙 확장으로 인해 얻을 수 있는 경험치 제한 10억으로 변경 
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL ERROR: Invalid Experience, %s %lf\r\n", GetCharacterString(&m_character, string()), fChangeValue);
		return 0.0;
	}
	// end 2012-01-16 by hskim, EP4 - 경험치 버그 예방 : 3억 이상이면 경험치 못먹도록 방지

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-06-14 by cmkwon
//	if(i_bCheckValidGameUser
//		&& FALSE == this->IsValidGameUser())
//	{// 2006-06-14 by cmkwon, 베트남 정액제 체크 - 경험치
//		return;
//	}

	///////////////////////////////////////////////////////////////////////////////
	// 경험치 추가 Rate를 구한다
	if(i_bApplyPlusRate)
	{
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
		//fChangeValue = fChangeValue * (this->GetPlusRateExp() + 0.005f * m_nOnlineEachOtherFriendCnts); //  GetPlusRateExp() 함수내에서 적용하게끔 수정
		fChangeValue = fChangeValue * (this->GetPlusRateExp(nInSamePartyMember));
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
		
	}
	
///////////////////////////////////////////////////////////////////////////////
// 2007-06-14 by cmkwon, 게임 지속 시간 제한 기본 시스템으로 수정 - 아래와 같이 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-11-16 by cmkwon, 베트남에 하루에 3시간 이상 게임하면 경험치 50%감소, 5시간 이상이면 경험치 습득 없음(퀘스트 제외)
//	if(i_bCheckValidGameUser
//		&& LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType())
//	{// 2006-11-16 by cmkwon, 베트남만 처리된다
//
//		int nGameContinueTimeOfToday = this->GetCurGameContinueTimeInSecondOfToday();
//		if(nGameContinueTimeOfToday > TERM_GAME_PLAYTIME_LIMIT_LAST_SEC)
//		{// 2006-11-23 by cmkwon, 경험치/SPI 습득 없음
//			return 0;
//		}
//		if(nGameContinueTimeOfToday > TERM_GAME_PLAYTIME_LIMIT_FIRST_SEC)
//		{// 2006-11-23 by cmkwon, 경험치/SPI 습득 50%
//			fChangeValue	/= 2;
//		}
//	}
	if(i_bCheckValidGameUser)
	{
		float	fApplyRate		= 0.0f;
		BOOL	bRestriction	= this->GPGetApplyRateByGamePlayingTime(&fApplyRate);
		if(bRestriction)
		{
			if(0.0f >= fApplyRate)
			{
				return 0;
			}
			fChangeValue	*= fApplyRate;
		}
	}

	EnterCriticalSection(&m_criticalLevelAndExperience);

	/////////////////////////////////////////////////////////////
	// start 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현
	Experience_t PetExperience = 0;

#ifdef SC_GROWING_PARTNER_HSKIM_JHAHN		// 파트너 시스템 2차 컨텐츠 활성화 여부 확인
	ITEM *pItem = GetAttachedItem(POS_PET);

	if( i_bApplyPartner == TRUE && pItem != NULL && pItem->ItemNum != 0 )
	{
		if( NULL != pItem->ItemNum)
		{
			UID64_t	 UniqueNumber = ((ITEM_GENERAL *)pItem->ItemNum)->UniqueNumber;

			tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(UniqueNumber);

			if( NULL != pPetInfo && 0 != pPetInfo->PetExpRatio )
			{
				PetExperience = (INT64)(fChangeValue * pPetInfo->PetExpRatio / 100.0);		// 소수점은 자르기

				if( TRUE == PetChangeExperience(PetExperience) )
				{
				fChangeValue = fChangeValue - PetExperience;
			    }
		    }
	    }
	}
#endif
	// end 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현
	//////////////////////////////////////////////////////////////

	// start 2011-11-15 by hskim, EP4 [트리거 시스템] - 버닝맵 경험치 추가
#ifdef S_EP4_HSKIM		// ON/OFF 기능 구현
	if(i_bApplyPlusRate)
	{
		BURNING_MAP_INFO * pBurningMapInfo = this->ms_pFieldIOCP->GetBurningMapInfo(this->m_character.MapChannelIndex.MapIndex);

		if(NULL != pBurningMapInfo)
		{
			fChangeValue = fChangeValue * (CAtumSJ::GetBurningMapAddExperience(this->m_character.Level) / 100.0f);
		}
	}
#endif
	// end 2011-11-15 by hskim, EP4 [트리거 시스템] - 버닝맵 경험치 추가

	if(m_character.Level >= CHARACTER_MAX_LEVEL)
	{// 2006-04-10 by cmkwon, 최대레벨에서는 더이상 경험치 증가는 없다
		m_character.Level		= CHARACTER_MAX_LEVEL;
		m_character.Experience	= CAtumSJ::GetInitialExperienceOfLevel(CHARACTER_MAX_LEVEL);

		LeaveCriticalSection(&m_criticalLevelAndExperience);		// 2006-04-12 by cmkwon, 수정함
		return 0;
	}

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-06-14 by cmkwon
//	Experience_t tmMaxExp = 0.0f;
//	if(FALSE == this->IsValidGameUser(&tmMaxExp, m_character.Experience+fChangeValue))
//	{// 2006-06-14 by cmkwon, 베트남 정액제 체크 - 경험치
//		fChangeValue			= tmMaxExp - m_character.Experience;
//		m_character.Experience	= tmMaxExp;
//	}
	
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
#ifdef S_BONUSEXPSYSTEM_RENEWAL
	if(fChangeValue >= 0.0f && i_bApplyPlusRate)
	{
		// 경험치가 들어왔다면, 휴식경험치 카운트와 킬카운트를 수정후 전송

		// 2014-12-05 by bckim, 이벤트맵에서는 킬카운트 반영하지 않음.
		CFieldMapProject *pFMPro = this->GetCurrentFieldMapProject();
		if ( NULL != pFMPro && FALSE == IS_MAP_INFLUENCE_EVENT_AREA(pFMPro->m_nMapInfluenceType) )
		{
		m_nRestExperienceCount--;	
		}
		// End. 2014-12-05 by bckim, 이벤트맵에서는 킬카운트 반영하지 않음.

		m_nRestExperienceCount = max(m_nRestExperienceCount,0);

		// 2012-10-19 by jhjang 해피아워 경험치 리뉴얼 - 킬카운트 300일때 바로 지급하게 수정
		if(RefreshKillCount(pTargetMonster))
		{
			SendToClient_RestCount();
		}
		// end 2012-10-19 by jhjang 해피아워 경험치 리뉴얼 - 킬카운트 300일때 바로 지급하게 수정
	}
#endif //S_BONUSEXPSYSTEM_RENEWAL
	// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

	m_character.Experience += fChangeValue;		// 2011-11-15 by hskim, EP4 [트리거 시스템] - 버닝맵 경험치 추가 (파트너에서 변경했던 코드 원래 코드로 변경)

	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
// 2006-05-20 by cmkwon, 경험치로그는 저장하지 않는다, 다운경험치로그만 저장한다.
	CAtumLogSender::SendLogMessageEXP(this, fChangeValue, m_character.Experience);	// Send Log
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기

	if (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1) <= m_character.Experience)
	{	// Level Up

// 2007-01-15 by cmkwon, StoreExperienceDelayStore()함수에서 시스렘로그에 남기는 부분 추가함
//		///////////////////////////////////////////////////////////////////////////////
		// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
		// 2006-05-24 by cmkwon, 렙업시에만 경험치로그 저장
		CAtumLogSender::SendLogMessageEXP(this, fChangeValue, m_character.Experience);	// Send Log
#endif	//#ifdef S_FULL_LOG_JHSEOL
		// end 2012-08-30 by jhseol, 풀로그 남기기

		m_character.Level++;
		ChangeHP(GetCharacterTotalHP());
// 2006-04-04 by cmkwon, ChangeHP()함수 내에서 처리되고 있음
//		SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
// 2007-01-29 by cmkwon, 레벨업시에 잘리는 경험치 없다록 하기 우해서 아래와 같이 수정함, 최대경험치는 올라간레벨의 99%임
//		m_character.Experience = CAtumSJ::GetInitialExperienceOfLevel(m_character.Level);
		m_character.Experience = min(m_character.Experience, CAtumSJ::GetInitialExperienceOfLevel(m_character.Level) + 0.99f * (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1)-CAtumSJ::GetInitialExperienceOfLevel(m_character.Level)));
		CAtumLogSender::SendLogMessageLEVEL(this, m_character.Level-1, m_character.Level);	// Send Log
		if(m_character.MaxLevel < m_character.Level)
		{
			m_character.MaxLevel = m_character.Level;
		}
		// 2005-09-29 by cmkwon, 수정됨
		m_character.BonusStat += BONUS_STAT_PER_A_LEVEL;
		CAtumLogSender::SendLogMessageSTAT(this, STAT_BONUS, m_character.BonusStat);	// Send Log

		// 만피시켜주기
		m_character.CurrentHP = this->GetCharacterTotalHP();
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);

		QPARAM_CHARACTER_CHANGE_LEVEL *pQChangeLevel = new QPARAM_CHARACTER_CHANGE_LEVEL;
		pQChangeLevel->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQChangeLevel->Level					= m_character.Level;
		pQChangeLevel->BonusStat				= m_character.BonusStat;
// 2005-11-15 by cmkwon, 삭제함
//		pQChangeLevel->BonusSkillPoint			= 0;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeLevel, this, m_character.AccountUniqueNumber, pQChangeLevel);

		SendCharacterInfo(T_FC_CHARACTER_CHANGE_LEVEL);

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
//		///////////////////////////////////////////////////////////////////////////////
//		// 자동 스탯 분배 - 처리 필요없으면 그냥 리턴
//		this->DistributeBonusStatByAutoStatType();

		// update db
		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);

		this->SendString128(STRING_128_DEBUG_L1, "Level %5.0f : level up", this->m_character.Level);

		// 2006-02-09 by cmkwon, 자신이 타세력에 의해 죽을 경우 줘야 할 킬마크 설정
		this->ResetGiveKillMarkItemPtr2Killer();

// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 아래에 CFieldIOCP::SendGameEventMessage() 함수로 처리함
// 		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 - 레벨에 따른 해피아워로 유저에게 정보 전송한다.
// 		ms_pFieldIOCP->m_pHappyHourEventManager->SendHappyHourEventInfoByLevel(this, this->m_character.InfluenceType);
		bSendHappyHourEventInfo		= TRUE;		// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 아래에서 처리 하기 위해 플래그 처리함

		this->StoreExperienceDelayStore();					// 2006-05-21 by cmkwon, 렙업시에 경험치도 저장

		//////////////////////////////////////////////////////////////////////////
		// 2007-07-20 by dhjin, ITEM_EVENT_TYPE_NEWMEMBER_LEVELUP 이벤트 아이템 체크 
		vectItemEventInfo		vectItemEventInfo1;
// 2008-02-01 by cmkwon, ItemEvent 에 LastGameEndDate 체크 루틴 추가 - 
//		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemLevelUp(&vectItemEventInfo1, &m_AccountRegisteredDate, m_character.Level, m_character.UnitKind);
		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemLevelUp(&vectItemEventInfo1, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, m_character.InfluenceType,\
			m_character.UnitKind, &m_AccountRegisteredDate, m_character.Level, 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, 아이템 이벤트 - 서브타입 추가구조로 변경

			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	= m_character.CharacterUniqueNumber; // 2014-03-12 by jekim, 주민번호당 아이템 지급	// 2009-11-19 by cmkwon, 아이템 이벤트에 Account/Character 체크 기능 추가 - 
			pQParam->CheckWithCharacterUID = vectItemEventInfo1[i].CheckWithCharacterUID; // 2014-03-12 by jekim, 주민번호당 아이템 지급
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckEventItem, this, m_character.AccountUniqueNumber, pQParam);
		}
	}

// 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);
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_EXP);

	LeaveCriticalSection(&m_criticalLevelAndExperience);

	///////////////////////////////////////////////////////////////////////////////
	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 
	if(bSendHappyHourEventInfo)
	{
		ms_pFieldIOCP->SendGameEventMessage(this, GetCharacter()->InfluenceType, T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO_BY_LEVEL);
	}

	// 2011-01-20 by shcho, 버닝맵 - 내부에서 레벨업시 안튕기는 버그 수정 
	if(TRUE == IsGetOutBurningMap(this->m_character.MapChannelIndex.MapIndex)) 
	{
		this->WarpToCityMap();	// 마을로 모시겠슴둥
	}
	// end 2011-01-20 by shcho, 버닝맵 - 내부에서 레벨업시 안튕기는 버그 수정

	return fChangeValue;		// 2007-03-06 by cmkwon, 경험치 변화량을 리턴
}

void CFieldIOCPSocket::ChangeLevel(int nLevelChangeValue, int nPercentageOfExp)
{
	if(CHARACTER_MAX_LEVEL <= m_character.Level+nLevelChangeValue)
	{
		nLevelChangeValue	= CHARACTER_MAX_LEVEL - m_character.Level;
		nPercentageOfExp	= 0;
	}
	EnterCriticalSection(&m_criticalLevelAndExperience);
	// change level and send
	m_character.Level += nLevelChangeValue;
	ChangeHP(GetCharacterTotalHP());
// 2006-04-04 by cmkwon, ChangeHP()함수 내에서 처리되고 있음
//	SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
	m_character.CurrentHP = this->GetCharacterTotalHP();		// 만피 시켜주기
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
	// 변수 오류 수정
	if (nPercentageOfExp < 0) nPercentageOfExp = 0;
	else if (nPercentageOfExp > 99) nPercentageOfExp = 99;
	m_character.Experience = CAtumSJ::GetInitialExperienceOfLevel(m_character.Level)
		+ ((float)nPercentageOfExp/100.0f)*(CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1) - CAtumSJ::GetInitialExperienceOfLevel(m_character.Level));
	// 2005-09-29 by cmkwon, 수정됨
	m_character.BonusStat += max(0, nLevelChangeValue*BONUS_STAT_PER_A_LEVEL);	// 보너스 stat 조절

	CAtumLogSender::SendLogMessageLEVEL(this, m_character.Level-1, m_character.Level);	// Send Log

	QPARAM_CHARACTER_CHANGE_LEVEL *pQChangeLevel = new QPARAM_CHARACTER_CHANGE_LEVEL;
	pQChangeLevel->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	pQChangeLevel->Level = m_character.Level;
	pQChangeLevel->BonusStat = m_character.BonusStat;
// 2005-11-15 by cmkwon, 삭제함
//	pQChangeLevel->BonusSkillPoint = 0;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeLevel, this, m_character.AccountUniqueNumber, pQChangeLevel);
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_LEVEL);

	StoreExperienceDelayStore();
// 2007-01-15 by cmkwon, StoreExperienceDelayStore()함수로 변경
//	// change exp and send
//	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);

	m_character.AutoStatType			= AUTOSTAT_TYPE_FREESTYLE;

	// update db
	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);

	// 레벨에 맞지 않는 퀘스트 제거
	m_mapQuest.lock();
	mtmapQuestIndex2FieldCharacterQuest::iterator itrQuest = m_mapQuest.begin();
	while (itrQuest != m_mapQuest.end())
	{
		CFieldCharacterQuest *pFCharacterQuest = &itrQuest->second;
		if (pFCharacterQuest->QuestState == QUEST_STATE_IN_PROGRESS)
		{
			CQuest *pQuestInfo = ms_pFieldIOCP->m_mapQuestInfoFromScript.findEZ(pFCharacterQuest->QuestIndex);
			if (pQuestInfo != NULL && !IS_IN_RANGE(pQuestInfo->ReqLevel.Min, m_character.Level, pQuestInfo->ReqLevel.Max))
			{
				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++;
	}
	m_mapQuest.unlock();

	LeaveCriticalSection(&m_criticalLevelAndExperience);

	// 2006-02-09 by cmkwon, 자신이 타세력에 의해 죽을 경우 줘야 할 킬마크 설정
	this->ResetGiveKillMarkItemPtr2Killer();

// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 아래와 같이 CFieldIOCP::SendGameEventMessage() 로 처리 함
// 	// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 - 레벨에 따른 해피아워로 유저에게 정보 전송한다.
// 	ms_pFieldIOCP->m_pHappyHourEventManager->SendHappyHourEventInfoByLevel(this, this->m_character.InfluenceType);
	ms_pFieldIOCP->SendGameEventMessage(this, GetCharacter()->InfluenceType, T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO_BY_LEVEL);	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 

	// 2011-01-20 by shcho, 버닝맵 - 내부에서 레벨업시 안튕기는 버그 수정 
	if(TRUE == IsGetOutBurningMap(this->m_character.MapChannelIndex.MapIndex)) 
	{
		this->WarpToCityMap();	// 마을로 모시겠슴둥
	}
    // end 2011-01-20 by shcho, 버닝맵 - 내부에서 레벨업시 안튕기는 버그 수정 
}

void CFieldIOCPSocket::CheckAndUpdateStatus()
{
	if(NULL == m_pCurrentFieldMapChannel){					return;}

	if(STATUS_SILVER_CLASS_GENERAL == m_character.Status)
	{// 2006-01-02 by cmkwon, 매달 최고 여단 명성 여단의 여단장에게 주어지는 계급, 서버 정기 점검 시간에 처리한다.
		return;
	}

	BYTE nNewStatus = CAtumSJ::GetStatusByPropensity(m_character.Propensity);
	if (nNewStatus != m_character.Status)
	{
		m_character.Status = nNewStatus;

		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_STATUS, T_FC_CHARACTER_CHANGE_STATUS, pMsgChangeStatus, pMsgChangeStatusBuf);
		pMsgChangeStatus->ClientIndex	= m_character.ClientIndex;
		pMsgChangeStatus->Status		= nNewStatus;
		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pMsgChangeStatusBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_STATUS)
			, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

		QPARAM_CHARACTER_CHANGE_STATUS *pQChangeStatus = new QPARAM_CHARACTER_CHANGE_STATUS;
		pQChangeStatus->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQChangeStatus->Status					= m_character.Status;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeStatus, this, m_character.AccountUniqueNumber, pQChangeStatus);
	}
} 
void CFieldIOCPSocket::ChangeHP(USHORT i_nHP)
{
	if(m_character.HP == i_nHP){			return;}
	m_character.HP = i_nHP;

	BOOL bSendCurrentHP = FALSE;
	if (m_character.CurrentHP > m_character.HP)
	{// CurrentHP 보정

		m_character.CurrentHP	= m_character.HP;
		bSendCurrentHP			= TRUE;
	}

	// HP 회복 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);

	// Send MSG
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
	if(bSendCurrentHP)
	{
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
	}

// 2005-03-07 by cmkwon, DB에 저장할 필요없음
//	// 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);
}

void CFieldIOCPSocket::ChangeDP(USHORT i_nDP)
{
	if(m_character.DP == i_nDP){			return;}
	m_character.DP = i_nDP;

	BOOL bSendCurrentDP = FALSE;
	if (m_character.CurrentDP > m_character.DP)
	{// CurrentDP 보정
		m_character.CurrentDP	= m_character.DP;
		bSendCurrentDP			= TRUE;
	}

	// DP 회복 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);

	// Send MSG
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
	if(bSendCurrentDP)
	{
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
	}
// 2005-03-07 by cmkwon, DB에 저장할 필요없음
//	// 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);
}

void CFieldIOCPSocket::ChangeSP(USHORT i_nSP, BOOL i_bStore2DB/*=FALSE*/)
{
	if(m_character.SP == i_nSP){			return;}

	m_character.SP = i_nSP;

	BOOL bSendCurrentSP = FALSE;
	if (m_character.CurrentSP > m_character.SP)
	{// CurrentSP 보정
		m_character.CurrentSP	= m_character.SP;
		bSendCurrentSP			= TRUE;
	}

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

	// Send MSG
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
	if(bSendCurrentSP)
	{
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTSP);
	}
// 2005-03-07 by cmkwon, DB에 저장할 필요없음
// 	if(i_bStore2DB)
// 	{
// 		// 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);
// 	}
}

void CFieldIOCPSocket::ChangeEP(USHORT i_nEP, BOOL i_bStore2DB/*=FALSE*/)
{
	if(m_character.EP == i_nEP){			return;}

	m_character.EP = i_nEP;
	
	BOOL bSendCurrentEP = FALSE;
	if (m_character.CurrentEP > m_character.EP)
	{// CurrentEP 보정
		m_character.CurrentEP	= m_character.EP;
		bSendCurrentEP			= TRUE;
	}

	// Send MSG
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
	if(bSendCurrentEP)
	{
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTEP);
	}
// 2005-03-07 by cmkwon, DB에 저장할 필요없음
//	if(i_bStore2DB)
//	{
//		// 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);
//	}
}

USHORT CFieldIOCPSocket::GetCharacterTotalHP(void)
{
	USHORT usRetHP = CAtumSJ::GetCharacterHP(m_character.Level);

// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템	
// 	if (m_ItemCenter.ItemNum != 0 
// 		&& m_ItemCenter.Kind == ITEMKIND_DEFENSE)
// 	{// 아머 장착 시
// 
// // 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정 함.
// // 		if(m_ItemCenter.DestParameter1 == DES_HP)
// // 		{
// // 			usRetHP += (USHORT)m_ItemCenter.ParameterValue1;
// // 		}
// 		if(DES_HP == m_ItemCenter.ArrDestParameter[0])
// 		{
// 			usRetHP += (USHORT)m_ItemCenter.ArrParameterValue[0];
// 		}
// 
// 		usRetHP += GetEnchantValue(&m_ItemCenter, DES_HP);
// 	}
// 
// // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 아래와 같이 GetParamValue_POS_ATTACHMENT() 함수로 처리
// //	if(0 != m_ItemAttachment.ItemNum
// //		&& ITEMKIND_ACCESSORY_UNLIMITED == m_ItemAttachment.Kind
// //		&& DES_HP == m_ItemAttachment.DestParameter1)
// //	{// 2006-04-04 by cmkwon, 무제한 액세서리 아이템 처리
// //		usRetHP += (USHORT)m_ItemAttachment.ParameterValue1;
// //	}
// 	usRetHP += this->GetParamValue_POS_ATTACHMENT(DES_HP);
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	usRetHP += m_ParamFactor.pfp_HP;

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
	//	return usRetHP + m_nPlusHP;
	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)
		///////////////////////////////////////////////////////////////////////////////////////////////////
		/// start 2012-05-18 by jhseol, 리비전적용 - 기존엔 플레이 중에만 적용하도록 되있었음. 이것을 시작할때도 적용되도록 수정함.
		&& (TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState) || INFINITY_STATE_ENTERING == this->m_InfinityPlayingInfo.InfinityState)
		/// end 2012-05-18 by jhseol, 리비전적용 - 기존엔 플레이 중에만 적용하도록 되있었음. 이것을 시작할때도 적용되도록 수정함.
		///////////////////////////////////////////////////////////////////////////////////////////////////
		// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		&& usRetHP + m_nPlusHP < this->m_InfinityPlayingInfo.RevisionHP) {
		// 아레나 서버에서 인피니티 중이라면 HP 최소 보정
		return this->m_InfinityPlayingInfo.RevisionHP;
	}
	
	return usRetHP + m_nPlusHP;
}

USHORT CFieldIOCPSocket::GetCharacterTotalDP(void)
{
	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	USHORT usRetDP =  CAtumSJ::GetCharacterDP(m_character.TotalGearStat.ShieldPart, m_character.Level);

// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템		
// 	if (m_ItemCenter.ItemNum != 0 
// 		&& m_ItemCenter.Kind == ITEMKIND_DEFENSE)
// 	{// 아머 장착 시
// 
// 		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 		//if(m_ItemCenter.DestParameter2 == DES_DP)
// 		//{
// 		//	usRetDP += (USHORT)m_ItemCenter.ParameterValue2;
// 		//}
// 		if(m_ItemCenter.ArrDestParameter[1] == DES_DP)
// 		{
// 			usRetDP += (USHORT)m_ItemCenter.ArrParameterValue[1];
// 		}
// 
// 		usRetDP += GetEnchantValue(&m_ItemCenter, DES_DP);
// 	}
// 
// // 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 아래와 같이 GetParamValue_POS_ATTACHMENT() 함수로 처리
// //	if(0 != m_ItemAttachment.ItemNum
// //		&& ITEMKIND_ACCESSORY_UNLIMITED == m_ItemAttachment.Kind
// //		&& DES_DP == m_ItemAttachment.DestParameter1)
// //	{// 2006-04-04 by cmkwon, 무제한 액세서리 아이템 처리
// //		usRetDP += (USHORT)m_ItemAttachment.ParameterValue1;
// //	}
// 	usRetDP += this->GetParamValue_POS_ATTACHMENT(DES_DP);
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	usRetDP += m_ParamFactor.pfp_DP;

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
//	return usRetDP + m_nPlusDP;
	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)
		///////////////////////////////////////////////////////////////////////////////////////////////////
		/// start 2012-05-18 by jhseol, 리비전적용 - 기존엔 플레이 중에만 적용하도록 되있었음. 이것을 시작할때도 적용되도록 수정함.
		&& (TRUE == IS_INFINITY_STATE_PLAYING(this->m_InfinityPlayingInfo.InfinityState) || INFINITY_STATE_ENTERING == this->m_InfinityPlayingInfo.InfinityState)
		/// end 2012-05-18 by jhseol, 리비전적용 - 기존엔 플레이 중에만 적용하도록 되있었음. 이것을 시작할때도 적용되도록 수정함.
		///////////////////////////////////////////////////////////////////////////////////////////////////
		// end 2011-04-08 by hskim, 인피니티 3차 - 시네마 단계별 기능 구현
		&& (usRetDP + m_nPlusDP) < this->m_InfinityPlayingInfo.RevisionDP) {
		// 아레나 서버에서 인피니티 중이라면 DP 최소 보정
		return this->m_InfinityPlayingInfo.RevisionDP;
	}
	
	return usRetDP + m_nPlusDP;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			USHORT CFieldIOCPSocket::GetCharacterTotalEP(void)
/// \brief		현재 캐릭터의 Total EP를 구한다.
/// \author		cmkwon
/// \date		2006-04-04 ~ 2006-04-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
USHORT CFieldIOCPSocket::GetCharacterTotalEP(void)
{
	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	SHORT nTmpEp = CAtumSJ::GetCharacterEP(m_character.TotalGearStat.FuelPart, m_character.Level);

// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 아래와 같이 GetParamValue_POS_ATTACHMENT() 함수로 처리
//	if(0 != m_ItemAttachment.ItemNum
//		&& ITEMKIND_ACCESSORY_UNLIMITED == m_ItemAttachment.Kind
//		&& DES_EP == m_ItemAttachment.DestParameter1)
//	{// 2006-04-04 by cmkwon, 무제한 액세서리 아이템 처리
//		nTmpEp += (USHORT)m_ItemAttachment.ParameterValue1;
//	}
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
//	nTmpEp += this->GetParamValue_POS_ATTACHMENT(DES_EP);
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	nTmpEp += m_ParamFactor.pfp_EP;

	return nTmpEp;
}

// 2010-08-26 by shcho&jsKim, 밤 아이템 구현
USHORT CFieldIOCPSocket::GetCharacterTotalSP(void)
{
	SHORT ntmpSp = CAtumSJ::GetCharacterSP(m_character.TotalGearStat.SoulPart, m_character.Level);
	ntmpSp += m_ParamFactor.pfp_SP;
	
	return ntmpSp;
}
// END 2010-08-26 by shcho&jsKim, 밤 아이템 구현

// m_character.HP를 i_fChangeValHP에 할당하면 만피임
// 2006-07-21 by cmkwon, 인자 추가 - ClientIndex_t i_SkillUseClientIdx
void CFieldIOCPSocket::ChangeCurrentHP(float i_fChangeValHP, BYTE i_nDamageType/*= DAMAGE_BY_NA*/, ClientIndex_t i_SkillUseClientIdx/*=0*/)
{
	if (i_fChangeValHP == 0.0f){				return;}
	
	float fOldCurHP = m_character.CurrentHP;
	if (i_fChangeValHP > 0.0f)
	{
		// 2010-12-21 by jskim, HP, DP 키트 적용량 증가 아이템 구현
		//m_character.CurrentHP = min(m_character.CurrentHP+i_fChangeValHP, m_character.HP);
		ITEM_GENERAL * pHPDPItem = this->m_ItemManager.GetItemGeneralByDestParam( DES_RARE_ITEM_HPDP );
		if( pHPDPItem )
		{
			i_fChangeValHP += i_fChangeValHP * pHPDPItem->ItemInfo->GetParameterValue( DES_RARE_ITEM_HPDP );
			this->m_ItemManager.UpdateItemCountByPointer( DES_RARE_ITEM_HPDP );
		}		
		m_character.CurrentHP = min(m_character.CurrentHP+i_fChangeValHP, m_character.HP);
		// end 2010-12-21 by jskim, HP, DP 키트 적용량 증가 아이템 구현
	}
	else if (i_fChangeValHP < 0.0f)
	{
		float fTemp = m_character.CurrentHP = max(m_character.CurrentHP+i_fChangeValHP, 0.0f);
		if (fTemp <= 0.0f)
		{// 기체 폭파

			CharacterDeadRoutine(i_nDamageType);
			return;
		}
		m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
	}

	if(i_fChangeValHP > 0.0f
		&& IS_VALID_CLIENT_INDEX(i_SkillUseClientIdx)
		&& this->GetCharacter()->ClientIndex != i_SkillUseClientIdx)
	{// 2006-07-21 by cmkwon, Aggro 시스템 구현
		ActionInfo tmActionInfo(i_SkillUseClientIdx, timeGetTime(), 0.0f, m_character.CurrentHP - fOldCurHP);
		if(0.0f < tmActionInfo.fSumAggro)
		{
			this->AddAggroList(&tmActionInfo);
		}

		//////////////////////////////////////////////////////////////////////////
		// 2008-12-23 by dhjin, 전쟁 보상 추가안
		CFieldIOCPSocket * SkillUseClient = this->ms_pFieldIOCP->GetFieldIOCPSocket(i_SkillUseClientIdx);
		if(NULL != SkillUseClient
			&& (this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint()
				|| this->ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring())
			&& IS_MAP_INFLUENCE_WAR(SkillUseClient->GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())
			&& 0 == SkillUseClient->GetCurrentFieldMapChannel()->GetMapChannelIndex().ChannelIndex
			)
		{
			UID32_t WarContribution = (UID32_t)(m_character.CurrentHP - fOldCurHP);
			this->ms_pFieldIOCP->WarContributionCalculation(SkillUseClient, WarContribution);
		}
	}

	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
}

// 2006-07-21 by cmkwon, 인자 추가 - ClientIndex_t i_SkillUseClientIdx
void CFieldIOCPSocket::ChangeCurrentDP(float i_fChangeValDP, ClientIndex_t i_SkillUseClientIdx/*=0*/)
{
	if (i_fChangeValDP == 0.0f)
	{
		return;
	}

	float fOldCurDP = m_character.CurrentDP;
	if (i_fChangeValDP > 0.0f)
	{
		// 2010-12-21 by jskim, HP, DP 키트 적용량 증가 아이템 구현
		//m_character.CurrentDP = min(m_character.CurrentDP+i_fChangeValDP, m_character.DP);
		ITEM_GENERAL * pDPDPItem = this->m_ItemManager.GetItemGeneralByDestParam( DES_RARE_ITEM_HPDP );
		if( pDPDPItem )
		{
			i_fChangeValDP += i_fChangeValDP * pDPDPItem->ItemInfo->GetParameterValue( DES_RARE_ITEM_HPDP );
			this->m_ItemManager.UpdateItemCountByPointer( DES_RARE_ITEM_HPDP );
		}		
		m_character.CurrentDP = min(m_character.CurrentDP+i_fChangeValDP, m_character.DP);
		// end 2010-12-21 by jskim, HP, DP 키트 적용량 증가 아이템 구현
	}
	else if (i_fChangeValDP < 0.0f)
	{
		m_character.CurrentDP = max(m_character.CurrentDP+i_fChangeValDP, 0.0f);
		m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
	}

	if(i_fChangeValDP > 0.0f
		&& IS_VALID_CLIENT_INDEX(i_SkillUseClientIdx)
		&& this->GetCharacter()->ClientIndex != i_SkillUseClientIdx)
	{// 2006-07-21 by cmkwon, Aggro 시스템 구현
		ActionInfo tmActionInfo(i_SkillUseClientIdx, timeGetTime(), 0.0f, m_character.CurrentDP - fOldCurDP);
		if(0.0f < tmActionInfo.fSumAggro)
		{
			this->AddAggroList(&tmActionInfo);
		}

		//////////////////////////////////////////////////////////////////////////
		// 2008-12-23 by dhjin, 전쟁 보상 추가안
		CFieldIOCPSocket * SkillUseClient = this->ms_pFieldIOCP->GetFieldIOCPSocket(i_SkillUseClientIdx);
		if(NULL != SkillUseClient
			&& (this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint()
				|| this->ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring())
			&& IS_MAP_INFLUENCE_WAR(SkillUseClient->GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())
			&& 0 == SkillUseClient->GetCurrentFieldMapChannel()->GetMapChannelIndex().ChannelIndex
			)
		{
			UID32_t WarContribution = (UID32_t)(m_character.CurrentDP - fOldCurDP);
			this->ms_pFieldIOCP->WarContributionCalculation(SkillUseClient, WarContribution);
		}
	}

	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);	
}

void CFieldIOCPSocket::ChangeCurrentSP(float i_fChangeValSP)
{
	if (0.0f >= i_fChangeValSP)
	{
		return;
	}
	
	m_character.CurrentSP = min(m_character.CurrentSP+(SHORT)i_fChangeValSP, m_character.SP);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTSP);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::DecreaseCurrentSP(int i_nChangeValSP, INT i_nSkillBaseNum/*=0*/)
/// \brief		
/// \author		cmkwon
/// \date		2005-11-22 ~ 2005-11-22
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::DecreaseCurrentSP(int i_nChangeValSP, INT i_nSkillBaseNum/*=0*/)
{
	if (0 >= i_nChangeValSP)
	{
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-11-22 by cmkwon, 스마트 스피드 적용 처리 - 스마트 스피드 사용시는 적용하지 않는다
	if(MGEAR_SKILL_BASENUM_SMARTSP != i_nSkillBaseNum)
	{
		CParamFactor *pPFactor = this->GetParamFactor();
		if(0.0f < pPFactor->pfm_SKILL_SMARTSP)
		{		
			i_nChangeValSP = i_nChangeValSP - (int)(i_nChangeValSP*(double)pPFactor->pfm_SKILL_SMARTSP);
		}
	}

	m_character.CurrentSP = max(m_character.CurrentSP-i_nChangeValSP, 0);
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTSP);
}


void CFieldIOCPSocket::ChangeCurrentEP(float i_fChangeValEP)
{
	if (i_fChangeValEP == 0.0f)
	{
		return;
	}
	else if (i_fChangeValEP > 0.0f)
	{
		m_character.CurrentEP = min(m_character.CurrentEP+i_fChangeValEP, m_character.EP);
	}
	else if (i_fChangeValEP < 0.0f)
	{
		m_character.CurrentEP = max(m_character.CurrentEP+i_fChangeValEP, 0.0f);
	}

	SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTEP);
}

// HP, DP 변화 관련: DP 우선 적용 후 HP 적용
float CFieldIOCPSocket::DecreaseCharacterHPDP(float i_fChangeValue
											  , BYTE i_enumDamageType
											  , BOOL i_bCheckRecovery/*=TRUE*/
											  , CFieldMonster *i_pAttackMonster/*=NULL*/
											  , CFieldIOCPSocket *i_pAttackCharacter/*=NULL*/)
{
	if (m_bNoDamage || m_bArenaNoDamage)	// 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
	{// 무적 상태
		return m_character.CurrentHP;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-04 by dhjin, 체프 처리
	if(DAMAGE_BY_COLLISION != i_enumDamageType)
	{// 2006-12-15 by dhjin, 오브젝트 충돌은 체프 데미지에 영향이 없다.
		if(ApplyFieldDummyDamage(i_fChangeValue, i_enumDamageType))
		{
			return m_character.CurrentHP;
		}	
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-11-22 by cmkwon, 
	if(DAMAGE_BY_COLLISION == i_enumDamageType
		&& 0.0f != this->GetParamFactor()->pfm_SKILL_COLLISIONDAMAGE_DOWN)
	{
		i_fChangeValue *= (1.0f - this->GetParamFactor()->pfm_SKILL_COLLISIONDAMAGE_DOWN);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-11-21 by cmkwon, 데미지 감소에 ParamFactor 적용하여 처리하기
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 절대값 감소 아이템
	// 1. DestParamValue 값 만큼 데미지 감소 
	// 2. DP있는 상황에서 리듀스 데미지 체크
	float fReduceDamage = this->GetParamReduceDamage();
	if(0.0f != fReduceDamage) {
		if(i_fChangeValue <= fReduceDamage) {
			return m_character.CurrentHP;
		}

		float fTemp = m_character.CurrentDP - (i_fChangeValue - fReduceDamage);
		if(0.0f <= fTemp) {
			m_character.CurrentDP	= fTemp;
			i_fChangeValue			= 0.0f;
			SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
			return m_character.CurrentHP;
		}
		
		i_fChangeValue -= fReduceDamage;
		m_character.CurrentDP	= 0.0f;
	}

	if(0.0f < m_character.CurrentDP
		&& 0.0f != this->GetParamFactor()->pfm_SKILL_REDUCE_SHIELD_DAMAGE)
	{
// 2005-11-29 by cmkwon
//		DBGOUT("CurrentDP(%4.2f) ReduceShield(%4.2f)	=> Damage(%4.2f)\n",
//			m_character.CurrentDP, this->GetParamFactor()->pfm_SKILL_REDUCE_SHIELD_DAMAGE, i_fChangeValue);
		float fTemp = m_character.CurrentDP - i_fChangeValue*(1.0f - this->GetParamFactor()->pfm_SKILL_REDUCE_SHIELD_DAMAGE);
		if(0.0f <= fTemp)
		{
			m_character.CurrentDP	= fTemp;
			i_fChangeValue			= 0.0f;
			SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
			return m_character.CurrentHP;
		}
		
		i_fChangeValue			-= m_character.CurrentDP*(1.0f + this->GetParamFactor()->pfm_SKILL_REDUCE_SHIELD_DAMAGE);
		m_character.CurrentDP	= 0.0f;

// 2005-11-29 by cmkwon
//		DBGOUT("	CurrentDP(%4.2f) ReduceShield(%4.2f)	=> Damage(%4.2f)\n",
//			m_character.CurrentDP, this->GetParamFactor()->pfm_SKILL_REDUCE_SHIELD_DAMAGE, i_fChangeValue);
	}

	UID32_t WarContribution;	// 2008-12-23 by dhjin, 전쟁 보상 추가안

	if (m_character.CurrentDP + m_character.CurrentHP <= i_fChangeValue)
	{// 폭파
		if(DAMAGE_BY_PK == i_enumDamageType
			&& NULL != i_pAttackCharacter
			&& (this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint()
				|| this->ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring())
			&& IS_MAP_INFLUENCE_WAR(i_pAttackCharacter->GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())
			&& 0 == i_pAttackCharacter->GetCurrentFieldMapChannel()->GetMapChannelIndex().ChannelIndex
			)
		{// 2008-12-23 by dhjin, 전쟁 보상 추가안 - 폭파가 되었기 때문에 피케릭터 현재 피양만큼만 넣어준다.
			WarContribution = (UID32_t)(m_character.CurrentDP + m_character.CurrentHP);
			this->ms_pFieldIOCP->WarContributionCalculation(i_pAttackCharacter, WarContribution);
			this->ms_pFieldIOCP->WarDeathContributionCalculation(this);
		}
		CharacterDeadRoutine(i_enumDamageType, i_pAttackMonster, i_pAttackCharacter);
		return 0.0f;
	}
	else if (m_character.CurrentDP <= 0.0f && m_character.CurrentHP > i_fChangeValue)
	{
		// HP만 깍기, DP가 0인 경우
		m_character.CurrentHP = max(0.0f, m_character.CurrentHP-i_fChangeValue);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
	}
	else if (IS_IN_RANGE(m_character.CurrentDP, i_fChangeValue, m_character.CurrentHP + m_character.CurrentDP))
	{
		// DP도 깍고 HP도 깍고
		m_character.CurrentHP = max(0.0f, m_character.CurrentHP - (i_fChangeValue - m_character.CurrentDP));
		m_character.CurrentDP = 0.0f;		

		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
	}
	else if (m_character.CurrentDP > i_fChangeValue)
	{
		// DP만 깍기
		m_character.CurrentDP = max(0.0f, m_character.CurrentDP-i_fChangeValue);
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
	}

	if(DAMAGE_BY_PK == i_enumDamageType
		&& NULL != i_pAttackCharacter
		&& (this->ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint()
			|| this->ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring())
		&& IS_MAP_INFLUENCE_WAR(i_pAttackCharacter->GetCurrentFieldMapChannel()->GetMapInfluenceTypeW())
		&& 0 == i_pAttackCharacter->GetCurrentFieldMapChannel()->GetMapChannelIndex().ChannelIndex
		)
	{// 2008-12-23 by dhjin, 전쟁 보상 추가안 - 폭파가 안되었으면 데미지만큼 넣어준다.
		WarContribution = (UID32_t)i_fChangeValue;
		this->ms_pFieldIOCP->WarContributionCalculation(i_pAttackCharacter, WarContribution);
	}	

	// HP가 0 이하면 무조건 폭파
	if (m_character.CurrentHP <= 0.0f)
	{// 폭파

		CharacterDeadRoutine(i_enumDamageType, i_pAttackMonster, i_pAttackCharacter);
		return 0.0f;
	}
	
	if (i_bCheckRecovery
		&& m_character.CurrentHP > 0.0f
		&& IsValidCharacter())
	{
		if(m_character.CurrentHP < m_character.HP)
		{
			m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
		}

		if(m_character.CurrentDP < m_character.DP)
		{
			m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
		}
	}

#ifdef _DEBUG
//	SendString128Static(STRING_128_USER_NOTICE, "Damage: %4.2f, DP: %4.2f/%d, HP: %4.2f/%d",
//					i_fChangeValue,
//					m_character.CurrentDP, m_character.DP,
//					m_character.CurrentHP, m_character.HP);
//	DBGOUT("%s Damage: %4.2f, DP: %4.2f/%d, HP: %4.2f/%d\r\n",
//					m_character.CharacterName, i_fChangeValue,
//					m_character.CurrentDP, m_character.DP,
//					m_character.CurrentHP, m_character.HP);
#endif

	return m_character.CurrentHP;
}

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
// ///////////////////////////////////////////////////////////////////////////////
// /// \fn			void CFieldIOCPSocket::CheckArmorState(void)
// /// \brief		아머 장착 여부에 따른 적용 사항 확인
// /// \author		kelovon
// /// \date		2004-10-28 ~ 2004-10-28
// /// \warning	
// ///////////////////////////////////////////////////////////////////////////////
// void CFieldIOCPSocket::CheckArmorState(void)
// {
// 	// 아머 장착 여부에 따른 처리 - ParamFactor3, ParamFactor4는 ResetAllSkillAndEnchant()에서 적용된다
// 	ChangeHP(GetCharacterTotalHP());
// 	ChangeDP(GetCharacterTotalDP());
// }

void CFieldIOCPSocket::ApplyArmorParamFactor(void)
{
	if(0 == m_ItemCenter.ItemNum
		|| m_ItemCenter.Kind != ITEMKIND_DEFENSE)
	{
		return;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 아머는 3,4번만 ParamFactor에 적용한다(1,2번은 HP, SP를 올린다)
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정, 아머는 3번째부터 ParamFacter를 적용한다.
//	SetParamFactor(&m_ParamFactor, m_ItemCenter.DestParameter3, m_ItemCenter.ParameterValue3);
//	SetParamFactor(&m_ParamFactor, m_ItemCenter.DestParameter4, m_ItemCenter.ParameterValue4);	
	for(int i=2; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
	{
		SetParamFactor(&m_ParamFactor, m_ItemCenter.ArrDestParameter[i], m_ItemCenter.ArrParameterValue[i]);
	}
}

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
void CFieldIOCPSocket::CheckComputerState(ITEM *i_pItemInfo, BOOL i_bAttach, BOOL i_bSendChangeInfo/*=TRUE*/)
{
	if (i_pItemInfo->Kind != ITEMKIND_COMPUTER)
	{
		return;
	}

	if (i_bAttach)
	{
		for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
		{
			// 2010-03-17 by cmkwon, 인피1차 발동류 아이템 관련 버그 수정 - 게임 리스타트시에 CurrentDP에 아머의 추가 DP만큼 빠지는 버그 수정 
 			ApplyComputerGearStat(i_pItemInfo->ArrDestParameter[i], i_pItemInfo->ArrParameterValue[i], i_bSendChangeInfo);
		}
	}
	else
	{
		for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
		{
			// 2010-03-17 by cmkwon, 인피1차 발동류 아이템 관련 버그 수정 - 게임 리스타트시에 CurrentDP에 아머의 추가 DP만큼 빠지는 버그 수정 
			// 2010-03-25 by cmkwon, cpu 장착/해제 버그 수정(괄호 버그) - 
			ApplyComputerGearStat(i_pItemInfo->ArrDestParameter[i], -(i_pItemInfo->ArrParameterValue[i]), i_bSendChangeInfo);
		}
	}

	if(i_bSendChangeInfo)
	{
		this->SendStat_UpdateDB(FALSE);
	}
}

// 2013-05-31 by jhseol,bckim 아머 컬렉션 - CheckAllState 함수
void CFieldIOCPSocket::CheckAllState(INT SataCount, BOOL i_bAttach, BOOL i_bSendChangeInfo /*TRUE*/)
{
	if ( 0 == SataCount	)
	{
		return;
	}

	if ( i_bAttach)
	{
		SataCount = SataCount*(1);
	}
	else
	{
		SataCount = SataCount*(-1);
	}
	
	ApplyComputerGearStat(DES_ATTACK_PART	, SataCount, i_bSendChangeInfo);
	ApplyComputerGearStat(DES_DEFENSE_PART	, SataCount, i_bSendChangeInfo);
	ApplyComputerGearStat(DES_FUEL_PART		, SataCount, i_bSendChangeInfo);
	ApplyComputerGearStat(DES_SOUL_PART		, SataCount, i_bSendChangeInfo);
	ApplyComputerGearStat(DES_SHIELD_PART	, SataCount, i_bSendChangeInfo);
	ApplyComputerGearStat(DES_DODGE_PART	, SataCount, i_bSendChangeInfo);
	
	if(i_bSendChangeInfo)
	{
		this->SendStat_UpdateDB(FALSE);
	}
}				
// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - CheckAllState 함수

// 2010-03-17 by cmkwon, 인피1차 발동류 아이템 관련 버그 수정 - 게임 리스타트시에 CurrentDP에 아머의 추가 DP만큼 빠지는 버그 수정 
void CFieldIOCPSocket::ApplyComputerGearStat(DestParam_t desParam, float paramValue, BOOL i_bSendInfo/*=TRUE*/)		// 2011-08-01 by hskim, 파트너 시스템 2차 - 자료형 변경 (DestParameter - 255 -> 32767 지원)
{	
	switch (desParam)
	{
	case DES_ATTACK_PART:
		{			
			m_character.TotalGearStat.AttackPart += (Stat_t)paramValue;
			m_character.TotalGearStat.AttackPart = max(m_character.TotalGearStat.AttackPart, m_character.GearStat.AttackPart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.AttackPart = min(m_character.TotalGearStat.AttackPart, COUNT_MAX_STAT_POINT);
		}
		break;
	case DES_DEFENSE_PART:
		{
			m_character.TotalGearStat.DefensePart += (Stat_t)paramValue;
			m_character.TotalGearStat.DefensePart = max(m_character.TotalGearStat.DefensePart, m_character.GearStat.DefensePart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.DefensePart = min(m_character.TotalGearStat.DefensePart, COUNT_MAX_STAT_POINT);
		}
		break;
	case DES_FUEL_PART:
		{
			m_character.TotalGearStat.FuelPart += (Stat_t)paramValue;
			m_character.TotalGearStat.FuelPart = max(m_character.TotalGearStat.FuelPart, m_character.GearStat.FuelPart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.FuelPart = min(m_character.TotalGearStat.FuelPart, COUNT_MAX_STAT_POINT);

			// EP 변경
			// 2010-03-31 by cmkwon, 연료 관련 버그 수정(K0002796) - DP와 동일한 방식으로 변경
			if(i_bSendInfo)
			{
				ChangeEP(GetCharacterTotalEP(), TRUE);
			}
		}
		break;
	case DES_SOUL_PART:
		{
			m_character.TotalGearStat.SoulPart += (Stat_t)paramValue;
			m_character.TotalGearStat.SoulPart = max(m_character.TotalGearStat.SoulPart, m_character.GearStat.SoulPart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.SoulPart = min(m_character.TotalGearStat.SoulPart, COUNT_MAX_STAT_POINT);

			// SP 변경
			// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
			ChangeSP(CAtumSJ::GetCharacterSP(m_character.TotalGearStat.SoulPart, m_character.Level), TRUE);
		}
		break;
	case DES_SHIELD_PART:
		{
			m_character.TotalGearStat.ShieldPart += (Stat_t)paramValue;
			m_character.TotalGearStat.ShieldPart = max(m_character.TotalGearStat.ShieldPart, m_character.GearStat.ShieldPart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.ShieldPart = min(m_character.TotalGearStat.ShieldPart, COUNT_MAX_STAT_POINT);

			// DP 변경
			if(i_bSendInfo)
			{// 2010-03-17 by cmkwon, 인피1차 발동류 아이템 관련 버그 수정 - 게임 리스타트시에 CurrentDP에 아머의 추가 DP만큼 빠지는 버그 수정, DP만 체크, SP,EP는 스탯으로만 변경이 된다. 
				ChangeDP(GetCharacterTotalDP());
			}
		}
		break;
	case DES_DODGE_PART:
		{
			m_character.TotalGearStat.DodgePart += (Stat_t)paramValue;
			m_character.TotalGearStat.DodgePart = max(m_character.TotalGearStat.DodgePart, m_character.GearStat.DodgePart);
// 2007-05-16 by cmkwon, 300초과로 갑을 가지고 있고 적용시 최대 300이 되도록 수정
//			m_character.TotalGearStat.DodgePart = min(m_character.TotalGearStat.DodgePart, COUNT_MAX_STAT_POINT);
		}
		break;
	}
}

// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
//BOOL CFieldIOCPSocket::ProcessSplashDamage(enumAttackToTarget type,
//					  CFieldIOCPSocket *pAttackSocket, void* pAttackUnit,
//					  D3DXVECTOR3 explosionPosition, ITEM *pAttackItem,
//					  ClientIndex_t clientIndexToExclude)
//{
//	if ((!(pAttackItem->Kind == ITEMKIND_FOR_MON_ALLATTACK) && !IS_SECONDARY_WEAPON(pAttackItem->Kind)) || pAttackItem->ExplosionRange <= 0)
//	{
//		return FALSE;
//	}
//
//	vector<ClientIndex_t>	ClientIndexVector;
//	vector<ClientIndex_t>	*pClientIndexVector = NULL;
//	IOCPWorkerTLSDATA		*pTLSData = ms_pFieldIOCP->GetIOCPWorkerTLSDATA();
//	CFieldIOCP				*pFieldIOCP = pAttackSocket->ms_pFieldIOCP;
//	CFieldMapChannel		*pMapChannel = NULL;
//
//	float					fDistance = 0;
//	float					fDamage = 0;
//	BYTE					DamageKind = DAMAGEKIND_NO_DAMAGE;
//
//	if(NULL == pTLSData)
//	{
//		ClientIndexVector.reserve(100);
//		pClientIndexVector = &ClientIndexVector;
//	}
//	else
//	{
//		pClientIndexVector = &pTLSData->clientIndexVector;
//	}
//
//	if (type == C2M)
//	{
//		pMapChannel = pAttackSocket->m_pCurrentFieldMapChannel;
//
//		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(
//							explosionPosition.x, explosionPosition.z,
//							CAtumSJ::GetExplosionRange(pAttackItem, &pAttackSocket->m_ParamFactor), pClientIndexVector);
//
//		if (nMonsters <= 0)
//		{
//			return FALSE;
//		}
//
//		int i = 0;
//		while (i < nMonsters)
//		{
//			CHARACTER			*pAttackCharacter = (CHARACTER*)pAttackUnit;
//			CFieldIOCPSocket	*pTargetNPCSocket = NULL;
//			CFieldMonster		*pMonster = NULL;
//			ClientIndex_t		tmpMonsterIndex = (*pClientIndexVector)[i];
//
//			if ( tmpMonsterIndex == clientIndexToExclude
//				|| !pAttackSocket->CheckValidAttackTargetMonster(tmpMonsterIndex, pAttackSocket->m_character.MapChannelIndex.ChannelIndex, pMonster))
//			{
//				i++;
//				continue;
//			}
//
//			fDistance = D3DXVec3Length(&(explosionPosition - pMonster->PositionVector));
//			DamageKind = DAMAGEKIND_NO_DAMAGE;
//
//			float fDamageWeight
//				= pAttackSocket->CalcSplashDamageWeightByExposionRange(C2M, pAttackItem, &pAttackSocket->m_ParamFactor, fDistance, &DamageKind, pMonster->MonsterInfoPtr->Size);
//
//			if (DamageKind != DAMAGEKIND_NO_DAMAGE)
//			{
//				fDamage = CalcDamageOfAttack(C2M, fDamageWeight, pAttackSocket,	// @ProcessSplashDamage()
//					pAttackCharacter, pTargetNPCSocket, pMonster, pAttackItem,
//					&DamageKind, explosionPosition);
//			}
//			else
//			{
//				fDamage = 0.0f;
//			}
//
//#ifdef _DEBUG
//			pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0000, i, tmpMonsterIndex, fDamage, fDamageWeight*100);
//#endif
//
//			i++;
//		}
//	}
//	else if (type == C2C)
//	{
//		// not implemented yet
//		ASSERT_NOT_IMPLEMENTED_YET();
//	}
//	else if (type == M2C)
//	{
////#ifdef _DEBUG
////		DBGOUT("M2C Splash\r\n");
////#endif
//		CFieldMonster *pAttackMonster = (CFieldMonster*)pAttackUnit;
//		pMapChannel = pAttackMonster->m_pCurrentFieldMapChannelMonster;
//
//		int nCharacters = pMapChannel->GetAdjacentCharacterIndexes(
//							explosionPosition.x, explosionPosition.z,
//							CAtumSJ::GetExplosionRange(pAttackItem, &pAttackSocket->m_ParamFactor), pClientIndexVector);
//
//		if (nCharacters <= 0)
//		{
//			return FALSE;
//		}
//
//		int i = 0;
//		while (i < nCharacters)
//		{
//			CFieldIOCPSocket	*pTargetCharacterSocket = NULL;
//			CHARACTER			*pTargetCharacter = NULL;
//			ClientIndex_t		tmpClientIndex = (*pClientIndexVector)[i];
//
//			if (tmpClientIndex == clientIndexToExclude
//				|| !pAttackSocket->CheckValidAttackTargetCharacter(tmpClientIndex, pTargetCharacterSocket, pTargetCharacter))
//			{
//				i++;
//				continue;
//			}
//
//			fDistance = D3DXVec3Length(&(explosionPosition - pTargetCharacter->PositionVector));
//			DamageKind = DAMAGEKIND_NO_DAMAGE;
//
//			float fDamageWeight
//				= pAttackSocket->CalcSplashDamageWeightByExposionRange(M2C, pAttackItem, &pAttackSocket->m_ParamFactor, fDistance, &DamageKind, 10);
//
//			if (DamageKind != DAMAGEKIND_NO_DAMAGE)
//			{
//				fDamage = CalcDamageOfAttack(M2C, fDamageWeight, pAttackSocket,	// @ProcessSplashDamage()
//					pAttackMonster, pTargetCharacterSocket, pTargetCharacter, pAttackItem,
//					&DamageKind, explosionPosition);
//			}
//			else
//			{
//				fDamage = 0.0f;
//			}
//
//#ifdef _DEBUG
//			pTargetCharacterSocket->SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0001, i, pTargetCharacter->CharacterName, fDamage);
//#endif
//
//			i++;
//		}
//	}
//
//	return TRUE;
//}



///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ProcessSplashDamageC2All(CFieldIOCPSocket *i_pAttFSock, SATTACK_PARAMETER *i_pAttParam, float i_fRadius, D3DXVECTOR3 *i_pVec3TargetPos)
/// \brief		
/// \author		dhjin
/// \date		2006-11-30 ~ 2006-11-30
/// \warning	인자 변경(SATTACK_PARAMETER *i_pAttParam <== ITEM *i_pAttItem)
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ProcessSplashDamageC2All(CFieldIOCPSocket *i_pAttFSock, SATTACK_PARAMETER *i_pAttParam, float i_fRadius, D3DXVECTOR3 *i_pVec3TargetPos)
{
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pSFCAttackOK, Sendbuf);
	pSFCAttackOK->AttackIndex						= i_pAttFSock->GetCharacter()->ClientIndex;
	pSFCAttackOK->TargetInfo.TargetIndex			= 0;
	pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
//	pSFCAttackOK->TargetInfo.TargetPosition			= 0;
	pSFCAttackOK->FirePosition.Reset();	
	pSFCAttackOK->AttackType						= ATT_TYPE_SPLASH_PRI;
	pSFCAttackOK->WeaponIndex						= 0;
	pSFCAttackOK->ItemNum							= i_pAttParam->pWeaponItemInfo->ItemNum;
	pSFCAttackOK->RemainedBulletFuel				= 0;
	pSFCAttackOK->SkillNum							= 0;
	pSFCAttackOK->TargetInfo.MultiTargetIndex		= i_pAttParam->MultiTargetIndex;		// 2011-04-04 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가


	vector<ClientIndex_t>	ClientIndexVector;		
	ClientIndexVector.reserve(100);

	CFieldMapChannel		*pFMChann = i_pAttFSock->m_pCurrentFieldMapChannel;
	if(NULL == pFMChann){						return;}

	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by dhjin, C2ALLC Splash 데미지 처리
	int nUnits = pFMChann->GetExactCharacterIndexes(&ClientIndexVector, i_pVec3TargetPos, i_fRadius, i_pAttFSock->m_character.ClientIndex);

	if (0 < nUnits && TRUE != IS_MAP_INFLUENCE_NON_DISPUTE(i_pAttFSock->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()) )		// 2012-01-17 by hskim, EP4 [비분쟁 지역] - 유저간 공격 금지 구역
	{
		for(int i= 0; i < nUnits; i++)
		{
			///////////////////////////////////////////////////////////////////////////////
			// 초기화
			pSFCAttackOK->TargetInfo.TargetIndex			= 0;
			pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;

			CFieldIOCPSocket	*pTargetCSock = ms_pFieldIOCP->GetFieldIOCPSocket(ClientIndexVector[i]);
			CHARACTER			*pTargetCharacter = NULL;
			if(NULL == pTargetCSock
				|| FALSE == pTargetCSock->IsValidCharacter()
				|| FALSE == CFieldIOCPSocket::IsValidCharacterEnemy(i_pAttFSock, pTargetCSock))
			{
				continue;
			}

			pTargetCharacter	= &pTargetCSock->m_character;
			BYTE	DamageKind	= DAMAGEKIND_NORMAL;
			pSFCAttackOK->TargetInfo.TargetIndex = pTargetCharacter->ClientIndex;	// 2005-12-14 by cmkwon, 타겟 인덱스를 설정함

			float fDamage = CalcDamageOfAttackNew(&DamageKind, C2C, 1.0f, i_pAttFSock, &i_pAttFSock->m_character, i_pAttParam, pTargetCSock, pTargetCharacter, i_fRadius);			
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//			float fDamage = CalcDamageOfAttack(C2C, 1.0f, i_pAttFSock, &i_pAttFSock->m_character, pTargetCSock, pTargetCharacter, i_pAttItem
//					, &DamageKind, *i_pVec3TargetPos, i_fRadius, 0);			

			i_pAttFSock->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));		// 2006-12-01 by dhjin, 공격자에게 전송
			pTargetCSock->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));		// 2006-12-01 by dhjin, 피공격자에게 전송
		}// end_for(int i= 0; i < nCharacters; i++)
	}// END - if (0 < nCharacters)
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by dhjin, C2ALLM Splash 데미지 처리
	nUnits = pFMChann->GetExactMonsterIndexes(&ClientIndexVector, i_pVec3TargetPos, i_fRadius);
	if(0 < nUnits)
	{
		for(int i= 0; i < nUnits; i++)
		{
			///////////////////////////////////////////////////////////////////////////////
			// 초기화
			pSFCAttackOK->TargetInfo.TargetIndex			= 0;
			pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;

			CFieldMonster	*pTargetMon = pFMChann->GetFieldMonster(ClientIndexVector[i], 31);
			if(NULL == pTargetMon
				|| FALSE == pTargetMon->IsValidMonster()
				|| IS_SAME_CHARACTER_MONSTER_INFLUENCE(i_pAttFSock->GetCharacter()->InfluenceType, pTargetMon->MonsterInfoPtr->Belligerence)
				|| BELL_INFINITY_DEFENSE_MONSTER == pTargetMon->MonsterInfoPtr->Belligerence)	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 받지 않는다.
			{
				continue;
			}
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 배리어 체크
			if(pTargetMon->CheckBarrierHave()) {
				if(pTargetMon->CheckBarrierUsing()) {
					INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USING, T_FC_BATTLE_MONSTER_BARRIER_USING, pSendMsg, BSendBuf);
					pSendMsg->MonsterIndex		= pTargetMon->MonsterIndex;
					i_pAttFSock->SendAddData(BSendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USING));
//					i_pAttFSock->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
					continue;
				}
				if(pTargetMon->BarrierUse()) {
					INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USE, T_FC_BATTLE_MONSTER_BARRIER_USE, pSendMsg, BSendBuf);
					pSendMsg->MonsterIndex		= pTargetMon->MonsterIndex;
					pSendMsg->SkillItemNum		= pTargetMon->m_bBarrierInfo.SkillNum;
					i_pAttFSock->m_pCurrentFieldMapChannel->SendMessageToAllInChannel(BSendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USE));
//					i_pAttFSock->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
					continue;
				}
			}

			BYTE	DamageKind	= DAMAGEKIND_NORMAL;
			pSFCAttackOK->TargetInfo.TargetIndex = pTargetMon->MonsterIndex;	// 2005-12-14 by cmkwon, 타겟 인덱스를 설정함

			// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
			BOOL bContinue = FALSE;
			
			if( NULL != pTargetMon && TRUE == pTargetMon->IsTriggerFunction() )
			{
				// 이 몬스터는 트리거 시스템과 연결되어 있다.
				mt_auto_lock mtAuto(&pTargetMon->m_mtVectTriggerFunctionPtr);

				for(int i=0; i<pTargetMon->m_mtVectTriggerFunctionPtr.size(); i++)
				{
					CTriggerFunction *pTriggerFunction = pTargetMon->m_mtVectTriggerFunctionPtr[i];
					if( TRUE == pTriggerFunction->OnIsInvincible(pTargetMon->MonsterInfoPtr->MonsterUnitKind, i_pAttFSock) )
					{
						bContinue = TRUE;
					}
					// 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_pAttFSock->m_nCrystalAttackCount++;
							if( 1 == i_pAttFSock->m_nCrystalAttackCount )
							{
								i_pAttFSock->SendString128(STRING_128_USER_NOTICE, STRMSG_121126_0001);
							}
							if( 50 <= i_pAttFSock->m_nCrystalAttackCount )
							{
								i_pAttFSock->m_nCrystalAttackCount = 0;
							}
							bContinue = TRUE;
						}
						else
						{
							i_pAttFSock->m_nCrystalAttackCount = 0;
						}
						// end 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장 : 50번 공격할때마다 메세지 출력
					}
					// end 2013-01-23 by jhseol, 전쟁 시 크리스탈만 공격 불가능 하도록 수정
				}
			}

			if( TRUE == bContinue )
			{
				continue;
			}
			// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

			float fDamage = CalcDamageOfAttackNew(&DamageKind, C2M, 1.0f, i_pAttFSock, &i_pAttFSock->m_character, i_pAttParam, NULL, pTargetMon, i_fRadius);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//			float fDamage = CalcDamageOfAttack(C2M, 1.0f, i_pAttFSock, &i_pAttFSock->m_character, NULL, pTargetMon, i_pAttItem
//					, &DamageKind, *i_pVec3TargetPos, i_fRadius, 0);			

			i_pAttFSock->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));		// 2006-12-01 by dhjin, 공격자에게 전송

			///////////////////////////////////////////////////////////////////////
			// Attack 정보를 NPC에게 보냄
			INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, Send2NPC);
			pSetAttackChar->ChannelIndex	= pFMChann->GetMapChannelIndex().ChannelIndex;
			pSetAttackChar->AttackIndex		= i_pAttFSock->GetCharacter()->ClientIndex;
			pSetAttackChar->TargetIndex		= pTargetMon->MonsterIndex;
			pSetAttackChar->DamageAmount	= fDamage;
			pSetAttackChar->ItemKind		= i_pAttParam->pWeaponItemInfo->Kind;
			pFMChann->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
		}// end_for(int i= 0; i < nCharacters; i++)
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack(MSG_FN_BATTLE_ATTACK_PRIMARY *i_pAttackPri, CFieldIOCPSocket *i_pAttackMonSock, CFieldMonster *i_pAttackMon, ITEM *i_pAttackItem)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-13 ~ 2005-12-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ProcessSplashDamageMonsterAllAttack(MSG_FN_BATTLE_ATTACK_PRIMARY *i_pAttackPri, CFieldIOCPSocket *i_pAttackMonSock
														   , CFieldMonster *i_pAttackMon, ITEM *i_pAttackItem)
{
// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 아래와 같이 전체를 수정함.
// 	if (i_pAttackItem->Kind != ITEMKIND_FOR_MON_ALLATTACK
// 		|| 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 몬스터에게만 공격
// 	if(BELL_INFINITY_DEFENSE_MONSTER == pMonInfo->Belligerence) {
// 		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 							pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);	
// 		if (nMonsters <= 0) {
// 			// 2005-12-13 by cmkwon, 타겟이 없음
// 			return;
// 		}
// 		
// 		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_ATTACK_MONSTER != pTargetFMonster->MonsterInfoPtr->Belligerence) {
// 				continue;
// 			}
// 			pSFCAttackOK->TargetInfo.TargetIndex			= 0;
// 			pSFCAttackOK->TargetInfo.TargetItemFieldIndex	= 0;
// 			
// 			float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetFMonster->PositionVector));
// 			BYTE	DamageKind = i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);
// 			if(DAMAGEKIND_NO_DAMAGE != DamageKind) 
// 			{// 2007-10-22 by cmkwon, 데미지가 없는지 체크
// 				float fDamage = CalcDamageOfAttackMonsterToMonster(1.0f
// 					, i_pAttackMonSock, i_pAttackMon, &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	= pMapChannel->GetMapChannelIndex().ChannelIndex;
// 				pSetAttackChar->AttackIndex		= i_pAttackPri->AttackIndex;
// 				pSetAttackChar->TargetIndex		= i_pAttackPri->TargetIndex;
// 				pSetAttackChar->DamageAmount	= fDamage;
// 				pSetAttackChar->ItemKind		= attParam.pWeaponItemInfo->Kind;
// 				pMapChannel->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
// 			}
// 				
// 			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 몬스터와 유저 공격
// 	if(BELL_INFINITY_ATTACK_MONSTER == pMonInfo->Belligerence) {
// 		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 			pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);	
// 		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));
// 				BYTE	DamageKind = i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);
// 				if(DAMAGEKIND_NO_DAMAGE != DamageKind) 
// 				{// 2007-10-22 by cmkwon, 데미지가 없는지 체크
// 					float fDamage = CalcDamageOfAttackMonsterToMonster(1.0f
// 						, i_pAttackMonSock, i_pAttackMon, &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	= pMapChannel->GetMapChannelIndex().ChannelIndex;
// 					pSetAttackChar->AttackIndex		= i_pAttackPri->AttackIndex;
// 					pSetAttackChar->TargetIndex		= i_pAttackPri->TargetIndex;
// 					pSetAttackChar->DamageAmount	= fDamage;
// 					pSetAttackChar->ItemKind		= attParam.pWeaponItemInfo->Kind;
// 					pMapChannel->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
// 				}
// 				
// 				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,
// 			pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);
// 		if (nCharacters > 0)
// 		{// 2005-12-13 by cmkwon, 타겟이 없음
// 			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;
// 				}
// 				
// 				float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetCharacter->PositionVector));
// 				BYTE	DamageKind = i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);
// 				if(DAMAGEKIND_NO_DAMAGE != DamageKind)
// 				{// 2007-10-22 by cmkwon, 데미지가 없는지 체크
// 					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;
// 	}
// 
// 	int nCharacters = pMapChannel->GetAdjacentCharacterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z,
// 						pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);
// 	if (nCharacters <= 0)
// 	{// 2005-12-13 by cmkwon, 타겟이 없음
// 		return;
// 	}
// 
// 	////////////////////////////////////////////////////////////////////////////////
// 	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 위로 수정
// 	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
// // 	SATTACK_PARAMETER attParam;	
// // 	MEMSET_ZERO(&attParam, sizeof(attParam));
// // 	i_pAttackMon->APCalcAttckParameter(&attParam, i_pAttackItem, i_pAttackPri->WeaponIndex);
// // 
// // 	D3DXVECTOR3		vec3ExplosionPos = A2DX(i_pAttackPri->TargetPosition);
// 	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));
// 			BYTE	DamageKind = i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);
// 			if(DAMAGEKIND_NO_DAMAGE != DamageKind)
// 			{// 2007-10-22 by cmkwon, 데미지가 없는지 체크
// 				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++)
// 
// // 2007-10-22 by cmkwon, 위와 같이 수정함, 같은 세력 몬스터 처리가 되어 있지 않았음
// //	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 (i_pAttackMonSock->CheckValidAttackTargetCharacter(pMapChannel, tmpClientIndex, pTargetCharacterSocket, pTargetCharacter))
// //		{
// //			float	fDistance = D3DXVec3Length(&(vec3ExplosionPos - pTargetCharacter->PositionVector));
// //			BYTE	DamageKind = i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);
// //
// //			if(DAMAGEKIND_NO_DAMAGE != DamageKind)
// //			{
// //// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
// ////				pSFCAttackOK->TargetInfo.TargetIndex			= pTargetCharacter->ClientIndex;	// 2005-12-14 by cmkwon, 타겟 인덱스를 설정함
// ////				mt_auto_lock dummyLock(&pTargetCharacterSocket->m_mapFieldDummy);			// lock m_mapFieldDummy
// ////				if (pTargetCharacterSocket->m_mapFieldDummy.empty())
// ////				{// 피공격자가 Dummy를 달고 있지 않을 때
// ////					pSFCAttackOK->TargetInfo.TargetItemFieldIndex = 0;			// 2005-12-13 by cmkwon, 초기화
// ////
// ////					float fDamage = CalcDamageOfAttack(M2C, 1.0f, i_pAttackMonSock, i_pAttackMon, pTargetCharacterSocket, pTargetCharacter, i_pAttackItem
// ////						, &DamageKind, vec3ExplosionPos, i_pAttackItem->Range, ((i_pAttackItem->OrbitType == ORBIT_BODYSLAM) ? 0 : fDistance ));
// ////#ifdef _DEBUG
// ////					pTargetCharacterSocket->SendString128(STRING_128_ADMIN_CMD, "MonSplash: Idx(%d) Damage(%3.1f) to %s"
// ////						, i, fDamage, i_pAttackMon->MonsterInfoPtr->MonsterName);
// ////#endif
// ////				}
// ////				else
// ////				{// 피공격자가 Dummy를 달고 있을 때
// ////					
// ////					FIELD_DUMMY *pTargetDummy = (pTargetCharacterSocket->m_mapFieldDummy.begin())->second;
// ////					pSFCAttackOK->TargetInfo.TargetItemFieldIndex = pTargetDummy->ItemFieldIndex;
// ////					
// ////					float fDamage = CalcDamageOfAttack(M2C, 1.0f, i_pAttackMonSock, i_pAttackMon, pTargetCharacterSocket, pTargetCharacter, i_pAttackItem
// ////						, &DamageKind, vec3ExplosionPos, 0, 0, (pTargetDummy==NULL?NULL:pTargetDummy->ItemFieldIndex));
// ////#ifdef _DEBUG
// ////					pTargetCharacterSocket->SendString128(STRING_128_ADMIN_CMD, "MonSplash(dummy): Idx(%d) Damage(%3.1f) to %s"
// ////						, i, fDamage, i_pAttackMon->MonsterInfoPtr->MonsterName);
// ////#endif
// ////				}
// //				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 ));
// //// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
// ////				// 2006-12-04 by dhjin, 아래와 같이 수정
// ////				float fDamage = CalcDamageOfAttack(M2C, 1.0f, i_pAttackMonSock, i_pAttackMon, pTargetCharacterSocket, pTargetCharacter, i_pAttackItem
// ////					, &DamageKind, vec3ExplosionPos, i_pAttackItem->Range, ((i_pAttackItem->OrbitType == ORBIT_BODYSLAM) ? 0 : fDistance ));
// //
// //			}// end_if(DAMAGEKIND_NO_DAMAGE != DamageKind)
// //		}// end_if (i_pAttackMonSock->CheckValidAttackTargetCharacter(tmpClientIndex, pTargetCharacterSocket, pTargetCharacter))
// //
// //		if(pTargetCharacterSocket
// //			&& pTargetCharacterSocket->IsValidCharacter(FALSE))
// //		{
// //			pTargetCharacterSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
// //		}
// //	}// end_for(int i= 0; i < nCharacters; i++)
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - 
	if ((ITEMKIND_FOR_MON_ALLATTACK != i_pAttackItem->Kind && ITEMKIND_FOR_MON_RANGE_ATTACK != i_pAttackItem->Kind)
		|| i_pAttackItem->ExplosionRange <= 0)
	{// 2005-12-13 by cmkwon, 아이템 설정 오류
		
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[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);
		return;
	}

	if(NULL == i_pAttackMon
		|| FALSE == i_pAttackMon->IsValidMonster())
	{
		return;
	}
	MONSTER_INFO *pAttFMonInfo = i_pAttackMon->MonsterInfoPtr;
	if(NULL == pAttFMonInfo)
	{
		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->TargetInfo.MultiTargetIndex		= i_pAttackPri->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	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));
	attParam.MultiTargetIndex = i_pAttackPri->MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	i_pAttackMon->APCalcAttckParameter(&attParam, i_pAttackItem, i_pAttackPri->WeaponIndex);

	D3DXVECTOR3		vec3ExplosionPos = i_pAttackMon->PositionVector;

	// 2010-03-17 by cmkwon, 1/3 M to M 처리
	if(BELL_INFINITY_DEFENSE_MONSTER == pAttFMonInfo->Belligerence
		|| BELL_INFINITY_ATTACK_MONSTER == pAttFMonInfo->Belligerence)
	{
		int nMonsters = pMapChannel->GetAdjacentMonsterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z, pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);	
		if (0 < nMonsters)
		{
			vectClientIndex_t::iterator itr(ClientIndexVector.begin());
			for(; itr != ClientIndexVector.end(); itr++)
			{
				ClientIndex_t tmTarIdx = *itr;
				if(tmTarIdx == i_pAttackPri->AttackIndex)
				{
					continue;
				}

				CFieldMonster *pTarFMon = pMapChannel->GetFieldMonster(tmTarIdx, 105);
				if(NULL == pTarFMon
					|| FALSE == pTarFMon->IsValidMonster()					
					|| FALSE == IS_WARABLE_M2M_BELL(pAttFMonInfo->Belligerence, pTarFMon->MonsterInfoPtr->Belligerence))
				{
					continue;
				}

				float	fDamage		= 0.0f;
				float	fDistance	= D3DXVec3Length(&(vec3ExplosionPos - pTarFMon->PositionVector));
				BYTE	DamageKind	= i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);

				if(DAMAGEKIND_NO_DAMAGE != DamageKind
					&& ITEMKIND_FOR_MON_RANGE_ATTACK == i_pAttackItem->Kind)
				{// 2010-03-17 by cmkwon, ITEMKIND_FOR_MON_RANGE_ATTACK는 각도 체크까지 진행

					D3DXVECTOR3		tmUnitVec3M2C;
					D3DXVec3Normalize(&tmUnitVec3M2C, &(pTarFMon->PositionVector - i_pAttackMon->PositionVector));		// 현재 몬스터에서 타겟몬스터를 향하는 Target Vector를 구한다.
					float fPinPoint = ACOS(D3DXVec3Dot(&i_pAttackMon->TargetVector, &tmUnitVec3M2C));					// 몬스터에서 Target Vector와 위에서 구한 현재 Target Vector 사이의 각을 구한다
					if(fPinPoint > i_pAttackItem->RangeAngle)
					{
						DamageKind = DAMAGEKIND_NO_DAMAGE;
					}
				}
				if(DAMAGEKIND_NO_DAMAGE != DamageKind)
				{// 2007-10-22 by cmkwon, 데미지가 없는지 체크

					fDamage = CalcDamageOfAttackMonsterToMonster(1.0f, i_pAttackMonSock, i_pAttackMon, &attParam, (void*)pTarFMon);					
				}

				INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, Send2NPC);
				pSetAttackChar->ChannelIndex	= pMapChannel->GetMapChannelIndex().ChannelIndex;
				pSetAttackChar->AttackIndex		= i_pAttackPri->AttackIndex;
				pSetAttackChar->TargetIndex		= i_pAttackPri->TargetIndex;
				pSetAttackChar->DamageAmount	= fDamage;
				pSetAttackChar->ItemKind		= attParam.pWeaponItemInfo->Kind;
				pMapChannel->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
			}// END - for(; itr != ClientIndexVector.end(); itr++)
		}
	}


	// 2010-03-17 by cmkwon, 2/3 M to C 처리
	if(BELL_INFINITY_DEFENSE_MONSTER != pAttFMonInfo->Belligerence)
	{
		int nCharacters = pMapChannel->GetAdjacentCharacterIndexes(i_pAttackPri->TargetPosition.x, i_pAttackPri->TargetPosition.z, pMapChannel->GetMonsterVisibleDiameterW(), &ClientIndexVector);
		if (0 < nCharacters)
		{
			vectClientIndex_t::iterator itr(ClientIndexVector.begin());
			for(; itr != ClientIndexVector.end(); itr++)
			{
				ClientIndex_t tmTarIdx = *itr;
				
				CFieldIOCPSocket	*pTargetCharacterSocket	= NULL;
				CHARACTER			*pTargetCharacter		= NULL;
				
				if (FALSE == i_pAttackMonSock->CheckValidAttackTargetCharacter(pMapChannel, tmTarIdx, pTargetCharacterSocket, pTargetCharacter)
					|| TRUE == IS_SAME_CHARACTER_MONSTER_INFLUENCE(pTargetCharacter->InfluenceType, pAttFMonInfo->Belligerence))
				{
					continue;
				}

				float	fDistance	= D3DXVec3Length(&(vec3ExplosionPos - pTargetCharacter->PositionVector));
				BYTE	DamageKind	= i_pAttackMonSock->CalcSplashDamageKindByMonsterAllAttack(i_pAttackItem, fDistance, 0);

				if(DAMAGEKIND_NO_DAMAGE != DamageKind
					&& ITEMKIND_FOR_MON_RANGE_ATTACK == i_pAttackItem->Kind)
				{// 2010-03-17 by cmkwon, ITEMKIND_FOR_MON_RANGE_ATTACK는 각도 체크까지 진행
					
					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)
					{
						DamageKind = DAMAGEKIND_NO_DAMAGE;
					}
				}

				if(DAMAGEKIND_NO_DAMAGE != DamageKind)
				{// 2007-10-22 by cmkwon, 데미지가 없는지 체크
					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 ));
				}
				
				pTargetCharacterSocket->SendAddData(Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK));
			}// END - for(; itr != ClientIndexVector.end(); itr++)
		}
	}

	// 2010-03-17 by cmkwon, 3/3 전체 공격 정보를 주위에 전송
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(i_pAttackPri->AttackIndex, Sendbuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), pMapChannel, FALSE, pMapChannel->GetMonsterVisibleDiameterW());
}

// 2007-06-08 by cmkwon, 함수를 CalcDamageOfAttackNew()로 변경함
///****** 파라미터 정의 *********************************************************
//	enumAttackToTarget	type			: 공격자와 피공격자에 따른 분류
//	float				fDamageWeight	: Damage Weight, 범위가 있는 경우 0.0f ~ 1.0f
//	CFieldIOCPSocket	*pAttackSocket	: client socket 혹은 npc socket
//	void				*pAttackUnit	: CHARACTER 혹은 CFieldMonster
//	CFieldIOCPSocket	*pTargetSocket	: client socket 혹은 npc socket
//	void				*pTargetUnit	: CHARACTER 혹은 CFieldMonster
//	ITEM				*pAttackItem	: 공격 아이템
//	BYTE				*pDamageKind	: [out]크리티컬인 경우 값 return
//	UINT				ItemFieldIndex	: 아이템을 공격할 경우 ItemFieldIndex, 아니면 0
//******************************************************************************/
//float CFieldIOCPSocket::CalcDamageOfAttack(enumAttackToTarget type, float fDamageWeight,
//						  CFieldIOCPSocket *pAttackSocket, void* pAttackUnit,
//						  CFieldIOCPSocket *pTargetSocket, void *pTargetUnit,
//						  ITEM *pAttackItem, BYTE *pDamageKind,
//						  D3DXVECTOR3 &TargetPosition,
//						  float fSkillAppliedAttackRange, float fActualAttackDistance,
//						  UINT ItemFieldIndex)
//{
//	// Weight가 0이거나 DAMAGEKIND_NO_DAMAGE이면 그냥 return
//	if(fDamageWeight == 0 || *pDamageKind == DAMAGEKIND_NO_DAMAGE)
//	{
//		return 0.0f;
//	}
//	int		nRand = 0;
//
//	float	fAttackSuccessProbability = 0.0f;
//	float	fAttackProbability = 0.0f;
//	float	fDefenseProbability = 0.0f;
//
//	float	fDamage = 0.0f;
//	float	fAttack = 0.0f;
//	float	fDefense = 0;	// fDefense/255 만큼 빼준다.
//
//	BOOL	bIsPrimaryAttack = IS_PRIMARY_WEAPON(pAttackItem->Kind) || IS_PRIMARY_WEAPON_MONSTER(pAttackItem->Kind);
//
//	CHARACTER		*pAttackCharacter = NULL;
//	CHARACTER		*pTargetCharacter = NULL;
//
//	CParamFactor	*pAttackParamFactor = NULL;		// 캐릭터용
//	CParamFactor	*pTargetParamFactor = NULL;		// 캐릭터용
//
//	CFieldMonster	*pAttackMonster = NULL;
//	CFieldMonster	*pTargetMonster = NULL;
//
//	MONSTER_INFO	*pAttackMonsterInfo = NULL;
//	MONSTER_INFO	*pTargetMonsterInfo = NULL;
//
//	char WeaponTypeString[128];	// 디버그 스트링용
//#ifdef _DEBUG
//
//	if (IS_PRIMARY_WEAPON(pAttackItem->Kind))
//	{
//		sprintf(WeaponTypeString, STRMSG_S_F2NOTIFY_0002);
//	}
//	else if (IS_SECONDARY_WEAPON(pAttackItem->Kind))
//	{
//		sprintf(WeaponTypeString, STRMSG_S_F2NOTIFY_0003);
//	}
//	else if (IS_PRIMARY_WEAPON_MONSTER(pAttackItem->Kind))
//	{
//		sprintf(WeaponTypeString, STRMSG_S_F2NOTIFY_0004, pAttackItem->ItemName);
//	}
//	else if (IS_SECONDARY_WEAPON_MONSTER(pAttackItem->Kind))
//	{
//		sprintf(WeaponTypeString, STRMSG_S_F2NOTIFY_0005, pAttackItem->ItemName);
//	}
//	else
//	{
//		// invalid item kind
//		sprintf(WeaponTypeString, STRMSG_S_F2NOTIFY_0006);
//	}
//#endif
//
//	///////////////////////////////////////////////////////////////////////////
//	// 공격자와 피공격자 결정
//	///////////////////////////////////////////////////////////////////////////
//	if (type == C2C)
//	{
//		pAttackCharacter = (CHARACTER*)pAttackUnit;
//		pTargetCharacter = (CHARACTER*)pTargetUnit;
//
//		pAttackParamFactor = &pAttackSocket->m_ParamFactor;
//		pTargetParamFactor = &pTargetSocket->m_ParamFactor;
//	}
//	else if (type == C2M)
//	{
//		pAttackCharacter = (CHARACTER*)pAttackUnit;
//		pTargetMonster = (CFieldMonster*)pTargetUnit; pTargetMonsterInfo = pTargetMonster->MonsterInfoPtr;
//
//		pAttackParamFactor = &pAttackSocket->m_ParamFactor;
//	}
//	else if (type == M2C)
//	{
//		pAttackMonster = (CFieldMonster*)pAttackUnit; pAttackMonsterInfo = pAttackMonster->MonsterInfoPtr;
//		pTargetCharacter = (CHARACTER*)pTargetUnit;
//
//		pTargetParamFactor = &pTargetSocket->m_ParamFactor;
//	}
//	else
//	{
//		*pDamageKind = DAMAGEKIND_NO_DAMAGE;
//		return 0.0f;
//	}
//
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-14 by dhjin, 아레나 맵에서는 몬스터 공격시 데미지가 0이다.
//	if(C2M == type
//		&& IS_MAP_INFLUENCE_ARENA(pAttackSocket->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
//	{
//		return 0.0f;
//	}
//	
//	//////////////////////////////////////////////////////////////////////////
//	// 2006-11-24 by dhjin, A기어의 고급무기에 대한 무적스킬이면 데미지 0
//	if(pTargetParamFactor 
//		&& TRUE == pTargetSocket->CheckSKILLBarrier()
//		&& (IS_SECONDARY_WEAPON(pAttackItem->Kind) || IS_SECONDARY_WEAPON_MONSTER(pAttackItem->Kind)))
//	{
//		return 0.0f;
//	}
//
//	//////////////////////////////////////////////////////////////////////////
//	// 2006-11-27 by dhjin, M기어의 무적이면 데미지 0
//	if (pTargetParamFactor 
//		&& TRUE == pTargetSocket->CheckSKILLInvincible())
//	{
//		return 0.0f;
//	}
//
//	//////////////////////////////////////////////////////////////////////////
//	// 2006-11-30 by dhjin, B기어의 빅붐이면 자신의 HP로 데미지
//	if (IS_EXIST_DES_PARAM(pAttackItem, DES_SKILL_BIG_BOOM))
//	{
//		// DAMAGE 표시하기
//		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
//		pMsgShowDamage->AmountDamage	= pAttackSocket->CalcSKILLBigBoom();
//		pMsgShowDamage->DamageKind		= *pDamageKind;
//		
//		switch(type)
//		{
//		case C2C:
//		case C2CI:
//			{
//				pMsgShowDamage->TargetIndex		= pTargetCharacter->ClientIndex;
//
//				pTargetSocket->DecreaseCharacterHPDP(pMsgShowDamage->AmountDamage, DAMAGE_BY_PK, TRUE, NULL, pAttackSocket);
//				pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//				pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//			}
//			break;
//		case C2M:
//			{
//				pMsgShowDamage->TargetIndex		= pTargetMonster->MonsterIndex;
//
//				pAttackSocket->InsertAttackTargetIndexVector(pTargetMonster->MonsterIndex);
//
//				///////////////////////////////////////////////////////////////////////////////
//				// 2006-07-21 by cmkwon, Aggro 추가
//				vectActionInfo tmAggroList;
//				pAttackSocket->GetAggroList(&tmAggroList);
//
//				float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter(pMsgShowDamage->AmountDamage, pAttackSocket, &tmAggroList);	// 2006-07-21 by cmkwon, Aggro 적용
//				pAttackSocket->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pTargetMonster, T_FN_MONSTER_CHANGE_HP);
//				if (fMonCurHP <= 0.0f)
//				{// 몬스터가 폭파된 경우
//
//					OnMonsterDead(pAttackSocket, pAttackCharacter, pTargetSocket, (CFieldMonster*)pTargetMonster, pAttackItem);
//				}
//				pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));								
//			}
//			break;
//		}
//		
//		return pMsgShowDamage->AmountDamage;
//	}
//
//	///////////////////////////////////////////////////////////////////////////
//	// 공격 확률 계산
//	///////////////////////////////////////////////////////////////////////////
//	if (type == C2C)
//	{
//		fAttackProbability = CAtumSJ::GetAttackProbabilityC(pAttackItem, pAttackParamFactor, bIsPrimaryAttack, pAttackCharacter->TotalGearStat.AttackPart);
//		fDefenseProbability = CAtumSJ::GetDefenseProbabilityC(pTargetCharacter, NULL, pTargetParamFactor, bIsPrimaryAttack);
//	}
//	else if (type == C2M)
//	{
//		fAttackProbability = CAtumSJ::GetAttackProbabilityC(pAttackItem, pAttackParamFactor, bIsPrimaryAttack, pAttackCharacter->TotalGearStat.AttackPart);
//		fDefenseProbability = CAtumSJ::GetDefenseProbabilityM(pTargetMonsterInfo);
//
//		if ((pTargetMonster->MonsterInfoPtr->Level - pAttackCharacter->Level) >= 1)
//		{// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 캐릭터의 공격 성공 확률 5% 감소
//			
//			fAttackProbability -= 0.05f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - pAttackCharacter->Level);
//		}
//	}
//	else if (type == M2C)
//	{
//		fAttackProbability = CAtumSJ::GetAttackProbabilityM(pAttackMonsterInfo, pAttackItem);
//		fDefenseProbability = CAtumSJ::GetDefenseProbabilityC(pTargetCharacter, NULL, pTargetParamFactor, bIsPrimaryAttack);
//
//		if ((pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level) >= 1)
//		{
//			// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 몬스터의 공격 성공 확률 2% 증가
//			fAttackProbability += 0.02f*PROB256_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level);
//		}
//	}
//	fAttackSuccessProbability = fAttackProbability - fDefenseProbability;
//
//	///////////////////////////////////////////////////////////////////////////
//	// 캐릭터이며, 1-1형 무기인 경우: 아이템의 Range의 50% 거리까지 "공격확률"을 감소시킨다.
//	///////////////////////////////////////////////////////////////////////////
//	if ( (type == C2C || type == C2M) && IS_PRIMARY_WEAPON_1(pAttackItem->Kind)
//		&& (fSkillAppliedAttackRange < fActualAttackDistance) )
//	{
//		float fTmpMultValue = 0.0f;
//		if (fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER >= fActualAttackDistance)
//		{
//			fTmpMultValue = (2*(MIN_ATTACK_DECREASE_FACTOR-1)*fActualAttackDistance/fSkillAppliedAttackRange + 3 - 2*MIN_ATTACK_DECREASE_FACTOR);
//		}
//		else if (IS_IN_RANGE(fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER,
//								fActualAttackDistance,
//								fSkillAppliedAttackRange*2)
//		)
//		{
//			fTmpMultValue = MIN_ATTACK_DECREASE_FACTOR;
//		}
//		else if (fSkillAppliedAttackRange*2 < fActualAttackDistance)
//		{
//			// 2배가 넘어가면 0
//			fTmpMultValue = 0.0f;
//		}
//
//		fAttackSuccessProbability *= fTmpMultValue;
//
//#ifdef _DEBUG
////		pAttackSocket->SendString128Static(STRING_128_ADMIN_CMD, "1-1: %4.2f%%", fTmpMultValue*100);
//		pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0007,
//			fSkillAppliedAttackRange, fActualAttackDistance, 100.0f - 100.0f * fTmpMultValue);
////		pAttackSocket->SendString128(STRING_128_DEBUG_L3, "%s->%s 확률(%5.2f)", WeaponTypeString, pTargetMonster->MonsterInfoPtr->MonsterName, fAttackSuccessProbability);
//#endif
//	}
//
//	nRand = RAND256();
//	if (nRand > (int)fAttackSuccessProbability)
//	{
//		// 확률 안에 들지 못 함
//
//		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamageMiss, pMsgShowDamageMissBuf);
//		pMsgShowDamageMiss->AmountDamage = 0.0f;
//		pMsgShowDamageMiss->DamageKind = DAMAGEKIND_NO_DAMAGE;
//
//		if (type == C2C)
//		{
//			pMsgShowDamageMiss->TargetIndex = pTargetCharacter->ClientIndex;
//			pAttackSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//			pTargetSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//			pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0008, WeaponTypeString, pTargetCharacter->CharacterName, nRand, fAttackSuccessProbability);
//		}
//		else if (type == C2M)
//		{
//			pMsgShowDamageMiss->TargetIndex = pTargetMonster->MonsterIndex;
//			pAttackSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//			pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0009,
//				WeaponTypeString, pTargetMonster->MonsterInfoPtr->MonsterName, nRand, fAttackSuccessProbability,
//				min(0.0f, 0.05f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - pAttackCharacter->Level)));
//		}
//		else if (type == M2C)
//		{
//			pMsgShowDamageMiss->TargetIndex = pTargetCharacter->ClientIndex;
//			pTargetSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//			pTargetSocket->SendString128(STRING_128_DEBUG_L2, STRMSG_S_F2NOTIFY_0010, WeaponTypeString, pAttackMonster->MonsterInfoPtr->MonsterName, nRand, fAttackSuccessProbability);
//		}
//		*pDamageKind = DAMAGEKIND_NO_DAMAGE;
//		return 0.0f;
//	}
//
//	///////////////////////////////////////////////////////////////////////////
//	// fAttack 계산
//	///////////////////////////////////////////////////////////////////////////
//	if (type == C2C || type == C2M)
//	{
//		fAttack = CAtumSJ::GetAttackC(pAttackCharacter, pAttackItem, pAttackParamFactor, bIsPrimaryAttack);
//	}
//	else if (type == M2C)
//	{
//		fAttack = CAtumSJ::GetAttackM(pAttackItem);
//
//		if ((pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level) >= 1)
//		{
//			// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 몬스터의 공격력 3% 증가
//			fAttack *= (1.0f + 0.03f*(pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level));
//		}
//	}
//
//	///////////////////////////////////////////////////////////////////////////
//	// 크리티컬 확인, check: 일단 CRITICAL은 계산 안 함, 20041109, kelovon with sjmin
//	///////////////////////////////////////////////////////////////////////////
////	if ((type == C2C || type == C2M) && (RAND256() <= (INT)(pAttackCharacter->AttackPart/2)))
////	{
////		// CRITICAL HIT
////		*pDamageKind = DAMAGEKIND_CRITICAL;
////		fDamage = fAttack;
////	}
////	else
//	{
//		///////////////////////////////////////////////////////////////////////////////
//		// 2005-06-30 by cmkwon, PierceAttack 확률 계산
//		int nPiercePercent = 0;
//		if(C2C == type || C2M == type)
//		{
//			nPiercePercent = CAtumSJ::GetAttackC_PierceAttackProbability(pAttackCharacter->TotalGearStat.AttackPart); 
//		}
//		else if(M2C	== type)
//		{
//			nPiercePercent = CAtumSJ::GetPierceAttackProbabilityM(pAttackMonster->MonsterInfoPtr->Level);
//		}
//
//		///////////////////////////////////////////////////////////////////////
//		// fDefense 계산
//		///////////////////////////////////////////////////////////////////////
//		if (type == C2C || type == M2C)
//		{
//			// 피공격자가 캐릭터이면
//			// 2007-01-04 by cmkwon, fDefense의 최소값 0.0f
//			fDefense = max(0.0f, CAtumSJ::GetDefenseC(pTargetCharacter, pTargetParamFactor, bIsPrimaryAttack) - nPiercePercent);
//			fDamage = fAttack*(PROB256_MAX_VALUE-fDefense)/PROB256_MAX_VALUE;
//		}
//		else if (type == C2M)
//		{
//			// 피공격자가 몬스터이면
//			// 2007-01-04 by cmkwon, fDefense의 최소값 0.0f
//			fDefense = max(0.0f, CAtumSJ::GetDefenseM(pTargetMonsterInfo) - nPiercePercent);
//			fDamage = fAttack*(PROB256_MAX_VALUE-fDefense)/PROB256_MAX_VALUE;
//		}
//	}
//
//	// 각과 거리에 따른 factor 적용
//	if (fDamageWeight >= 0.0f && fDamageWeight <= 1.0f)
//	{
//		fDamage *= fDamageWeight;
//	}
//	else
//	{
//		// check: abnormal error!
//		*pDamageKind = DAMAGEKIND_NO_DAMAGE;
//		return 0.0f;
//	}
//	fDamage = max(fDamage, 1.0f);
//	
//	///////////////////////////////////////////////////////////////////////////
//	// 캐릭터이며, 1-2형 무기인 경우: 아이템의 Range의 50% 거리까지 "데미지"를 감소시킨다.
//	///////////////////////////////////////////////////////////////////////////
//	// 2004-11-20 by cmkwon, 몬스터는 데미지 감소에 추가 처리
//	if (fSkillAppliedAttackRange < fActualAttackDistance
//		&& (IS_PRIMARY_WEAPON_2(pAttackItem->Kind) || IS_PRIMARY_WEAPON_MONSTER(pAttackItem->Kind))
//		)
//	{
//		float fTmpMultValue = 0.0f;
//		if (fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER >= fActualAttackDistance)
//		{
//			fTmpMultValue = (2*(MIN_ATTACK_DECREASE_FACTOR-1)*fActualAttackDistance/fSkillAppliedAttackRange + 3 - 2*MIN_ATTACK_DECREASE_FACTOR);
//		}
//		else if (IS_IN_RANGE(fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER,
//								fActualAttackDistance,
//								fSkillAppliedAttackRange*2)
//		)
//		{
//			fTmpMultValue = MIN_ATTACK_DECREASE_FACTOR;
//		}
//		else if (fSkillAppliedAttackRange*2 < fActualAttackDistance)
//		{
//			// 2배가 넘어가면 0
//			fTmpMultValue = 0.0f;
//		}
//
//		float fTempPreDamage = fDamage;
//
//		fDamage *= fTmpMultValue;
//
//#ifdef _DEBUG
////		pAttackSocket->SendString128Static(STRING_128_ADMIN_CMD, "1-2: %4.2f%%", fTmpMultValue*100);
//		pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0011,
//			fSkillAppliedAttackRange, fActualAttackDistance,
//			100.0f - 100.0f * fTmpMultValue, fTempPreDamage, fDamage);
//#endif
//	}
//
//	// Damage는 Attacker의 Max Attack을 넘을 수 없다
//	if (type == C2C || type == C2M)
//	{
//		fDamage = min(fDamage, CAtumSJ::GetMaxAttackC(pAttackCharacter, pAttackItem, pAttackParamFactor, bIsPrimaryAttack));
//	}
//	else if (type == M2C)
//	{
//		fDamage = min(fDamage, CAtumSJ::GetMaxAttackM(pAttackItem));
//	}
//
//	// DAMAGE 표시하기
//	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
//	pMsgShowDamage->AmountDamage = fDamage;
//	pMsgShowDamage->DamageKind = *pDamageKind;
//
//	if (type == C2C)
//	{
//		pMsgShowDamage->TargetIndex = pTargetCharacter->ClientIndex;
//		pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//		pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//		pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0012,
//										WeaponTypeString, pTargetCharacter->CharacterName,
//										fDamage, fAttack, (INT)fDefense,
//										nRand, fAttackSuccessProbability);
//		pTargetSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0013,
//										WeaponTypeString, pAttackCharacter->CharacterName,
//										fDamage, fAttack, (INT)fDefense,
//										nRand, fAttackSuccessProbability);
//	}
//	else if (type == C2M)
//	{
//		pMsgShowDamage->TargetIndex = pTargetMonster->MonsterIndex;
//		pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//		pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0014,
//			WeaponTypeString, pTargetMonster->MonsterInfoPtr->MonsterName, pTargetMonster->MonsterIndex, pTargetMonster->CurrentHP,
//			fDamage, fAttack, (INT)fDefense,
//			nRand, fAttackSuccessProbability);
//	}
//	else if (type == M2C)
//	{
//		pMsgShowDamage->TargetIndex = pTargetCharacter->ClientIndex;
//		pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
//
//		pTargetSocket->SendString128(STRING_128_DEBUG_L2, STRMSG_S_F2NOTIFY_0015,
//										WeaponTypeString, pAttackMonster->MonsterInfoPtr->MonsterName,
//										fDamage, fAttack, (INT)fDefense,
//										nRand, fAttackSuccessProbability);
//	}
//
//	///////////////////////////////////////////////////////////////////////////
//	// 데미지 계산 완료
//	///////////////////////////////////////////////////////////////////////////
//
//	// 캐릭터가 공격을 받았을 때 공통적으로 처리해야 하는 루틴
//	if (fDamage > 0.0f && (type == C2C || type == M2C))
//	{
//		// GRADUAL_HP_UP 취소
//// 		pTargetSocket->m_nRemainedTimeOfGradualHPUP = 0;
//	}
//
//	if (type == C2C)
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 공격자도 캐릭터, 피공격자도 캐릭터인 경우의 처리
//		///////////////////////////////////////////////////////////////////////
//
//// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
////		if (ItemFieldIndex != 0)
////		{
////			//////////////////////////////////////////
////			// 더미 가동 시
////			float fRemainedDamage = ApplyDummyDamage(pAttackItem, fDamage, ItemFieldIndex, pTargetSocket, pTargetCharacter);
////
////			if (fRemainedDamage > 0.0f)
////			{
////				pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_PK, TRUE, NULL, pAttackSocket);
////			}
////		}
////		else
////		{
////			//////////////////////////////////////////
////			// 더미 미가동시
////			pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_PK, TRUE, NULL, pAttackSocket);
////		}
//
//		//////////////////////////////////////////////////////////////////////////
//		// 2006-12-04 by dhjin
//		pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_PK, TRUE, NULL, pAttackSocket);
//	}
//	else if (type == M2C)
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 공격자가 몬스터, 피공격자가 캐릭터인 경우의 처리
//		///////////////////////////////////////////////////////////////////////
//
//// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
////		if (ItemFieldIndex != 0)
////		{
////			//////////////////////////////////////////
////			// 더미 가동 시
////			float fRemainedDamage = ApplyDummyDamage(pAttackItem, fDamage, ItemFieldIndex, pTargetSocket, pTargetCharacter);
////
////			if (fRemainedDamage > 0.0f)
////			{
////				pTargetSocket->DecreaseCharacterHPDP(fRemainedDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);
////			}
////		}
////		else
////		{
////			//////////////////////////////////////////
////			// 더미 미가동시
////#ifndef _ATUM_LOAD_TEST
////			pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);
////#else // _ATUM_LOAD_TEST
////			// 2004-03-11 cmkwon, LoadTest계정은 HP를 깍지 않는다.
////			if (0 != strnicmp(pTargetCharacter->AccountName, ATUM_LOAD_TEST_PREFIX_CHARACTER_NAME, ATUM_LOAD_TEST_PREFIX_CHARACTER_NAME_SIZE))
////			{
////				pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);
////			}
////#endif // _ATUM_LOAD_TEST
////		}
//
//		//////////////////////////////////////////////////////////////////////////
//		// 2006-12-04 by dhjin
//		// 2007-01-23 by cmkwon, _ATUM_LOAD_TEST부분 복구함
//#ifndef _ATUM_LOAD_TEST
//		pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);  // 2006-12-19 by dhjin, 몬스터에게 죽어도 패널티 없던 문제 수정.
//#else
//		// 2004-03-11 cmkwon, LoadTest계정은 HP를 깍지 않는다.
//		if (0 != strnicmp(pTargetCharacter->AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
//		{
//			pTargetSocket->DecreaseCharacterHPDP(fDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);  // 2006-12-19 by dhjin, 몬스터에게 죽어도 패널티 없던 문제 수정.
//		}
//#endif // END - _ATUM_LOAD_TEST
//
//	}
//	else if (type == C2M)
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 피공격자가 몬스터인 경우의 처리
//		///////////////////////////////////////////////////////////////////////
//		pAttackSocket->InsertAttackTargetIndexVector(pTargetMonster->MonsterIndex);
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 2006-07-21 by cmkwon, Aggro 추가
//		vectActionInfo tmAggroList;
//		pAttackSocket->GetAggroList(&tmAggroList);
//
//		float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter(fDamage, pAttackSocket, &tmAggroList);	// 2006-07-21 by cmkwon, Aggro 적용
//		pAttackSocket->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pTargetMonster, T_FN_MONSTER_CHANGE_HP);
//		if (fMonCurHP <= 0.0f)
//		{// 몬스터가 폭파된 경우
//
//			OnMonsterDead(pAttackSocket, pAttackCharacter, pTargetSocket, (CFieldMonster*)pTargetMonster, pAttackItem);
//		}
//	}
//	return fDamage;
//}


///////////////////////////////////////////////////////////////////////////////
/// \fn			float CFieldIOCPSocket::CalcDamageOfAttackNew(BYTE *o_pDamageKind, enumAttackToTarget i_attType, float i_fDamageWeight
/// \brief		// 2007-06-07 by cmkwon, 2형무기 계산식 시스템 변경으로 함수변경(CalcDamageOfAttackNew<-CalcDamageOfAttack)
/// \author		cmkwon
/// \date		2007-06-07 ~ 2007-06-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
float CFieldIOCPSocket::CalcDamageOfAttackNew(BYTE *o_pDamageKind, enumAttackToTarget i_attType, float i_fDamageWeight,
						  CFieldIOCPSocket *i_pAttackSocket, void* i_pAttackUnit, SATTACK_PARAMETER *i_pAttParam,
						  CFieldIOCPSocket *i_pTargetSocket, void *i_pTargetUnit, 
						  float fSkillAppliedAttackRange/*=0.0f*/, float fActualAttackDistance/*=0.0f*/)
{
	float	fRetDamage = 0.0f;

	if(0.0f >= i_fDamageWeight
		|| *o_pDamageKind == DAMAGEKIND_NO_DAMAGE)
	{
		return fRetDamage;
	}



	CHARACTER		*pAttackCharacter = NULL;		// 공격자가 캐릭터(C2C, C2M)
	CHARACTER		*pTargetCharacter = NULL;		// 피공격자가 캐릭터(C2C, M2C)
	CParamFactor	*pTargetParamFactor = NULL;		// 피공격자가 캐릭터(C2C, M2C)

	CFieldMonster	*pAttackMonster = NULL;			// 공격자가 몬스터(M2C)
	CFieldMonster	*pTargetMonster = NULL;			// 피공격자가 몬스터(C2M)
	MONSTER_INFO	*pTargetMonsterInfo = NULL;		// 피공격자가 몬스터(C2M)


	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 공격자와 피공격자 설정하기
	switch(i_attType)
	{
	case C2C:
		{
			pAttackCharacter	= (CHARACTER*)i_pAttackUnit;
			pTargetCharacter	= (CHARACTER*)i_pTargetUnit;
			pTargetParamFactor	= &i_pTargetSocket->m_ParamFactor;

			if(FALSE == i_pAttackSocket->IsValidCharacter()
				|| FALSE == i_pTargetSocket->IsValidCharacter())
			{
				return fRetDamage;
			}
		}
		break;
	case C2M:
		{
			pAttackCharacter	= (CHARACTER*)i_pAttackUnit;
			pTargetMonster		= (CFieldMonster*)i_pTargetUnit;
			pTargetMonsterInfo	= pTargetMonster->MonsterInfoPtr;
			if(FALSE == i_pAttackSocket->IsValidCharacter()
				|| FALSE == pTargetMonster->IsValidMonster())
			{
				return fRetDamage;
			}

			//////////////////////////////////////////////////////////////////////////
			// 2007-09-20 by cmkwon, 텔레포트 수정 - 텔레포트몬스터만 처리, 무적 상태 체크
			if(IS_TELEPORT_MONSTER(pTargetMonsterInfo->Belligerence)
				&& i_pAttackSocket->m_pCurrentFieldMapChannel->IsInvincibleTelePortState())
			{
				return fRetDamage;
			}
		}
		break;
	case M2C:
		{
			pAttackMonster		= (CFieldMonster*)i_pAttackUnit;
			pTargetCharacter	= (CHARACTER*)i_pTargetUnit;
			pTargetParamFactor	= &i_pTargetSocket->m_ParamFactor;
			if(FALSE == pAttackMonster->IsValidMonster()
				|| FALSE == i_pTargetSocket->IsValidCharacter())
			{
				return fRetDamage;
			}
		}
		break;
	default:
		{
			return fRetDamage;
		}
	}

	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, 아레나 맵에서는 캐릭터가 몬스터 공격시 데미지가 0이다.
	if(C2M == i_attType
		&& IS_MAP_INFLUENCE_ARENA(i_pAttackSocket->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		return fRetDamage;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew,
	BOOL bDamageDistributionToPartyMember = FALSE;

	
	//////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 피공격자가 캐릭터 일때
	if(C2C == i_attType || M2C == i_attType)
	{
		// 2007-06-07 by cmkwon, 피공격자가 A기어 배리어스킬 사용중일때 2형무기의 공격 데미지 0
		if(i_pTargetSocket->CheckSKILLBarrier()
			&& (IS_SECONDARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind) || IS_SECONDARY_WEAPON_MONSTER(i_pAttParam->pWeaponItemInfo->Kind)))
		{
			return fRetDamage;
		}

		// 2007-06-07 by cmkwon, 피공격자가 M기어 무적스킬 사용중이면 데미지 0
		if (i_pTargetSocket->CheckSKILLInvincible())
		{
			return 0.0f;
		}

		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew,
		bDamageDistributionToPartyMember	= i_pTargetSocket->IsDamageDistributionToPartyMember();	
	}

	//////////////////////////////////////////////////////////////////////////
	// 2006-11-30 by dhjin, B기어의 빅붐스킬이면 자신의 HP로 데미지
	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
	//if (IS_EXIST_DES_PARAM(i_pAttParam->pWeaponItemInfo, DES_SKILL_BIG_BOOM)
	if (i_pAttParam->pWeaponItemInfo->IsExistDesParam(DES_SKILL_BIG_BOOM)
		&& (C2C == i_attType || C2M == i_attType))
	{
		// DAMAGE 표시하기
		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
		pMsgShowDamage->AmountDamage	= i_pAttackSocket->CalcSKILLBigBoom();
		pMsgShowDamage->DamageKind		= *o_pDamageKind;
		pMsgShowDamage->byIsPrimaryWeapon	= IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind);	// 2008-12-03 by cmkwon, 데미지 정보에 1형,2형 정보 추가 - 
		pMsgShowDamage->MultiTargetIndex	= i_pAttParam->MultiTargetIndex;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가

		///////////////////////////////////////////////////////////////////////////////
		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew, 빅붐, 본인에게는 50%를 적용한다.
		if(bDamageDistributionToPartyMember)
		{
			pMsgShowDamage->AmountDamage	= pMsgShowDamage->AmountDamage/2;

// 			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 임시용 로그
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804  CFieldIOCPSocket::CalcDamageOfAttackNew# 1 %s Damage(%5.2f) DamageTy(%d) Attacker(%s) \r\n"
// 				, GetCharacterString(i_pTargetSocket->GetCharacter(), string()), pMsgShowDamage->AmountDamage, DAMAGE_BY_PK, GetCharacterString(i_pAttackSocket->GetCharacter(), string()));
		}

		switch(i_attType)
		{
		case C2C:
			{
				pMsgShowDamage->TargetIndex		= pTargetCharacter->ClientIndex;

				i_pTargetSocket->DecreaseCharacterHPDP(pMsgShowDamage->AmountDamage, DAMAGE_BY_PK, TRUE, NULL, i_pAttackSocket);
				i_pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
				i_pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

				// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew, 빅붐, 편대원들에게는 10%
				if(bDamageDistributionToPartyMember)
				{
					i_pTargetSocket->DamageDistributionToPartyMember(pMsgShowDamage->AmountDamage/5, DAMAGE_BY_PK, TRUE, NULL, i_pAttackSocket, pMsgShowDamage);
				}
			}
			break;
		case C2M:
			{

				// 2010. 07. 20 by hsLee. 빅붐 버그 수정. ( 빅붐 스킬 사용 중에 시간제 장착 아이템 장착시 데미지 0으로 되는 문제 수정. ( 0 데미지 예외처리.) )
				if ( pMsgShowDamage->AmountDamage > 0 )
				{	// 데미지 '0'이 아닐 때에만 피 감소, 어그로 리스트 처리.

					// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
					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 ( FALSE == pTriggerFunction->OnIsPossibleBossAttack(pTargetMonster->MonsterInfoPtr->MonsterUnitKind) )
							{// 보스 몬스터가 공략 가능한 상태인지 체크
								pMsgShowDamage->AmountDamage = 0;					// 대미지 강제 초기화
								pMsgShowDamage->DamageKind = DAMAGEKIND_NO_DAMAGE;	// 미스 판정
							}
						}
					}
					// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인

					pMsgShowDamage->TargetIndex		= pTargetMonster->MonsterIndex;

					i_pAttackSocket->InsertAttackTargetIndexVector(pTargetMonster->MonsterIndex);

					///////////////////////////////////////////////////////////////////////////////
					// 2006-07-21 by cmkwon, Aggro 추가
					vectActionInfo tmAggroList;
						i_pAttackSocket->GetAggroList(&tmAggroList);

	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리 - 밑과 같이 수정
	//				float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter(pMsgShowDamage->AmountDamage, i_pAttackSocket, &tmAggroList);	// 2006-07-21 by cmkwon, Aggro 적용
					// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
					if( DAMAGEKIND_NO_DAMAGE != pMsgShowDamage->DamageKind )
					{
						pTargetMonster->ProcessingDamagedMonsterByCharacter(pMsgShowDamage->AmountDamage, i_pAttackSocket, &tmAggroList);	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리
					}
					// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - miss 판정이 아닐때만 어그로를 추가한다.
					float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHP(pMsgShowDamage->AmountDamage);
					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);
					}
				}

				i_pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));								
			}
			break;
		}
		
		return pMsgShowDamage->AmountDamage;
	}

	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 스킬 사용여부와 세력비에 따른 버프 효과 비율 계산
	float tmBuffPercent = 0.0f;
	if ( NULL != i_pTargetSocket )
	{
		if (TRUE == i_pTargetSocket->m_SkillManager.IsSkillActivatedByItemNum(TURN_AROUND_BUFF_SKILL_1ST) || TRUE == i_pTargetSocket->m_SkillManager.IsSkillActivatedByItemNum(TURN_AROUND_BUFF_SKILL_3RD))
		{
			// 2014-03-25 by jekim, 승리의 환호
			if(0 == ms_pFieldIOCP->m_InflWarManager.GetPVPBuffPercent(i_pTargetSocket->m_character.InfluenceType,&tmBuffPercent))
			{
				tmBuffPercent = 0.0f;
			}
			// end 2014-03-25 by jekim, 승리의 환호
		}
	}
	// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 스킬 사용여부와 세력비에 따른 버프 효과 비율 계산

	///////////////////////////////////////////////////////////////////////////////
	// 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;
	switch(i_attType)
	{
	case C2C:
		{
			fAttackProbability	= i_pAttParam->fAttackProbability;
			fDefenseProbability	= CAtumSJ::GetDefenseProbabilityC(pTargetCharacter, NULL, pTargetParamFactor, bIsPrimaryAttack, i_attType, tmBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
		}
		break;
	case C2M:
		{
			fAttackProbability	= i_pAttParam->fAttackProbability;
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
// 			if ((pTargetMonster->MonsterInfoPtr->Level - pAttackCharacter->Level) >= 1)
// 			{
// 				// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 캐릭터의 공격 성공 확률 5% 감소
// 				fAttackProbability -= 0.05f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - pAttackCharacter->Level);
// 			}
			if ((pTargetMonster->MonsterInfoPtr->Level - i_pAttackSocket->GetLvCheckRevision()) >= 1)
			{
				// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 캐릭터의 공격 성공 확률 5% 감소
				// 2010-07-19 by dhjin, 확률 수식 변경
				// fAttackProbability -= 0.05f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - i_pAttackSocket->GetLvCheckRevision());
				fAttackProbability -= 0.05f*PROB100_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - i_pAttackSocket->GetLvCheckRevision());
			}

			// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
			// fDefenseProbability	= CAtumSJ::GetDefenseProbabilityM(pTargetMonsterInfo);
			fDefenseProbability	= CAtumSJ::GetDefenseProbabilityM(pTargetMonsterInfo , &pTargetMonster->MonsterInfoExtend );
			// End 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
		}
		break;
	case M2C:
		{
			fAttackProbability	= i_pAttParam->fAttackProbability;
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
// 			if ((pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level) >= 1)
// 			{
// 				// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 몬스터의 공격 성공 확률 2% 증가
// 				fAttackProbability += 0.02f*PROB256_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - pTargetCharacter->Level);
// 			}
			if ((pAttackMonster->MonsterInfoPtr->Level - i_pTargetSocket->GetLvCheckRevision()) >= 1)
			{
				// 몬스터의 레벨이 캐릭터보다 높으면, 1 차이마다 몬스터의 공격 성공 확률 2% 증가
				// 2010-07-19 by dhjin, 확률 수식 변경
				// fAttackProbability += 0.02f*PROB256_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - i_pTargetSocket->GetLvCheckRevision());
				fAttackProbability += 0.02f*PROB100_MAX_VALUE*(pAttackMonster->MonsterInfoPtr->Level - i_pTargetSocket->GetLvCheckRevision());

			}

			fDefenseProbability	= CAtumSJ::GetDefenseProbabilityC(pTargetCharacter, NULL, pTargetParamFactor, bIsPrimaryAttack, i_attType, tmBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
		}
		break;
	default:
		{
			return fRetDamage;
		}
	}
	fAttackSuccessProbability = fAttackProbability - fDefenseProbability;

	///////////////////////////////////////////////////////////////////////////
	// 공격자가 캐릭터이며 1형 무기인 경우 아이템의 Range를 벗아난 경우 : 아이템의 Range의 50% 거리까지 "공격확률"을 감소시킨다.
	///////////////////////////////////////////////////////////////////////////
	if ( (i_attType == C2C || i_attType == C2M)
		&& IS_PRIMARY_WEAPON_1(i_pAttParam->pWeaponItemInfo->Kind)
		&& (fSkillAppliedAttackRange < fActualAttackDistance) )
	{
		float fTmpMultValue = 0.0f;
		if (fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER >= fActualAttackDistance)
		{
			fTmpMultValue = (2*(MIN_ATTACK_DECREASE_FACTOR-1)*fActualAttackDistance/fSkillAppliedAttackRange + 3 - 2*MIN_ATTACK_DECREASE_FACTOR);
		}
		else if ( IS_IN_RANGE(fSkillAppliedAttackRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER,
								fActualAttackDistance,
								fSkillAppliedAttackRange*2) )
		{
			fTmpMultValue = MIN_ATTACK_DECREASE_FACTOR;
		}
		else if (fSkillAppliedAttackRange*2 < fActualAttackDistance)
		{
			// 2배가 넘어가면 0
			fTmpMultValue = 0.0f;
		}
		fAttackSuccessProbability *= fTmpMultValue;

#ifdef _DEBUG
		i_pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0007,
			fSkillAppliedAttackRange, fActualAttackDistance, 100.0f - 100.0f * fTmpMultValue);
#endif
	}

	// 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인
	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 ( FALSE == pTriggerFunction->OnIsPossibleBossAttack(pTargetMonster->MonsterInfoPtr->MonsterUnitKind) )
			{// 보스 몬스터가 공략 가능한 상태인지 체크
				fAttackSuccessProbability = 0.0f;	// 명중률 0% 절대 안박힘!
			}
		}
	}
	// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 보스 몬스터 공격 가능 여부 확인

	// 2010-07-19 by dhjin, 확률 수식 변경
	float fRandProbability = RANDF2(0, 100);

	// 2013-05-10 by jhseol, 간헐적으로 몬스터가 공격을 하면 서버가 죽는 버그 수정
	BOOL bApplyItemIgnoreAvoid = FALSE;
	BOOL bApplyItemIgnoreDefence = FALSE;
	if ( NULL != i_pAttackSocket )
	{
		bApplyItemIgnoreAvoid = i_pAttackSocket->IsApplyItemIgnoreAvoid();
		bApplyItemIgnoreDefence = i_pAttackSocket->IsApplyItemIgnoreDefence();
	}
	// end 2013-05-10 by jhseol, 간헐적으로 몬스터가 공격을 하면 서버가 죽는 버그 수정
	
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 회피력 무시 아이템 사용 시 처리로 밑과 같이 수정
//	if(FALSE == ((C2M == i_attType || C2C == i_attType) &&  (TRUE == i_pAttackSocket->IsApplyItemIgnoreAvoid()))	// 2009-09-09 ~ 2010-01 by dhjin, 인피니티 - 소스 체크, C2C도 가능하게 수정
	if(FALSE == ((C2M == i_attType || C2C == i_attType) &&  (TRUE == bApplyItemIgnoreAvoid) )	// 2013-05-10 by jhseol, 간헐적으로 몬스터가 공격을 하면 서버가 죽는 버그 수정
		&& fRandProbability > fAttackSuccessProbability) {	// 2010-07-19 by dhjin, 확률 수식 변경

		INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamageMiss, pMsgShowDamageMissBuf);
		pMsgShowDamageMiss->AmountDamage	= 0.0f;
		pMsgShowDamageMiss->DamageKind		= DAMAGEKIND_NO_DAMAGE;
		pMsgShowDamageMiss->byIsPrimaryWeapon	= IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind);	// 2008-12-03 by cmkwon, 데미지 정보에 1형,2형 정보 추가 - 
		pMsgShowDamageMiss->MultiTargetIndex	= i_pAttParam->MultiTargetIndex;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		
		switch(i_attType)
		{
		case C2C:
			{
				pMsgShowDamageMiss->TargetIndex = pTargetCharacter->ClientIndex;
				i_pAttackSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
				i_pTargetSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
				
				i_pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0008, szWeaponTypeString, pTargetCharacter->CharacterName, fRandProbability, fAttackSuccessProbability);	// 2010-07-19 by dhjin, 확률 수식 변경
			}
			break;
		case C2M:
			{
				pMsgShowDamageMiss->TargetIndex = pTargetMonster->MonsterIndex;
				i_pAttackSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
				////////////////////////////////////////////////////////////////////////////////
				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
				i_pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0009,
					szWeaponTypeString, pTargetMonster->MonsterInfoPtr->MonsterName, fRandProbability, fAttackSuccessProbability,	// 2010-07-19 by dhjin, 확률 수식 변경
//					min(0.0f, 0.05f*PROB256_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - i_pAttackSocket->GetLvCheckRevision())));		
					min(0.0f, 0.05f*PROB100_MAX_VALUE*(pTargetMonster->MonsterInfoPtr->Level - i_pAttackSocket->GetLvCheckRevision())));		// 2010-07-19 by dhjin, 확률 수식 변경	
			}
			break;
		case M2C:
			{
				pMsgShowDamageMiss->TargetIndex = pTargetCharacter->ClientIndex;
				i_pTargetSocket->SendAddData(pMsgShowDamageMissBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

				i_pTargetSocket->SendString128(STRING_128_DEBUG_L2, STRMSG_S_F2NOTIFY_0010, szWeaponTypeString, pAttackMonster->MonsterInfoPtr->MonsterName, fRandProbability, fAttackSuccessProbability);	// 2010-07-19 by dhjin, 확률 수식 변경
			}
			break;
		}
		
		*o_pDamageKind = DAMAGEKIND_NO_DAMAGE;

#ifdef S_B_GEAR_DAMAGE_PROBABILITY_INFO			// 2013-05-06 by bckim, B기어 타겟 데미지 확인
		if ( NULL != i_pAttackSocket )
		{
			if( IS_BGEAR(i_pAttackSocket->m_character.UnitKind) )
			{
				g_pFieldGlobal->WriteSystemLogEX(FALSE, "###### [CharacterName(UID) : %s(%d)][fRetDamage: 0.000000] == MISS!!  \r\n",i_pAttackSocket->m_character.CharacterName,i_pAttackSocket->m_character.CharacterUniqueNumber);	// 2013-10-16 by jhseol, 서버 디버깅시 불필요 DBGOUT 출력 코드 제거
				g_pFieldGlobal->WriteSystemLogEX(FALSE, "###### [CharacterName(UID) : %s(%d)][fRandProbability:%f],[fAttackSuccessProbability:%f],[fAttackProbability:%f],[fDefenseProbability:%f]\r\n",i_pAttackSocket->m_character.CharacterName,i_pAttackSocket->m_character.CharacterUniqueNumber,fRandProbability,fAttackSuccessProbability,fAttackProbability,fDefenseProbability);	// 2013-10-16 by jhseol, 서버 디버깅시 불필요 DBGOUT 출력 코드 제거
			}
		}
#endif
		return 0.0f;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 2. 공격력/방어력 처리(피어스율적용)
	///////////////////////////////////////////////////////////////////////////////	
	float fDefense = 0.0f;
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 방어력 무시 아이템 사용 시 처리로 밑과 같이 수정
// 	if (i_attType == C2C || i_attType == M2C)
// 	{// 피공격자가 캐릭터
// 		
// 		// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 
// 		//fDefense	= max(0.0f, CAtumSJ::GetDefenseC(pTargetCharacter, pTargetParamFactor, bIsPrimaryAttack) - i_pAttParam->fPierceAttackProbability);
// 		///////////////////////////////////////////////////////////////////////////////
// 		// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력(0~255)
// 		fDefense	= CAtumSJ::GetDefenseC(pTargetCharacter, pTargetParamFactor, bIsPrimaryAttack) - i_pAttParam->fPierceAttackProbability;
// 	}
// 	else if (i_attType == C2M)
// 	{// 피공격자가 몬스터
// 
// 		// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 
// 		//fDefense	= max(0.0f, CAtumSJ::GetDefenseM(pTargetMonsterInfo) - i_pAttParam->fPierceAttackProbability);
// 		///////////////////////////////////////////////////////////////////////////////
// 		// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력(0~255)
// 		// 2009-12-24 by cmkwon, 몬스터 Defense를 인피니티서버(아레나포함)에서 고정값으로 처리 - 
// 		fDefense	= CAtumSJ::GetDefenseM(pTargetMonsterInfo, g_pFieldGlobal->IsArenaServer()) - i_pAttParam->fPierceAttackProbability;		
// 	}
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력Defense(0~255)
// 	fDefense	= max(0.0f, fDefense);
// 	fDefense	= min(PROB256_MAX_VALUE, fDefense);
//	if(FALSE == ( (C2M == i_attType || C2C == i_attType) &&  (TRUE == i_pAttackSocket->IsApplyItemIgnoreDefence()) ) )
	if(FALSE == ( (C2M == i_attType || C2C == i_attType) &&  (TRUE == bApplyItemIgnoreDefence) ) )		// 2013-05-10 by jhseol, 간헐적으로 몬스터가 공격을 하면 서버가 죽는 버그 수정
	{	// 2009-09-09 ~ 2010-01 by dhjin, 인피니티 - 소스 체크, C2C도 가능하게 수정
		if (i_attType == C2C || i_attType == M2C)
		{// 피공격자가 캐릭터
			
			// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 
			//fDefense	= max(0.0f, CAtumSJ::GetDefenseC(pTargetCharacter, pTargetParamFactor, bIsPrimaryAttack) - i_pAttParam->fPierceAttackProbability);
			///////////////////////////////////////////////////////////////////////////////
			// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력(0~255)
			fDefense	= CAtumSJ::GetDefenseC(pTargetCharacter, pTargetParamFactor, bIsPrimaryAttack, i_attType, tmBuffPercent) - i_pAttParam->fPierceAttackProbability;	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
		}
		else if (i_attType == C2M)
		{// 피공격자가 몬스터
			
			// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 
			//fDefense	= max(0.0f, CAtumSJ::GetDefenseM(pTargetMonsterInfo) - i_pAttParam->fPierceAttackProbability);
			///////////////////////////////////////////////////////////////////////////////
			// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력(0~255)
			// 2009-12-24 by cmkwon, 몬스터 Defense를 인피니티서버(아레나포함)에서 고정값으로 처리 - 
			//fDefense	= CAtumSJ::GetDefenseM(pTargetMonsterInfo, g_pFieldGlobal->IsArenaServer()) - i_pAttParam->fPierceAttackProbability;		
			// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
			fDefense	= CAtumSJ::GetDefenseM(pTargetMonsterInfo, g_pFieldGlobal->IsArenaServer() , &pTargetMonster->MonsterInfoExtend ) - i_pAttParam->fPierceAttackProbability;

		}
		///////////////////////////////////////////////////////////////////////////////
		// 2009-12-17 by cmkwon, 데미지 계산식 관련한 필드(방어력,회피,피어스,확률)에 255이상 값을 설정 가능하게 수정 - 방어력Defense(0~255)
		fDefense	= max(0.0f, fDefense);
		// 2010-07-19 by dhjin, 확률 수식 변경
//		fDefense	= min(PROB256_MAX_VALUE, fDefense);
		fDefense	= min(PROB100_MAX_VALUE, fDefense);
	}

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-07 by cmkwon, 3. 각과 거리에 따른 factor 적용 - 확률이 성공하면 최소 1의 데미지
	///////////////////////////////////////////////////////////////////////////////	
	// 2009-12-17 by cmkwon, 공격력의 10%는 데미지로 받도록 수정 - 
	// 2010-07-19 by dhjin, 확률 수식 변경
//	fRetDamage	= (i_pAttParam->fAttack*(PROB256_MAX_VALUE-fDefense)/PROB256_MAX_VALUE) * i_fDamageWeight;
	// 2010. 11. 25 by jskim, 펫 데이지 확률 수정
	if( *o_pDamageKind == DAMAGEKIND_PET )
	{
		if(i_pAttParam->pWeaponItemInfo)
		{
			if( RAND100() <= PROB100_MAX_VALUE - fDefense )
			{
				fRetDamage = rand() % (int)(i_pAttParam->pWeaponItemInfo->AbilityMax + 1 - i_pAttParam->pWeaponItemInfo->AbilityMin) + i_pAttParam->pWeaponItemInfo->AbilityMin;
			}
			else
			{
				*o_pDamageKind = DAMAGEKIND_NO_DAMAGE;
				fRetDamage = 0;
			}
			
			// 2010-12-21 by jskim, 파트너 데미지 증가 아이템 구현
			ITEM_GENERAL * pPartnerDamageItem = i_pAttackSocket->m_ItemManager.GetItemGeneralByDestParam( DES_RARE_ITEM_PARTNER_DAMAGE );
 			if( pPartnerDamageItem )
 			{
 				fRetDamage += fRetDamage * pPartnerDamageItem->ItemInfo->GetParameterValue( DES_RARE_ITEM_PARTNER_DAMAGE );
				i_pAttackSocket->m_ItemManager.UpdateItemCountByPointer( DES_RARE_ITEM_PARTNER_DAMAGE );
 			}
			// end 2010-12-21 by jskim, 파트너 데미지 증가 아이템 구현
		}
	}
	else
	{
		fRetDamage	= (i_pAttParam->fAttack*(PROB100_MAX_VALUE-fDefense)/PROB100_MAX_VALUE) * i_fDamageWeight;
	}
	// end 2010. 11. 25 by jskim, 펫 데이지 확률 수정
	// 2010-04-08 by cmkwon, C2C만 공격력 10%를 최소 데미지로 받는 시스템 적용처리 제외 - 
	//fRetDamage	= max(i_pAttParam->fMaxAttack*0.1f, fRetDamage);
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-08 by cmkwon, C2C만 공격력 10%를 최소 데미지로 받는 시스템 적용처리 제외 - 
	// 2010. 11. 25 by jskim, 펫 데이지 확률 수정
// 	if(i_attType == C2C)
// 	{
// 		fRetDamage	= max(1.0f, fRetDamage);
// 	}
// 	else
// 	{
// 		fRetDamage	= max(i_pAttParam->fMaxAttack*0.1f, fRetDamage);
// 	}
// 	fRetDamage	= min(i_pAttParam->fMaxAttack, fRetDamage);
	if( *o_pDamageKind != DAMAGEKIND_PET )
	{
		if(i_attType == C2C)
		{
			fRetDamage	= max(1.0f, fRetDamage);
		}
		else
		{
			fRetDamage	= max(i_pAttParam->fMaxAttack*0.1f, fRetDamage);
		}
		fRetDamage	= min(i_pAttParam->fMaxAttack, fRetDamage);
	}
	// end 2010. 11. 25 by jskim, 펫 데이지 확률 수정
	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew, 자신에게는 50% 적용
	if(bDamageDistributionToPartyMember)
	{
		fRetDamage	= fRetDamage/2;

// 		// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - 임시용 로그
// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [TEMP] 090804  CFieldIOCPSocket::CalcDamageOfAttackNew# 2 %s Damage(%5.2f) DamageTy(%d)\r\n"
// 			, GetCharacterString(i_pTargetSocket->GetCharacter(), string()), fRetDamage, DAMAGE_BY_PK);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 4. 데미지 클라이언트에 전송하기
	// DAMAGE 표시하기
	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE, T_FC_BATTLE_SHOW_DAMAGE, pMsgShowDamage, pMsgShowDamageBuf);
	pMsgShowDamage->AmountDamage	= fRetDamage;
	pMsgShowDamage->DamageKind		= *o_pDamageKind;
	pMsgShowDamage->byIsPrimaryWeapon	= IS_PRIMARY_WEAPON(i_pAttParam->pWeaponItemInfo->Kind);	// 2008-12-03 by cmkwon, 데미지 정보에 1형,2형 정보 추가 - 
	pMsgShowDamage->MultiTargetIndex	= i_pAttParam->MultiTargetIndex;		// 2011-04-01 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon
	switch(i_attType)
	{
	case C2C:
		{
			pMsgShowDamage->TargetIndex = pTargetCharacter->ClientIndex;
			i_pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));
			i_pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

			i_pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0012,
											szWeaponTypeString, pTargetCharacter->CharacterName,
											fRetDamage, i_pAttParam->fAttack, (INT)fDefense,
											fRandProbability, fAttackSuccessProbability);			// 2010-07-19 by dhjin, 확률 수식 변경
			i_pTargetSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0013,
											szWeaponTypeString, pAttackCharacter->CharacterName,
											fRetDamage, i_pAttParam->fAttack, (INT)fDefense,
											fRandProbability, fAttackSuccessProbability);			// 2010-07-19 by dhjin, 확률 수식 변경
		}
		break;
	case C2M:
		{
			pMsgShowDamage->TargetIndex = pTargetMonster->MonsterIndex;
			i_pAttackSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

			i_pAttackSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0014,
				szWeaponTypeString, pTargetMonsterInfo->MonsterName, pTargetMonster->MonsterIndex, pTargetMonster->CurrentHP,
				fRetDamage, i_pAttParam->fAttack, (INT)fDefense,
				fRandProbability, fAttackSuccessProbability);			// 2010-07-19 by dhjin, 확률 수식 변경
		}
		break;
	case M2C:
		{
			pMsgShowDamage->TargetIndex = pTargetCharacter->ClientIndex;
			i_pTargetSocket->SendAddData(pMsgShowDamageBuf, MSG_SIZE(MSG_FC_BATTLE_SHOW_DAMAGE));

			i_pTargetSocket->SendString128(STRING_128_DEBUG_L2, STRMSG_S_F2NOTIFY_0015,
											szWeaponTypeString, pAttackMonster->MonsterInfoPtr->MonsterName,
											fRetDamage, i_pAttParam->fAttack, (INT)fDefense,
											fRandProbability, fAttackSuccessProbability);		// 2010-07-19 by dhjin, 확률 수식 변경
		}
		break;
	}

	///////////////////////////////////////////////////////////////////////////
	// 2007-06-07 by cmkwon, 계산된 데미지 적용
	///////////////////////////////////////////////////////////////////////////
	switch(i_attType)
	{
	case C2C:
		{
			// 2012-07-10 by jhseol, 아레나 판정 - 데미지 누적
			if(TRUE == g_pFieldGlobal->IsArenaServer()) 
			{
				if( ARENA_STATE_FIGHTING_WARING == i_pAttackSocket->m_ArenaInfo.State )
				{
					CArenaDeathMatchRoom * tmArenaDMRoom = ms_pFieldIOCP->m_ArenaManager.GetArenaDeathMatchRoom(i_pAttackSocket->m_ArenaInfo.DeathMatchRoomNum);
					if( NULL != tmArenaDMRoom )
					{
						if( i_pAttackSocket->m_ArenaInfo.TeamNum == tmArenaDMRoom->GetVCNTeamNum() )
						{
							tmArenaDMRoom->m_fVCNTeamDamage += fRetDamage;
						}
						else if( i_pAttackSocket->m_ArenaInfo.TeamNum == tmArenaDMRoom->GetANITeamNum() )
						{
							tmArenaDMRoom->m_fANITeamDamage += fRetDamage;
						}
					}
					else
					{
						g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENA] No Search DeathMatchRoom In Damage Check!!\r\n");
					}
				}
			}
			// end 2012-07-10 by jhseol, 아레나 판정 - 데미지 누적
			i_pTargetSocket->DecreaseCharacterHPDP(fRetDamage, DAMAGE_BY_PK, TRUE, NULL, i_pAttackSocket);

			///////////////////////////////////////////////////////////////////////////////
			// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew, 편대원들에게는 10%
			if(bDamageDistributionToPartyMember)
			{
				i_pTargetSocket->DamageDistributionToPartyMember(fRetDamage/5, DAMAGE_BY_PK, TRUE, NULL, i_pAttackSocket, pMsgShowDamage);
			}

#ifdef S_B_GEAR_DAMAGE_PROBABILITY_INFO			// 2013-05-06 by bckim, B기어 타겟 데미지 확인
			if( IS_BGEAR(i_pAttackSocket->m_character.UnitKind) )
			{
				g_pFieldGlobal->WriteSystemLogEX(FALSE, "###### [CharacterName(UID) : %s(%d)][fRetDamage:%f] == HIT!! ( [i_pAttParam->fAttack:%f] * (100 - [fDefense: %f]) / 100 ) * 100 ) * [i_fDamageWeight:%f]\r\n",i_pAttackSocket->m_character.CharacterName,i_pAttackSocket->m_character.CharacterUniqueNumber,fRetDamage,i_pAttParam->fAttack,fDefense,i_fDamageWeight);	// 2013-10-16 by jhseol, 서버 디버깅시 불필요 DBGOUT 출력 코드 제거
				g_pFieldGlobal->WriteSystemLogEX(FALSE, "###### [CharacterName(UID) : %s(%d)][fRandProbability:%f],[fAttackSuccessProbability:%f],[fAttackProbability:%f],[fDefenseProbability:%f]\r\n",i_pAttackSocket->m_character.CharacterName,i_pAttackSocket->m_character.CharacterUniqueNumber,fRandProbability,fAttackSuccessProbability,fAttackProbability,fDefenseProbability);		// 2013-10-16 by jhseol, 서버 디버깅시 불필요 DBGOUT 출력 코드 제거
			}
#endif

			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 드레인
			i_pAttackSocket->ApplyInvokingItemDrain(fRetDamage, i_pAttackSocket, i_pTargetSocket, NULL);
			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 미러링
			i_pTargetSocket->ApplyInvokingItemReflection(fRetDamage, i_pTargetSocket, i_pAttackSocket, NULL);
		}
		break;
	case M2C:		// 공격자가 몬스터, 피공격자가 캐릭터인 경우의 처리
		{		
// 2009-08-17 by cmkwon, 아래와 같이 수정함.
//#ifndef _ATUM_LOAD_TEST
//			i_pTargetSocket->DecreaseCharacterHPDP(fRetDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);  // 2006-12-19 by dhjin, 몬스터에게 죽어도 패널티 없던 문제 수정.
//#else
#if defined(_ATUM_LOAD_TEST)
			// 2004-03-11 cmkwon, LoadTest계정은 HP를 깍지 않는다.
			if (0 != strnicmp(pTargetCharacter->AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
			{
#endif // END - #if defined(_ATUM_LOAD_TEST)
				i_pTargetSocket->DecreaseCharacterHPDP(fRetDamage, DAMAGE_BY_MONSTER, TRUE, pAttackMonster);  // 2006-12-19 by dhjin, 몬스터에게 죽어도 패널티 없던 문제 수정.

				///////////////////////////////////////////////////////////////////////////////
				// 2009-08-03 by cmkwon, EP3-4 편대 대형 스킬 구현 - CalcDamageOfAttackNew, 편대원들에게는 10%
				if(bDamageDistributionToPartyMember)
				{
					i_pTargetSocket->DamageDistributionToPartyMember(fRetDamage/5, DAMAGE_BY_PK, TRUE, pAttackMonster, NULL, pMsgShowDamage);
				}

#if defined(_ATUM_LOAD_TEST)
			}
#endif // END - #if defined(_ATUM_LOAD_TEST)
			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 미러링
			i_pTargetSocket->ApplyInvokingItemReflection(fRetDamage, i_pTargetSocket, NULL, pAttackMonster);
		}
		break;
	case C2M:		// 공격자가 캐릭터, 피공격자가 몬스터인 경우의 처리
		{
			i_pAttackSocket->InsertAttackTargetIndexVector(pTargetMonster->MonsterIndex);

			///////////////////////////////////////////////////////////////////////////////
			// 2006-07-21 by cmkwon, Aggro 추가
			vectActionInfo tmAggroList;
			i_pAttackSocket->GetAggroList(&tmAggroList);

			// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리 - 밑과 같이 수정
//			float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHPByCharacter(fRetDamage, i_pAttackSocket, &tmAggroList);	// 2006-07-21 by cmkwon, Aggro 적용
			pTargetMonster->ProcessingDamagedMonsterByCharacter(fRetDamage, i_pAttackSocket, &tmAggroList);	// 2010-03-18 by dhjin, 몬스터 피 감소 처리 루틴 정리
			float	fMonCurHP = pTargetMonster->DecreaseMonsterCurrentHP(fRetDamage);
			i_pAttackSocket->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pTargetMonster, T_FN_MONSTER_CHANGE_HP);

			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef S_BOSS_MONSTER_DAMAGE_LOG_BY_SP_MS_OP	// 2014-03-31 by bckim, 거점,모선,전진기지 데미지 로그 ( 캐나다 요청)			
			if( 0.0f < fMonCurHP )
			{
				int nlogtype = 0;
				if( COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption,MPOPTION_BIT_BOSS_MONSTER) 
					&& ( BELL_INFLUENCE_VCN == pTargetMonster->MonsterInfoPtr->Belligerence 
					|| BELL_INFLUENCE_ANI == pTargetMonster->MonsterInfoPtr->Belligerence ) )
				{
					nlogtype = DAMAGE_LOG_MONSTER_MS;	// 모선전 : 보스몬스터 이고 벨리언스 값이 10,11
					CAtumLogSender::SendLogMessageAllMonsterKillLog( nlogtype, i_pAttackSocket,pTargetMonster,fRetDamage);
				}
				
				if( BELL_STRATEGYPOINT_VCN == pTargetMonster->MonsterInfoPtr->Belligerence 
					|| BELL_STRATEGYPOINT_ANI == pTargetMonster->MonsterInfoPtr->Belligerence )
				{
					nlogtype = DAMAGE_LOG_MONSTER_SP;	// 거점 : 몬스터 구분 벨리언스값이 12, 13
					CAtumLogSender::SendLogMessageAllMonsterKillLog( nlogtype, i_pAttackSocket,pTargetMonster,fRetDamage);
				}
				
				if( COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption,MPOPTION_BIT_BOSS_MONSTER) 
					&& ( BELL_OUTPOST_PROTECTOR_VCN == pTargetMonster->MonsterInfoPtr->Belligerence 
					|| BELL_OUTPOST_PROTECTOR_ANI == pTargetMonster->MonsterInfoPtr->Belligerence ))
				{
					nlogtype = DAMAGE_LOG_MONSTER_OP;	// 전진기지전 : 보스몬스터이고, 벨리언스값이 14,15,16,17 
					CAtumLogSender::SendLogMessageAllMonsterKillLog( nlogtype, i_pAttackSocket,pTargetMonster,fRetDamage);
				}
			}		
#endif			// End. 2014-03-31 by bckim, 거점,모선,전진기지 데미지 로그 ( 캐나다 요청)		

#ifdef S_ALL_MONSTER_KILL_LOG	// 2014-03-31 by bckim, 모든 몬스터 킬로그 ( 캐나다 요청) 					
			if (fMonCurHP <= 0.0f )
			{
				int MonsterLogType = KILL_LOG_MONSTER_NORMAL;
				CAtumLogSender::SendLogMessageAllMonsterKillLog( MonsterLogType, i_pAttackSocket,pTargetMonster,fRetDamage);
			}
#endif				// End. 2014-03-31 by bckim, 모든 몬스터 킬로그 ( 캐나다 요청) 			
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


			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++;
				}

				// 2014-01-08 by jhseol, 보스몬스터 보상강화 보완 - CFieldIOCPSocket::OnMonsterDead() 내부로 이동 주석처리
// 				// 2013-08-28 by bckim, 보스몬스터 보상강화
// #ifdef SC_BOSS_MONSTER_REWARD_BCKIM_SSJUNG
// 				if( FALSE == g_pFieldGlobal->IsArenaServer() 
// 					&& TRUE == COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER) )
// 				{					
// 					RewardOfBossMonster(i_pAttackSocket, pTargetMonster);
// 				}				
// #endif
// 				// End. 2013-08-28 by bckim, 보스몬스터 보상강화		
				// end 2014-01-08 by jhseol, 보스몬스터 보상강화 보완 - CFieldIOCPSocket::OnMonsterDead() 내부로 이동 주석처리

				OnMonsterDead(i_pAttackSocket, pAttackCharacter, NULL, (CFieldMonster*)pTargetMonster, i_pAttParam->pWeaponItemInfo);
			}

			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 드레인
			i_pAttackSocket->ApplyInvokingItemDrain(fRetDamage, i_pAttackSocket, NULL, pTargetMonster);
		}
		break;
	}

	return fRetDamage;
}


// 2013-08-28 by bckim, 보스몬스터 보상강화
BOOL CFieldIOCPSocket::RewardOfBossMonster(CFieldIOCPSocket *pLastAttackedUser, CFieldMonster *pTargetMonster)
{
	if( NULL == pTargetMonster )
	{
		return FALSE;
	}

	float nMinDamage	= max(pTargetMonster->MonsterInfoPtr->MonsterRewardInfo.fMinDamege, 0.0f);	// 해당 몬스터의 누적데미지의 최저량 
	INT nMaxPerson		= max(pTargetMonster->MonsterInfoPtr->MonsterRewardInfo.nMaxPerson, 0 );	// 해당 몬스터의 보상인원 제한 
	INT nRewardItemNum	= pTargetMonster->MonsterInfoPtr->MonsterRewardInfo.ItemNum;				// 해당 몬스터에 따르는 보상아이템 

	MAP_CHANNEL_INDEX tmpMonsterMap	= pTargetMonster->GetCurrentMapChannelMonster()->GetMapChannelIndex();

	ITEM * pItemInfo = ms_pFieldIOCP->GetItemInfo(nRewardItemNum);	
	if(  NULL == pItemInfo )	
	{
		return FALSE;
	}

	// 2. 최초로 보스몬스터에게 데미지를 입힌 유져 
	if( IS_VALID_CLIENT_INDEX( pTargetMonster->m_nFirstUserAttacks) )
	{
		CFieldIOCPSocket *tmpFirstAttackedUser = ms_pFieldIOCP->GetFieldIOCPSocket(pTargetMonster->m_nFirstUserAttacks);	
		float ftmpSumDamage =  pTargetMonster->GetSumDamageByClientIDX(pTargetMonster->m_nFirstUserAttacks);
		if( NULL != tmpFirstAttackedUser && ftmpSumDamage >= nMinDamage )
		{										
			tmpFirstAttackedUser->m_ItemManager.InsertBossRewardItemByItemNum(nRewardItemNum, 2, pTargetMonster);			
		}
	}
	// 4. 마지막으로 보스몬스터를 죽인 유져 
	if(  NULL != pLastAttackedUser )
	{
		float ftmpSumDamage =  pTargetMonster->GetSumDamageByClientIDX(pLastAttackedUser->m_character.ClientIndex);
		if( ftmpSumDamage >= nMinDamage )
		{		
			pLastAttackedUser->m_ItemManager.InsertBossRewardItemByItemNum(nRewardItemNum, 4, pTargetMonster);
		}
	}

	mtvectorActionInfoPtr tmpRewardAttackedInfo;
	if( FALSE == pTargetMonster->GetSortActionInfoByMaxDamage(&tmpRewardAttackedInfo)
		||tmpRewardAttackedInfo.empty()	)
	{
		return FALSE;	
	}
	
	
	// 2013-10-02 by bckim, 보스몬스터 보상강화 스트링 보완작업 
	{
		mt_auto_lock mtA(&pTargetMonster->m_mtvectorRewardInfoPtr);
		mtvectorActionInfoPtr::iterator itr(pTargetMonster->m_mtvectorRewardInfoPtr.begin());					
		for(; itr != pTargetMonster->m_mtvectorRewardInfoPtr.end(); itr++)
		{
			CFieldIOCPSocket *tmpRewardUser = ms_pFieldIOCP->GetFieldIOCPSocket((*itr)->UnitIndex);
			if( NULL != tmpRewardUser && TRUE == tmpRewardUser->IsValidCharacter(FALSE) )
			{
				tmpRewardUser->SendString128(STRING_128_USER_OPERATOR,STRMSG_130828_0005, pTargetMonster->MonsterInfoPtr->MonsterName);
			}		
		}
		mtA.auto_unlock_cancel();
	}
	// End. 2013-10-02 by bckim, 보스몬스터 보상강화 스트링 보완작업

	mtvectorActionInfoPtr::iterator itr_reward(tmpRewardAttackedInfo.begin());
	// 3. 보스몬스터에게 가장 많은 데미지를 준 유져 // 제일 첨에 있는 놈이 데미지를 많이 준 놈이다. 
	CFieldIOCPSocket *tmpMaxSumDamagedUser = ms_pFieldIOCP->GetFieldIOCPSocket((*itr_reward)->UnitIndex);				
	if( NULL != tmpMaxSumDamagedUser )
	{
		tmpMaxSumDamagedUser->m_ItemManager.InsertBossRewardItemByItemNum(nRewardItemNum, 3, pTargetMonster);
	}
	
	if( nMaxPerson )
	{
		int nCount = 0;
		while( itr_reward != tmpRewardAttackedInfo.end())
		{
			CFieldIOCPSocket *tmpRewardUser = ms_pFieldIOCP->GetFieldIOCPSocket((*itr_reward)->UnitIndex);
			if( NULL == tmpRewardUser )
			{
				itr_reward++;
				continue;
			}

			if( nCount < nMaxPerson )		// 위에서 제일 많이 떄린놈 줬음. 
			{
				// 1. 보스몬스터에게 데미지를 입힌 유져
				if( TRUE == tmpRewardUser->m_ItemManager.InsertBossRewardItemByItemNum(nRewardItemNum, 1, pTargetMonster) )
				{
					nCount++;
				}
			}
			itr_reward++;
		}
	}
	else
	{
		while( itr_reward != tmpRewardAttackedInfo.end())
		{
			CFieldIOCPSocket *tmpRewardUser = ms_pFieldIOCP->GetFieldIOCPSocket((*itr_reward)->UnitIndex);
			if( NULL == tmpRewardUser )
			{
				itr_reward++;
				continue;
			}
			tmpRewardUser->m_ItemManager.InsertBossRewardItemByItemNum(nRewardItemNum, 1, pTargetMonster);
			itr_reward++;
		}	
	}
	return TRUE;
}
// End. 2013-08-28 by bckim, 보스몬스터 보상강화




// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
//float CFieldIOCPSocket::ApplyDummyDamage(ITEM *i_pAttackItem, float i_fDamage, UINT i_nItemFieldIndex, CFieldIOCPSocket *i_pTargetSocket, CHARACTER *i_pTargetCharacter)
//{
//	if (i_pTargetSocket == NULL || !i_pTargetSocket->IsUsing())
//	{
//		return 0;
//	}
//
//	// lock m_mapFieldDummy
//	mt_auto_lock dummyLock(&i_pTargetSocket->m_mapFieldDummy);
//
//	//////////////////////////////////////////
//	// 더미 가동 시, 더미의 내구도만 감소
//	FIELD_DUMMY *pDummy = i_pTargetSocket->m_mapFieldDummy.findLock(i_nItemFieldIndex);
//	if (pDummy == NULL)
//	{
//		// 타이머 이벤트 혹은 먼저 온 무기에 의해 맞아서 사라진 경우
//		return i_fDamage;
//	}
//
//	if (pDummy->pItemInfo->DestParameter1 == DES_PRIMARY_WEAPON)
//	{
//		if (!IS_PRIMARY_WEAPON(i_pAttackItem->Kind) && !IS_PRIMARY_WEAPON_MONSTER(i_pAttackItem->Kind))
//		{
//			return i_fDamage;
//		}
//	}
//	else if (pDummy->pItemInfo->DestParameter1 == DES_SECONDARY_WEAPON)
//	{
//		if (!IS_SECONDARY_WEAPON(i_pAttackItem->Kind) && !IS_SECONDARY_WEAPON_MONSTER(i_pAttackItem->Kind))
//		{
//			return i_fDamage;
//		}
//	}
//	else
//	{
//// 2005-04-25 by cmkwon
////		ASSERT_NEVER_GET_HERE();
//		return i_fDamage;
//	}
//
//	// Hit Rate 확인
//	if (RAND256() > pDummy->pItemInfo->HitRate)
//	{
//#ifdef _DEBUG
//		i_pTargetSocket->SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0016, pDummy->pItemInfo->HitRate);
//#endif
//		return i_fDamage;
//	}
//
//	float fDummyDamage = min(pDummy->Endurance1, i_fDamage);
//
//#ifdef _DEBUG
//	i_pTargetSocket->SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0017,
//								(UINT)pDummy, pDummy->Endurance1-fDummyDamage, pDummy->Endurance1, i_fDamage);
//#endif
//
//	pDummy->Endurance1 -= fDummyDamage;
//
//	if (pDummy->Endurance1 <= 0)
//	{
//		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_EXPLODE_ITEM, T_FC_BATTLE_ATTACK_EXPLODE_ITEM, pExplodeItem, pExplodeItemBuf);
//		pExplodeItem->TargetIndex = i_pTargetCharacter->ClientIndex;
//		pExplodeItem->TargetItemFieldIndex = i_nItemFieldIndex;
//		i_pTargetSocket->ms_pFieldIOCP->SendInRangeMessageAroundCharacter(i_pTargetCharacter->ClientIndex, pExplodeItemBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_EXPLODE_ITEM)
//			, i_pTargetSocket->m_pCurrentFieldMapChannel, TRUE, i_pTargetSocket->m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
//
//		i_pTargetSocket->m_mapFieldDummy.deleteLock(i_nItemFieldIndex);
//		delete((FIELD_DUMMY*)i_nItemFieldIndex);
//	}
//
//	return (i_fDamage - fDummyDamage);
//}


///////////////////////////////////////////////////////////////////////////////
/// \fn			int CFieldIOCPSocket::SupplyBullet(ITEM_GENERAL *i_pWeaponItem, ITEM *i_pBulletItem, int i_nSupplyCount)
/// \brief		
/// \author		cmkwon
/// \date		2005-11-03 ~ 2005-11-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int CFieldIOCPSocket::SupplyBullet(ITEM_GENERAL *i_pWeaponItem, ITEM *i_pBulletItem, int i_nSupplyCount)
{
// 2007-10-06 by cmkwon, 멤버쉽 혜택 수정 - 베트남 총알 두배 제외, 아래와 같이 수정
//	if(i_nSupplyCount <= 0
//		|| 2*i_pWeaponItem->ItemInfo->Charging <= i_pWeaponItem->CurrentCount)	// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 체크 수정, 총알을 두배 채울 수 있다
//	{
//		return 0;
//	}
//
//	///////////////////////////////////////////////////////////////////////////////	
//	// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
//	if(m_ItemManager.IsExistPremiumCard())
//	{// 2007-09-06 by cmkwon, 멤버쉽 체크
//
//		// 2007-09-06 by cmkwon, 멤버쉽 혜택 수정 - 총알을 두배 채울 수 있다
//		i_nSupplyCount = min(i_nSupplyCount, 2*i_pWeaponItem->ItemInfo->Charging - i_pWeaponItem->CurrentCount);
//	}
//	else
//	{
//		i_nSupplyCount = min(i_nSupplyCount, i_pWeaponItem->ItemInfo->Charging - i_pWeaponItem->CurrentCount);
//	}

	// 2007-10-06 by cmkwon, 보급 개수 체크 
	if(i_nSupplyCount <= 0)
	{
		return 0;
	}

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

	i_nSupplyCount = min(i_nSupplyCount, nMaxChargingCnt - i_pWeaponItem->CurrentCount);
	
	// Weapon의 count 변경
	m_ItemManager.UpdateItemCountByPointer(i_pWeaponItem, i_nSupplyCount, IUT_BULLET, ITEM_IN_CHARACTER, TRUE, FALSE);

	if (IS_PRIMARY_WEAPON(i_pWeaponItem->ItemInfo->Kind))
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_PRI_BULLET_RELOADED, T_FC_BATTLE_PRI_BULLET_RELOADED, pPriBulletReloded, pPriBulletRelodedBuf);
		pPriBulletReloded->BulletCount = i_pWeaponItem->CurrentCount;
		pPriBulletReloded->RechargeCount	= i_nSupplyCount;				// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		pPriBulletReloded->RechargeType		= BULLET_RECHARGE_TYPE_REPAIR_SHOP;	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		SendAddData(pPriBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_PRI_BULLET_RELOADED));
	}
	else if (IS_SECONDARY_WEAPON(i_pWeaponItem->ItemInfo->Kind))
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SEC_BULLET_RELOADED, T_FC_BATTLE_SEC_BULLET_RELOADED, pSecBulletReloded, pSecBulletRelodedBuf);
		pSecBulletReloded->BulletCount = i_pWeaponItem->CurrentCount;
		pSecBulletReloded->RechargeCount	= i_nSupplyCount;				// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		pSecBulletReloded->RechargeType		= BULLET_RECHARGE_TYPE_REPAIR_SHOP;	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		SendAddData(pSecBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_SEC_BULLET_RELOADED));
	}
	else
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL ERROR: Invalid Item Kind @SupplyBullet(), %s %s\r\n",
			GetCharacterString(&m_character, string()),
			GetItemGeneralString(i_pWeaponItem, string()));
		return FALSE;
	}

	return i_nSupplyCount;
}



void CFieldIOCPSocket::OnMonsterDead(CFieldIOCPSocket *pAttackSocket, CHARACTER *pAttackCharacter,
									CFieldIOCPSocket *pTargetSocket, CFieldMonster *pTargetMonster,
									ITEM *pAttackItem)
{

	CFieldMapChannel *pFieldMapChannel = pAttackSocket->m_pCurrentFieldMapChannel;
	if(NULL == pFieldMapChannel){						return;}

	// 2014-01-08 by jhseol, 보스몬스터 보상강화 보완 - 이달의 아머 추가대미지로 잡았을경우 보상 안주는 버그 수정
#ifdef SC_BOSS_MONSTER_REWARD_BCKIM_SSJUNG
	if( FALSE == g_pFieldGlobal->IsArenaServer() 
		&& TRUE == COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER) )
	{					
		RewardOfBossMonster(pAttackSocket, pTargetMonster);
	}				
#endif
	// end 2014-01-08 by jhseol, 보스몬스터 보상강화 보완 - 이달의 아머 추가대미지로 잡았을경우 보상 안주는 버그 수정

	// 2012-11-15 by bckim, 이벤트 로드크레아시아 몬스터 아이템 지급 구현 
	if ( NULL != pTargetMonster )
	{
		INT nEventMonsterUnitKind = pTargetMonster->MonsterInfoPtr->MonsterUnitKind;
		if( EVENT_MONSTER_INDEX_IN_MAP_ANI == nEventMonsterUnitKind )	//	2117400
		{
			// 2013-06-28 by bckim, 로드크레아시아 아이템 드롭이 안되는 버그 수정 
			pFieldMapChannel->InsertItemInMap(EVENT_MONSTER_DROP_ITEM_INDEX,EVENT_MONSTER_DROP_ITEM_COUNT,INFLUENCE_TYPE_VCN);
			pFieldMapChannel->OnMonsterDeadFieldMapChannel(pTargetMonster);
			return;
		}
		if ( EVENT_MONSTER_INDEX_IN_MAP_VCN == nEventMonsterUnitKind)	//	2117300
		{
			// 2013-06-28 by bckim, 로드크레아시아 아이템 드롭이 안되는 버그 수정 
			pFieldMapChannel->InsertItemInMap(EVENT_MONSTER_DROP_ITEM_INDEX,EVENT_MONSTER_DROP_ITEM_COUNT,INFLUENCE_TYPE_ANI);
			pFieldMapChannel->OnMonsterDeadFieldMapChannel(pTargetMonster);
			return;
		}
	}
	// 2012-11-15 by bckim, 이벤트 로드크레아시아 몬스터 아이템 지급 구현. End

	///////////////////////////////////////////////////////////////////////////////
	// 몬스터가 공격받은 리스트를 임시 변수에 할당하고 초기화 한다
	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);
// 2006-07-21 by cmkwon, 어그로 시스템 구현 작업으로 주석처리
// 		if (pFieldMapChannel != pFISock->GetCurrentFieldMapChannel()
// 			|| pTmpActionInfo->fSumDamage <= 0.0f)
// 		{// 죽은 몬스터와 맵이 다르거나 데미지 총합이  0.0보다 작을 때
// 			delete pTmpActionInfo;
// 			itr = tmAttackedInfo.erase(itr);
// 			continue;
// 		}
		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 = pAttackSocket->ms_pFieldIOCP->m_dwTimeStarted + (pTargetMonster->m_dwTimeCreatedTick - pAttackSocket->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)
	{
		DbgOut("	Exprience division error MapInfo(%d:%d) CharacterInfo(%s:%d) MonsterInfo(%s:%d) fTotalDamage(%5.3f) < 0.0f or Empty Vector: %d, Distance(%5.1f)\n"
			, pAttackCharacter->MapChannelIndex.MapIndex, pAttackCharacter->MapChannelIndex.ChannelIndex
			, pAttackCharacter->CharacterName, pAttackCharacter->CharacterUniqueNumber, pTargetMonster->MonsterInfoPtr->MonsterName, pTargetMonster->MonsterInfoPtr->MonsterUnitKind
			, fTotalDamage, tmAttackedInfo.size(), D3DXVec3Length(&(pTargetMonster->PositionVector - pAttackCharacter->PositionVector)));

		///////////////////////////////////////////////////////////////////////////////
		// 임시 변수를 삭제 처리한다
		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);

		if(IS_TUTORIAL_MAP_INDEX(pFieldMapChannel->GetMapChannelIndex().MapIndex))
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY, T_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY, pSTMonDead, SendBuf);
			pSTMonDead->monsterIdx		= pTargetMonster->MonsterIndex;
			
			mt_auto_lock mtCT(&pTargetMonster->m_mtvectClientIdxForTargetType);
			ms_pFieldIOCP->SendInRangeClientIndexVectorAroundPosition(pTargetMonster->PositionVector, &pTargetMonster->m_mtvectClientIdxForTargetType
				, SendBuf, MSG_SIZE(MSG_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY), pFieldMapChannel, pFieldMapChannel->GetMonsterVisibleDiameterW());
		}

		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);
			}
		}

// 2009-01-13 by cmkwon, 미션 보상을 파티원 모두에게 주기 명령어 추가 - 위와 같이 수정 함
// 		if(tmExpDivison.pFParty0 && tmExpDivison.nPartyMemberCnts > 1)
// 		{				
// 			for(int j=0; j < tmExpDivison.nPartyMemberCnts; j++)
// 			{
// 				pFISock	= tmExpDivison.ArrSEXP_PARTYMEMBER[j].pFISock0;
// 				if(NULL == pFISock
// 					|| pFISockofTopDamage == pFISock
// 					|| FALSE == pFISock->IsValidCharacter())
// 				{// 2006-07-18 by cmkwon, 유효 파티원 체크
// 					continue;
// 				}
// 
// 				pFISock->AddCharacterQuestMonsterCount(pTargetMonster->MonsterInfoPtr->MonsterUnitKind, FALSE);
// 			}
// 		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-07-13 by cmkwon, 경험치 분배
	DROPITEM			dropItem;	// priorityInfoCount는 생성자에서 0으로 할당
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정
//	expDivisionMan.ProcessEXPDivision(&dropItem, &msgBossMonsterLog, pTargetMonster->MonsterInfoPtr->Experience, COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER));

	// 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() ) ) 
	{
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
		expDivisionMan.ProcessEXPDivisionInfinityMap(&dropItem, &msgBossMonsterLog, pTargetMonster->rtn_MonsterExperience() , COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER), pTargetMonster);
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
	}
	else 
	{
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
		expDivisionMan.ProcessEXPDivision(&dropItem, &msgBossMonsterLog, pTargetMonster->rtn_MonsterExperience() , COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER), pTargetMonster);
		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
	}
	// End 2010. 05. 31 by hsLee 인피니티 필드 2차 난이도 조절. (오브젝트 몬스터 밸런스 적용 문제 수정.)

// 2006-08-08 by cmkwon, 필요 없는 코드임
// #ifdef _DEBUG
// 	for (int jj = 0; jj < dropItem.priorityInfoCount; jj++)
// 	{
// 		DBGOUT("  priority(%#08x): %d -> %d\n",
// 			&dropItem,
// 			dropItem.priorityInfoArray[jj].CharacterUniqueNumber,
// 			dropItem.priorityInfoArray[jj].dwDelay);
// 	}
// #endif

	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);

	if(IS_TUTORIAL_MAP_INDEX(pFieldMapChannel->GetMapChannelIndex().MapIndex))
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY, T_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY, pSTMonDead, SendBuf);
		pSTMonDead->monsterIdx		= pTargetMonster->MonsterIndex;
		
		mt_auto_lock mtCT(&pTargetMonster->m_mtvectClientIdxForTargetType);
		ms_pFieldIOCP->SendInRangeClientIndexVectorAroundPosition(pTargetMonster->PositionVector, &pTargetMonster->m_mtvectClientIdxForTargetType
			, SendBuf, MSG_SIZE(MSG_FC_MONSTER_TUTORIAL_MONSTER_DEAD_NOTIFY), pFieldMapChannel, pFieldMapChannel->GetMonsterVisibleDiameterW());
	}

	//////////////////////////////////////////////////////////////////////////
	// 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);
	}
}

// 2012-10-08 by jhjang 해피아워 경험치 리뉴얼
// 2012-10-19 by jhjang 해피아워 경험치 리뉴얼 - 킬카운트 300일때 바로 지급하게 수정
bool CFieldIOCPSocket::RefreshKillCount(CFieldMonster * pFieldMonster)
{
	if( !pFieldMonster						//몬스터 포인터가 널인가
		|| g_pFieldGlobal->IsArenaServer()	// 아레나 맵인가 // 2012-10-17 by jhjang 해피아워 경험치 리뉴얼
		|| m_bIsPayKillCountBonusItem		// 인벤토리에 킬카운트 경험치 보상 아이템이 있는가
 		|| !IsCheckLevel(max(pFieldMonster->MonsterInfoPtr->Level-15,1), min(pFieldMonster->MonsterInfoPtr->Level+15,CHARACTER_MAX_LEVEL+15))// 몬스터가 레벨차이가 몇 이상 나는가
 		)
	{
		return true;
	}

	// 킬카운트 증가
	m_nKillCount++;

	// 킬 카운트 클라이언트 전송
//	SendKillCount();

	if(m_nKillCount >=  KILLCOUNT_MAX)//킬 카운트에 따른 보상 처리
	{
		//아이템 지급
		m_ItemManager.InsertItemBaseByItemNum(KILLCOUNT_ITEMNUM, 1, IUT_GENERAL);
		//아이템 지급 변수 체크 활성화
		SetKillCountEventItem(true);

		// 300 카운트를 클라이언트에 전송, 그뒤 카운트를 초기화
		SendToClient_RestCount();

		m_nKillCount = 0;
		return false;
	}

	return true;
}
// end 2012-10-19 by jhjang 해피아워 경험치 리뉴얼 - 킬카운트 300일때 바로 지급하게 수정

void CFieldIOCPSocket::SetKillCountEventItem(bool bIsPayKillCountBonusItem)
{
	//아이템 지급 변수 수정 
	m_bIsPayKillCountBonusItem = bIsPayKillCountBonusItem;

	//아이템 지급변수 로그 활성화

}
void CFieldIOCPSocket::SendToClient_KillCount()
{
//	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_KILLCOUNT, T_FC_CHARACTER_KILLCOUNT, pKillCount, pKillCountBuf);
//	pKillCount->nRestCount = m_nKillCount;
//	this->SendAddData(pKillCountBuf, MSG_SIZE(MSG_FC_CHARACTER_KILLCOUNT));
}

void CFieldIOCPSocket::SendToClient_RestCount()
{
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_RESTCOUNT, T_FC_CHARACTER_RESTCOUNT, pRestCount, pRestCountBuf);
	pRestCount->nRestCount = m_nRestExperienceCount;
	pRestCount->nKillCount = m_nKillCount;
	this->SendAddData(pRestCountBuf, MSG_SIZE(MSG_FC_CHARACTER_RESTCOUNT));
}

void CFieldIOCPSocket::SendToClient_BonusExpRate()
{
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_BONUS_EXP_RATE, T_FC_CHARACTER_BONUS_EXP_RATE, pBonusExpRate, pBonusExpRateBuf);

	// 2012-10-17 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
	double fRate;
//	fRate = ((double)(m_nInSamePartyCount-1)*0.1 + 0.2) * 1000.0;
	//pBonusExpRate->nPartyRate = (INT)fRate;
	pBonusExpRate->nPartyRate = 0;
	fRate = min((0.015 * ((double)m_nOnlineEachOtherFriendCnts)),0.7)  * 1000.0;
	pBonusExpRate->nFriendRate = (INT)fRate;
	pBonusExpRate->nGuildRate = m_nGuildBonusExpRate;
	this->SendAddData(pBonusExpRateBuf, MSG_SIZE(MSG_FC_CHARACTER_BONUS_EXP_RATE));
	// 2012-10-17 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
}
// end 2012-10-08 by jhjang 해피아워 경험치 리뉴얼

// 2013-03-13 by hskim, 웹 캐시 상점
void CFieldIOCPSocket::GenCashAuthenticationKey()
{
	MEMSET_ZERO(m_szAuthenticationKey, sizeof(m_szAuthenticationKey));
	sprintf(m_szAuthenticationKey, "%010d%010d%010d%010d%010d%010d", rand32(), rand32(), rand32(), rand32(), rand32(), rand32());
}
// end 2013-03-13 by hskim, 웹 캐시 상점

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnInfluenceBossMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-21 ~ 2006-11-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnInfluenceBossMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{	
	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-02 by cmkwon, 서버 실행시 실행 관련 로그 추가 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] DeclarationNoti CFieldIOCPSocket::OnInfluenceBossMonsterCreated# %s Map(%s) MonsterNum(%d) \r\n"
		, CAtumSJ::GetInfluenceTypeString(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)), GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()), i_pFMon->MonsterInfoPtr->MonsterUnitKind);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 소유 해당 맵채널 초기화
	ms_pFieldIOCP->InitStrategyPointOccupyW((IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence))?TRUE:FALSE);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-27 by dhjin, 전략포인트 소유 세력 전략포인트 정보 초기화
	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfoByInfluenceType(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략몬스터 초기화
	INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_STRATEGYPOINT_INIT, T_FN_MONSTER_STRATEGYPOINT_INIT, pSInit, SendBuff);
	pSInit->ChannelIndex				= i_pFMapChann->GetMapChannelIndex().ChannelIndex;
	pSInit->bVCNMapInflTyforInit		= (INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)) ? TRUE : FALSE;
	pSInit->bCreateFlag					= TRUE;			// 2006-11-21 by cmkwon, 초기화 후에 바로 생성한다
	pSInit->bInfluenceBoss				= TRUE;			// 2007-08-30 by dhjin, 모선전시 전략포인트 소환인지 체크 비트 0 : FASLE, 1 : TRUE
	// 2013-08-14 by jhseol, 거점전 리뉴얼 - 모선전시 거점 소환
#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG	// - 모선전시 거점 소환
	if( NULL != i_pFMon && NULL != i_pFMon->MonsterInfoPtr )
	{	// 모선전 6랩으루 고정
		BYTE nMonsterInfl = INFLUENCE_TYPE_UNKNOWN;
		if ( BELL_INFLUENCE_VCN == i_pFMon->MonsterInfoPtr->Belligerence )
		{
			nMonsterInfl = INFLUENCE_TYPE_VCN;
		}
		else if ( BELL_INFLUENCE_ANI == i_pFMon->MonsterInfoPtr->Belligerence )
		{
			nMonsterInfl = INFLUENCE_TYPE_ANI;
		}
		pSInit->SummonMonsterNum = ms_pFieldIOCP->GetMonsterGeade_SummonMonsterNumByLevel(MONSTER_GRADE_TYPE_STRATEGYPOINT, nMonsterInfl, FIEXD_MSWAR_SPLEVEL);
	}
#endif
	// end 2013-08-14 by jhseol, 거점전 리뉴얼 - 모선전시 거점 소환
	i_pFMapChann->Send2NPCServerW(SendBuff, MSG_SIZE(MSG_FN_MONSTER_STRATEGYPOINT_INIT));	// 2006-11-21 by cmkwon, 전송은 하나의 맵채널로 하지만 NPCServer에서 모든 맵에 적용한다

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-29 by dhjin, 모선 소환시 모선 소환된 맵에 몬스터는 사라진다.
	INIT_MSG(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL, T_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL, pMonster, SendBuff);
	pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
	pMonster->bAllFlag			= FALSE;
	pMonster->bell1				= -1;
	pMonster->bell2				= -1;
	if(INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		pMonster->excludeBell1		= BELL_INFLUENCE_VCN;
		pMonster->excludeBell2		= BELL_STRATEGYPOINT_VCN;
	}
	else
	{
		pMonster->excludeBell1		= BELL_INFLUENCE_ANI;
		pMonster->excludeBell2		= BELL_STRATEGYPOINT_ANI;
	}
	pMonster->bNotCreateMonster = TRUE;
	ms_pFieldIOCP->Send2NPCServerByTCP(SendBuff, MSG_SIZE(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL));	

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 -  
//	ms_pFieldIOCP->m_InflWarManager.InitMSWarOptionTypeW(IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_VCN : INFLUENCE_TYPE_ANI);

	// 2007-10-16 by cmkwon, 로그 추가 - 세력전 시작
	CAtumLogSender::SendLogMessageInflWarStart(i_pFMapChann->GetMapChannelIndex().MapIndex, GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence), i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterInfoPtr->Belligerence);

	///////////////////////////////////////////////////////////////////////////////
	// 2008-10-28 by cmkwon, 대회서버 시스템 수정(MotherShip 소환시 상대 세력 도시맵으로 이동) - 상대 세력을 도시맵으로 워프 시킨다.

// 2012-12-05 by hskim, 모선전 시작시에 상대 세력 도시맵으로 워프
#ifdef S_KOR_TEST_MSWAR_BACK_TO_CITY_HSKIM
#else
	if(g_pFieldGlobal->GetIsJamboreeServer())
#endif
// end 2012-12-05 by hskim, 모선전 시작시에 상대 세력 도시맵으로 워프
	{
		BYTE byInflTy = INFLUENCE_TYPE_VCN;
		int nWarpedCnts = 0;
		if(INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
		{
			byInflTy = INFLUENCE_TYPE_ANI;
		}
		nWarpedCnts = ms_pFieldIOCP->WarpAllInfluenceUsersToCity(byInflTy, TRUE, TRUE);		// 2012-12-05 by hskim, 모선전 시작시에 상대 세력 도시맵으로 워프
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] %5d is warped %s user count when mothership was summoned !! \r\n", nWarpedCnts, CAtumSJ::GetInfluenceTypeString(byInflTy));
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-12-23 by dhjin, 전쟁 보상 추가안
	BYTE byInflTy = INFLUENCE_TYPE_VCN;
	if(INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		byInflTy = INFLUENCE_TYPE_ANI;
	}	
	ms_pFieldIOCP->InsertCBossWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex, ms_pFieldIOCP->m_InflWarManager.GetContributionPoint(byInflTy));
	ms_pFieldIOCP->WarStartOtherInflStayTimeForAllUser();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnInfluenceBossMonsterAutoDestroyed(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-21 ~ 2006-11-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnInfluenceBossMonsterAutoDestroyed(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-12 by dhjin, 선전 포고, 모든 분쟁 지역의 MapInfluenceType을 변경한다.
	ms_pFieldIOCP->ChangeMapInfluenceType2AllConflictAreaW(i_pFMon->MonsterInfoPtr->Belligerence, FALSE);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-14 by dhjin, 전함 자동 파괴시 정보 클라이언트에게 다 보낸다.
	INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_DEAD, T_FC_WAR_NOTIFY_INFLUENCE_MONSTER_AUTO_DESTROYED, pSMonDead, SendBuf);
	pSMonDead->MonsterUnitkind	= i_pFMon->MonsterInfoPtr->MonsterUnitKind;
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_DEAD),INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	//////////////////////////////////////////////////////////////////////////
	// 2007-11-06 by dhjin, 모선전 방어 성공시 보상 지급
	//ms_pFieldIOCP->PayBossMonsterSuccessDefend(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)); // 2013-11-18 by jekim, 모선 파괴를 못했지만 양 세력 모두 200+1000 습득한 이슈 수정 - 주석처리

	///////////////////////////////////////////////////////////////////////////////
	// 2007-05-15 by dhjin, 세력전 관련 처리, 방어전도 승리로 간주 처리한다.
	ms_pFieldIOCP->m_InflWarManager.OnInfluenceBossMonsterAutoDestroyedInflWarManager(i_pFMon->MonsterInfoPtr);
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 소유 해당 맵채널 초기화
	ms_pFieldIOCP->InitStrategyPointOccupyW((IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence))?TRUE:FALSE);
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-02-27 by dhjin, 전략포인트 소유 세력 전략포인트 정보 초기화
	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfoByInfluenceType(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));

// 2007-05-17 by cmkwon, 함수 수정으로 위치 변경
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-02-06 by dhjin, 보스 몬스터 자동 삭제 시 SSUMMONBOSSMONSTER_INFO 정보 초기화.
//	ms_pFieldIOCP->m_InflWarManager.OnInfluenceBossMonsterAutoDestroyedInflWarManager((IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence))?TRUE:FALSE);
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-27 by cmkwon
	char szSysLog[1024];
	wsprintf(szSysLog, "  [Notify] DeclarationNoti OnInflBossMonsterAutoDestroyed Monster(%8d) MonsterBelligerence[%d] MapChannel(%d)\r\n"
		, i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterInfoPtr->Belligerence, GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()));
	g_pFieldGlobal->WriteSystemLog(szSysLog);
	DBGOUT(szSysLog);

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-29 by dhjin, 몬스터 생성이 가능하게 다시 설정
	INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);
	pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
	i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-20 by cmkwon, 텔레포트 수정 - 보스몬스터 자동 삭제시에도 전략포인트 몬스터 초기화 메시지를 전송한다.
	INIT_MSG(MSG_FN_MONSTER_STRATEGYPOINT_INIT, T_FN_MONSTER_STRATEGYPOINT_INIT, pSInit, SendBuf);
	pSInit->ChannelIndex				= i_pFMapChann->GetMapChannelIndex().ChannelIndex;
	pSInit->bVCNMapInflTyforInit		= (INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)) ? TRUE : FALSE;
	// 2007-09-16 by dhjin, 주의~!! bCreateFlag = FALSE && bInfluenceBoss = FALSE 일 경우 ProcessNPCOnMonsterStrategyPointInit()함수에서 몬스터 소환을 허락한다.
	pSInit->bCreateFlag					= FALSE;		// 2006-11-21 by cmkwon, 초기화만 한다, 생성은 하지 않는다
	pSInit->bInfluenceBoss				= FALSE;		// 2007-08-30 by dhjin, 모선전시 전략포인트 소환인지 체크 비트 0 : FASLE, 1 : TRUE
	i_pFMapChann->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_MONSTER_STRATEGYPOINT_INIT));	// 2006-11-21 by cmkwon, 전송은 하나의 맵채널로 하지만 NPCServer에서 모든 맵에 적용한다

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-16 by dhjin, 텔레포트 정보 초기화
	ms_pFieldIOCP->m_InflWarManager.ClearTelePortByInfluenceWarEnd(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));

	//////////////////////////////////////////////////////////////////////////
	// 2008-04-01 by dhjin, 모선전, 거점전 정보창 기획안 - 
	ms_pFieldIOCP->m_InflWarManager.SetMSWarInfoResultByWarEnd(i_pFMon->MonsterInfoPtr->MonsterUnitKind, IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_VCN : INFLUENCE_TYPE_ANI);
	ms_pFieldIOCP->m_InflWarManager.SendLogMSWarInfoResult(i_pFMon->MonsterInfoPtr->MonsterUnitKind);
	ms_pFieldIOCP->m_InflWarManager.DeleteMSWarInfoResult(i_pFMon->MonsterInfoPtr->MonsterUnitKind);

	//////////////////////////////////////////////////////////////////////////
	// 2008-12-23 by dhjin, 전쟁 보상 추가안
	BYTE WinInfl = INFLUENCE_TYPE_VCN;
	if(INFLUENCE_TYPE_ANI == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		WinInfl = INFLUENCE_TYPE_ANI;
	}
	ms_pFieldIOCP->PayCBossWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex, WinInfl);
	ms_pFieldIOCP->DeleteCBossWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex);	

	// 2009-02-11 by dhjin, 시스템 로그 보완
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] OutPostWarNoti MSBoss WarContributionEnd : autoDes\r\n");

	// 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점
	if ( INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence) )
	{
		ms_pFieldIOCP->m_InflWarManager.m_bNGCTriggerBCUMSWarStartCheckOK = FALSE;
	}
	else if (INFLUENCE_TYPE_ANI == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence) )
	{
		ms_pFieldIOCP->m_InflWarManager.m_bNGCTriggerANIMSWarStartCheckOK = FALSE;
	}
	if ( NULL != ms_pFieldIOCP->m_pMapTriggerManager)
	{
		ms_pFieldIOCP->m_pMapTriggerManager->SetMSWarState(FALSE);
	}
	// end 2013-08-14 by jhseol, 거점전 리뉴얼 - NGC 거점
	//////////////////////////////////////////////////////////////////////////
	// 2009-01-12 by dhjin, 선전 포고
	ATUM_DATE_TIME CurrentTime;
	CurrentTime.SetCurrentDateTime();
	ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.SetMSWarFinish(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence), WinInfl, &CurrentTime);
	QPARAM_UPDATE_END_DECLARATION_OF_WAR *pQParam = new QPARAM_UPDATE_END_DECLARATION_OF_WAR;
	pQParam->Influence			= GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence);
	pQParam->MSWarStep			= ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.GetCurrentMSWarStep(GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));
	pQParam->MSWarEndTime		= CurrentTime;
	pQParam->MSWarEndState		= ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.GetCurrentMSWarEndState(GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateEndDeclarationOfWar, NULL, 0, pQParam);

	// 2007-10-16 by cmkwon, 로그 추가 - 세력전 종료
	CAtumLogSender::SendLogMessageInflWarEnd(i_pFMapChann->GetMapChannelIndex().MapIndex, GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence), i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterInfoPtr->Belligerence, FALSE);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnInfluenceBossMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann, CGuildDamageManager *i_pGDamageManager)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-13 ~ 2006-04-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnInfluenceBossMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann, CGuildDamageManager *i_pGDamageManager)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2009-07-02 by cmkwon, 서버 실행시 실행 관련 로그 추가 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] DeclarationNoti CFieldIOCPSocket::OnInfluenceBossMonsterDead# %s Map(%s) MonsterNum(%d) \r\n"
		, CAtumSJ::GetInfluenceTypeString(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)), GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()), i_pFMon->MonsterInfoPtr->MonsterUnitKind);

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-12 by dhjin, 선전 포고, // 2006-02-09 by cmkwon, 모든 분쟁 지역의 MapInfluenceType을 변경한다.
	ms_pFieldIOCP->ChangeMapInfluenceType2AllConflictAreaW(i_pFMon->MonsterInfoPtr->Belligerence, TRUE);

	///////////////////////////////////////////////////////////////////////////////
	// 2007-08-23 by cmkwon, 모선 폭파시 최고 데미지 준 여단명 표시 - 여기에서 정렬해서 최고 여단 정보를 검색한다
	SGUILD_DAMAGE *pBestGuild = i_pGDamageManager->GetBestGuild();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-09 by cmkwon, 보스몬스터 폭발된것을 모든 클라이언트로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_DEAD, T_FC_WAR_NOTIFY_INFLUENCE_MONSTER_DEAD, pSMonDead, SendBuf);
	pSMonDead->MonsterUnitkind	= i_pFMon->MonsterInfoPtr->MonsterUnitKind;
	if(pBestGuild)
	{// 2007-08-23 by cmkwon, 모선 폭파시 최고 데미지 준 여단명 표시 - 보낼 데이터 설정
		pSMonDead->uidBestGuildUID	= pBestGuild->GuildUID1;
		STRNCPY_MEMSET(pSMonDead->szBestGuildName, pBestGuild->GuildName2, SIZE_MAX_GUILD_NAME);
	}
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_DEAD),INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-09 by cmkwon, 여단 명성 처리
	// 2007-08-23 by cmkwon, 모선 폭파시 최고 데미지 준 여단명 표시 - 아래와 같이 수정함
	//if(1 <= i_pGDamageManager->GetGuildDamageListSize())
	if(pBestGuild
		&& IS_VALID_UNIQUE_NUMBER(pBestGuild->GuildUID1))
	{// 여단 명성

		INIT_MSG(MSG_FI_GUILD_ADD_GUILD_FAME, T_FI_GUILD_ADD_GUILD_FAME, pSGuildFame, SendBuf);
		pSGuildFame->guildUID	= pBestGuild->GuildUID1;	// 2007-08-23 by cmkwon, 모선 폭파시 최고 데미지 준 여단명 표시 - 기존소스 수정, i_pGDamageManager->GetBest1GuildUIDbySumOfDamage();
		pSGuildFame->addValues	= 100;
		ms_pFieldIOCP->Send2IMServer(SendBuf, MSG_SIZE(MSG_FI_GUILD_ADD_GUILD_FAME));
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-13 by cmkwon, 세력전 관련 처리
	ms_pFieldIOCP->m_InflWarManager.OnInfluenceBossMonsterDeadInflWarManager(i_pFMon->MonsterInfoPtr);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 소유 해당 맵채널 초기화
	ms_pFieldIOCP->InitStrategyPointOccupyW((IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence))?TRUE:FALSE);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-27 by dhjin, 전략포인트 소유 세력 전략포인트 정보 초기화
	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfoByInfluenceType(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 몬스터 초기화
	INIT_MSG(MSG_FN_MONSTER_STRATEGYPOINT_INIT, T_FN_MONSTER_STRATEGYPOINT_INIT, pSInit, SendBuf);
	pSInit->ChannelIndex				= i_pFMapChann->GetMapChannelIndex().ChannelIndex;
	pSInit->bVCNMapInflTyforInit		= (INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence)) ? TRUE : FALSE;
	// 2007-09-16 by dhjin, 주의~!! bCreateFlag = FALSE && bInfluenceBoss = FALSE 일 경우 ProcessNPCOnMonsterStrategyPointInit()함수에서 몬스터 소환을 허락한다.
	pSInit->bCreateFlag					= FALSE;		// 2006-11-21 by cmkwon, 초기화만 한다, 생성은 하지 않는다
	pSInit->bInfluenceBoss				= FALSE;		// 2007-08-30 by dhjin, 모선전시 전략포인트 소환인지 체크 비트 0 : FASLE, 1 : TRUE
	i_pFMapChann->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_MONSTER_STRATEGYPOINT_INIT));	// 2006-11-21 by cmkwon, 전송은 하나의 맵채널로 하지만 NPCServer에서 모든 맵에 적용한다

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-29 by dhjin, 몬스터 생성이 가능하게 다시 설정
	INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);
	pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
	i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-30 by dhjin, 모선전 승패에 따른 지도자 수령율 증감
	if(INFLUENCE_TYPE_ANI == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{// 2007-08-30 by dhjin, 바이제니유 세력이 알링턴 세력 모선을 격추시키면 바이제니유 세력에 판공비율+
		ms_pFieldIOCP->m_OutPostManager.UpdateExpediencyfundRateLeader(VCN_CITY_MAP_INDEX, INFLUENCE_TYPE_VCN, EXPEDIENCYFUND_LEADER_INFLUENCEWAR);
		ms_pFieldIOCP->m_OutPostManager.UpdateExpediencyfundRateLeader(ANI_CITY_MAP_INDEX, INFLUENCE_TYPE_ANI, -EXPEDIENCYFUND_LEADER_INFLUENCEWAR);
	}
	else
	{// 2007-08-30 by dhjin, 알링턴 세력이 바이제니유 세력 모선을 격추시키면 알링턴 세력에 판공비율+
		ms_pFieldIOCP->m_OutPostManager.UpdateExpediencyfundRateLeader(VCN_CITY_MAP_INDEX, INFLUENCE_TYPE_VCN, -EXPEDIENCYFUND_LEADER_INFLUENCEWAR);
		ms_pFieldIOCP->m_OutPostManager.UpdateExpediencyfundRateLeader(ANI_CITY_MAP_INDEX, INFLUENCE_TYPE_ANI, EXPEDIENCYFUND_LEADER_INFLUENCEWAR);
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-16 by dhjin, 텔레포트 정보 초기화
	ms_pFieldIOCP->m_InflWarManager.ClearTelePortByInfluenceWarEnd(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));

	//////////////////////////////////////////////////////////////////////////
	// 2008-04-01 by dhjin, 모선전, 거점전 정보창 기획안 - 
	ms_pFieldIOCP->m_InflWarManager.SetMSWarInfoResultByWarEnd(i_pFMon->MonsterInfoPtr->MonsterUnitKind, IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_ANI : INFLUENCE_TYPE_VCN);
	ms_pFieldIOCP->m_InflWarManager.SendLogMSWarInfoResult(i_pFMon->MonsterInfoPtr->MonsterUnitKind);
	ms_pFieldIOCP->m_InflWarManager.DeleteMSWarInfoResult(i_pFMon->MonsterInfoPtr->MonsterUnitKind);

	//////////////////////////////////////////////////////////////////////////
	// 2008-12-23 by dhjin, 전쟁 보상 추가안
	BYTE WinInfl = INFLUENCE_TYPE_ANI;
	if(INFLUENCE_TYPE_ANI == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		WinInfl = INFLUENCE_TYPE_VCN;
	}
	ms_pFieldIOCP->PayCBossWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex, WinInfl);
	ms_pFieldIOCP->DeleteCBossWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex);	

	// 2009-02-11 by dhjin, 시스템 로그 보완
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] OutPostWarNoti MSBoss WarContributionEnd : Dead\r\n");

	//////////////////////////////////////////////////////////////////////////
	// 2009-01-12 by dhjin, 선전 포고
	ATUM_DATE_TIME CurrentTime;
	CurrentTime.SetCurrentDateTime();
	ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.SetMSWarFinish(GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence), WinInfl, &CurrentTime);
	QPARAM_UPDATE_END_DECLARATION_OF_WAR *pQParam = new QPARAM_UPDATE_END_DECLARATION_OF_WAR;
	pQParam->Influence			= GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence);
	pQParam->MSWarStep			= ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.GetCurrentMSWarStep(GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));
	pQParam->MSWarEndTime		= CurrentTime;
	pQParam->MSWarEndState		= ms_pFieldIOCP->m_InflWarManager.m_DeclarationOfWar.GetCurrentMSWarEndState(GET_OTHER_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateEndDeclarationOfWar, NULL, 0, pQParam);

	// 2007-10-16 by cmkwon, 로그 추가 - 세력전 종료
	CAtumLogSender::SendLogMessageInflWarEnd(i_pFMapChann->GetMapChannelIndex().MapIndex, GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence), i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterInfoPtr->Belligerence, TRUE);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsValidStrategyPointMonster(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-21 ~ 2006-11-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsValidStrategyPointMonster(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	if(0 != i_pFMapChann->GetMapChannelIndex().ChannelIndex
		|| FALSE == IS_STRATEGYPOINT_MONSTER(i_pFMon->MonsterInfoPtr->Belligerence))
	{// 2006-11-20 by cmkwon, 전략포인트 몬스터 처리 0번 채널에서만 처리
		return FALSE;
	}

	if(IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		if(FALSE == IS_MAP_INFLUENCE_VCN(i_pFMapChann->GetMapInfluenceTypeW()))
		{
			return FALSE;
		}
	}
	else
	{
		if(FALSE == IS_MAP_INFLUENCE_ANI(i_pFMapChann->GetMapInfluenceTypeW()))
		{
			return FALSE;
		}
	}
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnStrategyPointMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-21 ~ 2006-11-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnStrategyPointMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by cmkwon
	char szSysLog[1024];
	sprintf(szSysLog, "	[Notify]: StategyPoint Monster Created !! Map(%s) MonInfo(%s:%d) MonIdx(%d) MonBell(%s)\r\n"
		, GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()), i_pFMon->MonsterInfoPtr->MonsterName
		, i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterIndex, GetMonsterBellString(i_pFMon->MonsterInfoPtr->Belligerence));
	g_pFieldGlobal->WriteSystemLog(szSysLog);
	DbgOut(szSysLog);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-27 by dhjin, 거점 생성하기 전에 기존에 존재하는 거점 정보가 있다면 삭제하고 생성한다. 같은 거점이 2개 생성되어 있을 수 없다.
//	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfo(i_pFMapChann->GetMapChannelIndex());
	ATUM_DATE_TIME	atumCur(true);
	SSUMMON_STRATEGYPOINT_INFO	tmSummonStrategyPointInfo;
	const MAP_INFO *pMapInfo	= CAtumSJ::GetMapInfo(i_pFMapChann->GetMapChannelIndex().MapIndex);
	if(pMapInfo)
	{
		STRNCPY_MEMSET(tmSummonStrategyPointInfo.MapName, pMapInfo->MapName, SIZE_MAX_MAP_NAME);
		tmSummonStrategyPointInfo.MapIndex					=	pMapInfo->MapIndex;
		if(INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
		{// 2006-11-21 by cmkwon, 
			tmSummonStrategyPointInfo.InfluenceType	= INFLUENCE_TYPE_VCN;
		}
		else
		{
			tmSummonStrategyPointInfo.InfluenceType	= INFLUENCE_TYPE_ANI;
		}
		tmSummonStrategyPointInfo.SummonStrategyPointTime	=	atumCur;
		ms_pFieldIOCP->m_InflWarManager.InsertSummonStrategyPointInfo(&tmSummonStrategyPointInfo);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 몬스터 죽은 시간 초기화 - 전략포인트 소유 안됨
	i_pFMapChann->SetLastTickStrategyPointMonsterDeaded(0);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-09 by cmkwon, 전략포인트 몬스터 생성 된것을 모든 클라이언트로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_WAR_MONSTER_CREATED, T_FC_WAR_MONSTER_CREATED, pSMsg, SendBuf);
	pSMsg->MonsterUnitKind	= i_pFMon->MonsterInfoPtr->MonsterUnitKind;
	pSMsg->MapChannIdx		= i_pFMapChann->GetMapChannelIndex();
	pSMsg->CreateTime.SetCurrentDateTime();
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_MONSTER_CREATED), INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-26 by dhjin, 모선전 정보 표시 기획안 - 전략포인트 생성 된 정보 설정
	// 2013-08-14 by jhseol, 거점전 리뉴얼 - 출력 타입 (0:모선전, 1:일반 거점전)
#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG	// - 일반 거점전 정보도 추가
	BYTE tmDisplayType = WARINFO_DISPLAY_TYPE_SPWAR;
	if(ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByMapInfluence(pMapInfo->MapInfluenceType))
	{
		tmDisplayType = WARINFO_DISPLAY_TYPE_MSWAR;
	}
	ms_pFieldIOCP->m_InflWarManager.InsertMSWarInfoByMSWarStart(pMapInfo->MapIndex, pMapInfo->MapInfluenceType, i_pFMon->MonsterInfoPtr->Belligerence, tmDisplayType);
	ms_pFieldIOCP->m_InflWarManager.SendMSWarInfoForAllUser();
#else
	if(ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByMapInfluence(pMapInfo->MapInfluenceType))
	{
		ms_pFieldIOCP->m_InflWarManager.InsertMSWarInfoByMSWarStart(pMapInfo->MapIndex, pMapInfo->MapInfluenceType, i_pFMon->MonsterInfoPtr->Belligerence);
		ms_pFieldIOCP->m_InflWarManager.SendMSWarInfoForAllUser();
	}
#endif
	// end 2013-08-14 by jhseol, 거점전 리뉴얼 - 출력 타입 (0:모선전, 1:일반 거점전)

	//////////////////////////////////////////////////////////////////////////
	// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 거점전 시작 시 정보 설정
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.CheckSummonBoss())
	{
		// 2013-08-14 by jhseol, 거점전 리뉴얼 - 결과 로그에 거점 level 추가
		BYTE nMonsterInfl = INFLUENCE_TYPE_UNKNOWN;
		if ( BELL_STRATEGYPOINT_VCN == i_pFMon->MonsterInfoPtr->Belligerence )
		{
			nMonsterInfl = INFLUENCE_TYPE_VCN;
		}
		else if ( BELL_STRATEGYPOINT_ANI == i_pFMon->MonsterInfoPtr->Belligerence )
		{
			nMonsterInfl = INFLUENCE_TYPE_ANI;
		}
		BYTE tmSPLevel = ms_pFieldIOCP->GetMonsterGeade_SummonMonsterLevelBySummonMonsterNum(MONSTER_GRADE_TYPE_STRATEGYPOINT, nMonsterInfl, i_pFMon->MonsterInfoPtr->MonsterUnitKind);
		// end 2013-08-14 by jhseol, 거점전 리뉴얼 - 결과 로그에 거점 level 추가
		ms_pFieldIOCP->m_InflWarManager.SetSPWarInfoResultByWarStart(IS_BELL_VCN(i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_ANI : INFLUENCE_TYPE_VCN, pMapInfo->MapIndex, tmSPLevel);		// 2013-08-14 by jhseol, 거점전 리뉴얼 - 결과 로그에 거점 level 추가

		//////////////////////////////////////////////////////////////////////////
		// 2008-12-23 by dhjin, 전쟁 보상 추가안
		ms_pFieldIOCP->InsertCStrategyPointWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex);
		ms_pFieldIOCP->WarStartOtherInflStayTimeForAllUser();
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-08-29 by dhjin, 전략포인트 소환시 전략포인트 소환된 맵과 이전 맵 몬스터는 사라진다.
	INIT_MSG_WITH_BUFFER(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL, T_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL, pMonster, SendBuf2);
	pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
	pMonster->bAllFlag			= FALSE;
	pMonster->bell1				= -1;
	pMonster->bell2				= -1;
	if(INFLUENCE_TYPE_VCN == GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence))
	{
		pMonster->excludeBell1		= BELL_INFLUENCE_VCN;
		pMonster->excludeBell2		= BELL_STRATEGYPOINT_VCN;
	}
	else
	{
		pMonster->excludeBell1		= BELL_INFLUENCE_ANI;
		pMonster->excludeBell2		= BELL_STRATEGYPOINT_ANI;
	}
	pMonster->bNotCreateMonster = TRUE;
	ms_pFieldIOCP->Send2NPCServerByTCP(SendBuf2, MSG_SIZE(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL));	
	CFieldMapChannel		*pBackFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex, 0));
	if(pBackFMChann)
	{
		pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
		ms_pFieldIOCP->Send2NPCServerByTCP(SendBuf2, MSG_SIZE(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL));
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 생성시 백맵2 의 맵에도 몬스터 제거
	pBackFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex2, 0));
	if(pBackFMChann)
	{
		pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
		ms_pFieldIOCP->Send2NPCServerByTCP(SendBuf2, MSG_SIZE(MSG_FN_NPCSERVER_DELETE_MONSTER_IN_MAPCHANNEL));
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnStrategyPointMonsterAutoDestroyed(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-21 ~ 2006-11-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnStrategyPointMonsterAutoDestroyed(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by cmkwon
	char szSysLog[1024];
	sprintf(szSysLog, "	[Notify]: StategyPoint Monster Auto destroyed !! Map(%s) MonInfo(%s:%d) MonIdx(%d) MonBell(%s)\r\n"
		, GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()), i_pFMon->MonsterInfoPtr->MonsterName
		, i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterIndex, GetMonsterBellString(i_pFMon->MonsterInfoPtr->Belligerence));
	g_pFieldGlobal->WriteSystemLog(szSysLog);
	DbgOut(szSysLog);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 몬스터 죽은 시간 초기화 - 전략포인트 소유 안됨
	i_pFMapChann->SetLastTickStrategyPointMonsterDeaded(0);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-23 by dhjin, 거점 정보 삭제
	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfo(i_pFMapChann->GetMapChannelIndex());
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 방어측 세력을 선택한다.
	BYTE byAttackerCharInflTy = GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence);
	BYTE byLoseCharInflTy = INFLUENCE_TYPE_UNKNOWN;		// 2008-01-07 by dhjin, 세력 보상 수정 - 
	if(INFLUENCE_TYPE_VCN == byAttackerCharInflTy)
	{
		byAttackerCharInflTy		= INFLUENCE_TYPE_VCN;
		byLoseCharInflTy			= INFLUENCE_TYPE_ANI;
	}
	else
	{
		byAttackerCharInflTy		= INFLUENCE_TYPE_ANI;
		byLoseCharInflTy			= INFLUENCE_TYPE_VCN;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-09 by cmkwon, 전략포인트 몬스터 자동 소멸 된것을 모든 클라이언트로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_WAR_MONSTER_AUTO_DESTROYED, T_FC_WAR_MONSTER_AUTO_DESTROYED, pSMsg, SendBuf);
	pSMsg->MonsterUnitKind	= i_pFMon->MonsterInfoPtr->MonsterUnitKind;
	pSMsg->MapChannIdx		= i_pFMapChann->GetMapChannelIndex();
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_MONSTER_AUTO_DESTROYED), INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN		// 2013-08-02 by jhseol, 세력포인트 컨텐츠 미반영 국가 거점 파괴시 세력포인트 안주는 버그 수정 - 기존코드 컨텐츠 구분
	if( FALSE == ms_pFieldIOCP->m_InflWarManager.CheckSummonBoss() )
	{
		// 2013-08-14 by jhseol, 거점전 리뉴얼 - 세력포인트 비율 변경
// 		BYTE nSPLevel = 1;
// 	#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG
// 		BYTE nMonsterInfl = INFLUENCE_TYPE_UNKNOWN;
// 		if ( BELL_STRATEGYPOINT_VCN == i_pFMon->MonsterInfoPtr->Belligerence )
// 		{
// 			nMonsterInfl = INFLUENCE_TYPE_VCN;
// 		}
// 		else if ( BELL_STRATEGYPOINT_ANI == i_pFMon->MonsterInfoPtr->Belligerence )
// 		{
// 			nMonsterInfl = INFLUENCE_TYPE_ANI;
// 		}
// 		nSPLevel = ms_pFieldIOCP->GetMonsterGeade_SummonMonsterLevelBySummonMonsterNum(MONSTER_GRADE_TYPE_STRATEGYPOINT, nMonsterInfl, i_pFMon->MonsterInfoPtr->MonsterUnitKind);
// 	#endif
// 		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER*nSPLevel, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER*nSPLevel);
		// end 2013-08-14 by jhseol, 거점전 리뉴얼 - 세력포인트 비율 변경
		// 2014-02-06 by jhseol, 세력포인트에 따른 거점 레벨링 밸런스 패치 - 연승에 따른 추가 세력포인트 지급
		INT AddContributionPointPoint = 0;
		INT VictoriesPoint = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(byAttackerCharInflTy);	// 지금까지 연승한 연승 포인트
		VictoriesPoint = min(VictoriesPoint++, 8);
	#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG
		AddContributionPointPoint = GetAddSTRATEGYPOINTbyVictoriesPoint(VictoriesPoint);
	#endif
		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER+AddContributionPointPoint, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER);
		// end 2014-02-06 by jhseol, 세력포인트에 따른 거점 레벨링 밸런스 패치 - 연승에 따른 추가 세력포인트 지급

//		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER);
		ms_pFieldIOCP->m_InflWarManager.CalcConsecutiveVictoriesPoint(byAttackerCharInflTy);
	}
#else
	ms_pFieldIOCP->m_InflWarManager.AddContributionPoint(byAttackerCharInflTy, ADD_CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER);
#endif
	// end 2013-05-09 by hskim, 세력 포인트 개선

// 2007-06-14 by cmkwon, 세력전 보상 수정 - 해당 세력 모든 유저에서 아래와 같이 수정됨
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-15 by dhjin, WarPoint 증가 (100점)
//	ms_pFieldIOCP->SendWarPointToInflClient(byAttackerCharInflTy, ADD_WARPOINT_STRATEGYPOINT_MONSTER);

	// 2007-06-14 by cmkwon, 세력전 보상 수정 - 현재맵과 이전맵 유저에게 WarPoint 추가
	i_pFMapChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	// 2006-11-30 by cmkwon, 공격측의 이전맵을 가져온다
	CFieldMapChannel		*pBackFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex, 0));
	if(pBackFMChann)
	{
		pBackFMChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 자동 소멸시 백맵2 에 공격측 WarPoint 보상
	CFieldMapChannel		*pBackFMChann2 = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex2, 0));
	if(pBackFMChann2)
	{
		pBackFMChann2->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}

	// 2008-01-07 by dhjin, 세력 보상 수정 - 
	i_pFMapChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	if(pBackFMChann)
	{
		pBackFMChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 자동 소멸시 백맵2 에 방어측 WarPoint 보상 
	if(pBackFMChann2)
	{
		pBackFMChann2->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, WPUT_STRATEGYPOINTWAR);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-20 by cmkwon, 현재맵 유저에게 아이템 지급
	vectMONSTER2ITEMPtr		vectDropItemList;
	ms_pFieldIOCP->GetDropItemList(&vectDropItemList, i_pFMon->MonsterInfoPtr->MonsterUnitKind);	
	for(int i=0; i < vectDropItemList.size(); i++)
	{
		i_pFMapChann->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		if(pBackFMChann)
		{// 2006-11-30 by cmkwon, 공격측의 이전맵의 유저에게도 지급한다.
			pBackFMChann->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 자동 소멸시 백맵2 에 공격측 아이템 보상
		if(pBackFMChann2)
		{// 2006-11-30 by cmkwon, 공격측의 이전맵의 유저에게도 지급한다.
			pBackFMChann2->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		}
	}

// 2009-12-04 by cmkwon, 거점전시 백맵/백맵2 몬스터 소환 처리 버그 수정 - 아래와 같이 m_InflWarManager.DeleteSPWarInfoResult() 함수 호출 이후에 처리하게 수정 
// 	//////////////////////////////////////////////////////////////////////////
// 	// 2007-08-29 by dhjin, 몬스터 생성이 가능하게 다시 설정
// 	INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);
// 	pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
// 	i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 	if(pBackFMChann)
// 	{
// 		pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
// 		pBackFMChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 	}
// 
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 자동 소멸시 백맵2 에 본스터 소환 가능하게 변경
// 	if(pBackFMChann2)
// 	{
// 		pMonster->mapChann			= pBackFMChann2->GetMapChannelIndex();
// 		pBackFMChann2->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 거점전 종료 시 정보 설정
	// 2008-07-25 by dhjin, STRATEGYPOINT_SUMMONTIME_BY_INFLUENCEBOSS/2 값이 적용 안되어 밑과 같이 수정
//	if(STRATEGYPOINT_SUMMONTIME_BY_INFLUENCEBOSS/2 == i_pFMon->MonsterInfoPtr->MPOptionParam1)
//	{
//		ms_pFieldIOCP->m_InflWarManager.SetSPWarInfoResultByWarEnd(i_pFMapChann->GetMapChannelIndex().MapIndex, byAttackerCharInflTy);
//		ms_pFieldIOCP->m_InflWarManager.SendLogSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);
//		ms_pFieldIOCP->m_InflWarManager.DeleteSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);
// 	}
	ms_pFieldIOCP->m_InflWarManager.SetSPWarInfoResultByWarEnd(i_pFMapChann->GetMapChannelIndex().MapIndex, byAttackerCharInflTy);
	ms_pFieldIOCP->m_InflWarManager.SendLogSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);
	ms_pFieldIOCP->m_InflWarManager.DeleteSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);
	
	//////////////////////////////////////////////////////////////////////////
	// 2009-12-04 by cmkwon, 거점전시 백맵/백맵2 몬스터 소환 처리 버그 수정 - m_InflWarManager.DeleteSPWarInfoResult()함수 호출 이후에 처리되어야 함.
	INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);
	if(ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(i_pFMapChann->GetMapChannelIndex().MapIndex))
	{
		pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
		i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
	}
	if(pBackFMChann && ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(pBackFMChann->GetMapChannelIndex().MapIndex))
	{
		pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
		pBackFMChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
	}
	if(pBackFMChann2 && ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(pBackFMChann2->GetMapChannelIndex().MapIndex))
	{
		pMonster->mapChann			= pBackFMChann2->GetMapChannelIndex();
		pBackFMChann2->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-12-23 by dhjin, 전쟁 보상 추가안
	ms_pFieldIOCP->PayCStrategyPointWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex, byAttackerCharInflTy);
	ms_pFieldIOCP->DeleteCStrategyPointWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex);	
	// 2009-02-11 by dhjin, 시스템 로그 보완
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] OutPostWarNoti StrategyPoint WarContributionEnd : autoDes\r\n");

}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnStrategyPointMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-20 ~ 2006-11-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnStrategyPointMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by cmkwon
	char szSysLog[1024];
	sprintf(szSysLog, "	[Notify]: StategyPoint Monster Dead !! Map(%s) MonInfo(%s:%d) MonIdx(%d) MonBell(%s)\r\n"
		, GET_MAP_STRING(i_pFMapChann->GetMapChannelIndex()), i_pFMon->MonsterInfoPtr->MonsterName
		, i_pFMon->MonsterInfoPtr->MonsterUnitKind, i_pFMon->MonsterIndex, GetMonsterBellString(i_pFMon->MonsterInfoPtr->Belligerence));
	g_pFieldGlobal->WriteSystemLog(szSysLog);
	DbgOut(szSysLog);

	//////////////////////////////////////////////////////////////////////////
	// 2007-02-23 by dhjin, 거점 정보 삭제
	ms_pFieldIOCP->m_InflWarManager.DeleteSummonStrategyPointInfo(i_pFMapChann->GetMapChannelIndex());
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 전략포인트 몬스터 죽은 시간 현재시간으로 설정 - 전략포인트 소유 함(2시간동안)
	i_pFMapChann->SetLastTickStrategyPointMonsterDeaded(timeGetTime());

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-21 by cmkwon, 공격측 세력을 선택한다.
	BYTE byAttackerCharInflTy = GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence);
	BYTE byLoseCharInflTy = INFLUENCE_TYPE_UNKNOWN;		// 2008-01-07 by dhjin, 세력 보상 수정 - 
	if(INFLUENCE_TYPE_VCN == byAttackerCharInflTy)
	{
		byAttackerCharInflTy		= INFLUENCE_TYPE_ANI;
		byLoseCharInflTy			= INFLUENCE_TYPE_VCN;
	}
	else
	{
		byAttackerCharInflTy		= INFLUENCE_TYPE_VCN;
		byLoseCharInflTy			= INFLUENCE_TYPE_ANI;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	BOOL bMotherShipWar = ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(byAttackerCharInflTy);
	BYTE byWPUpdateTy	= (bMotherShipWar == FALSE) ? WPUT_STRATEGYPOINTWAR : WPUT_MOTHERSHIPWAR;

	///////////////////////////////////////////////////////////////////////////////
	// 2006-02-09 by cmkwon, 보스몬스터 폭발된것을 모든 클라이언트로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_WAR_MONSTER_DEAD, T_FC_WAR_MONSTER_DEAD, pSMonDead, SendBuf);
	pSMonDead->MonsterUnitKind	= i_pFMon->MonsterInfoPtr->MonsterUnitKind;
	pSMonDead->MapChannIdx		= i_pFMapChann->GetMapChannelIndex();
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_WAR_MONSTER_DEAD), INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN		// 2013-08-02 by jhseol, 세력포인트 컨텐츠 미반영 국가 거점 파괴시 세력포인트 안주는 버그 수정 - 기존코드 컨텐츠 구분
	if( FALSE == ms_pFieldIOCP->m_InflWarManager.CheckSummonBoss() )
	{
		// 2013-08-14 by jhseol, 거점전 리뉴얼 - 세력포인트 비율 변경
// 		BYTE nSPLevel = 1;
// 	#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG
// 		BYTE nMonsterInfl = INFLUENCE_TYPE_UNKNOWN;
// 		if ( BELL_STRATEGYPOINT_VCN == i_pFMon->MonsterInfoPtr->Belligerence )
// 		{
// 			nMonsterInfl = INFLUENCE_TYPE_VCN;
// 		}
// 		else if ( BELL_STRATEGYPOINT_ANI == i_pFMon->MonsterInfoPtr->Belligerence )
// 		{
// 			nMonsterInfl = INFLUENCE_TYPE_ANI;
// 		}
// 		nSPLevel = ms_pFieldIOCP->GetMonsterGeade_SummonMonsterLevelBySummonMonsterNum(MONSTER_GRADE_TYPE_STRATEGYPOINT, nMonsterInfl, i_pFMon->MonsterInfoPtr->MonsterUnitKind);
// 	#endif
// 		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER*nSPLevel, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER*nSPLevel);
		// end 2013-08-14 by jhseol, 거점전 리뉴얼 - 세력포인트 비율 변경
		// 2014-02-06 by jhseol, 세력포인트에 따른 거점 레벨링 밸런스 패치 - 연승에 따른 추가 세력포인트 지급
		INT AddContributionPointPoint = 0;
		INT VictoriesPoint = ms_pFieldIOCP->m_InflWarManager.GetConsecutiveVictoriesPoint(byAttackerCharInflTy);	// 지금까지 연승한 연승 포인트
		VictoriesPoint = min(VictoriesPoint++, 8);
	#ifdef SC_STRATEGYPOINTWAR_RENEWAL_JHSEOL_SSJUNG
		AddContributionPointPoint = GetAddSTRATEGYPOINTbyVictoriesPoint(VictoriesPoint);
	#endif
		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER+AddContributionPointPoint, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER);
		// end 2014-02-06 by jhseol, 세력포인트에 따른 거점 레벨링 밸런스 패치 - 연승에 따른 추가 세력포인트 지급

//		ms_pFieldIOCP->m_InflWarManager.CalcContributionPoint(byAttackerCharInflTy, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_WINNER, CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER_LOSER);
		ms_pFieldIOCP->m_InflWarManager.CalcConsecutiveVictoriesPoint(byAttackerCharInflTy);
	}
#else
	ms_pFieldIOCP->m_InflWarManager.AddContributionPoint(byAttackerCharInflTy, ADD_CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER);
#endif
	// end 2013-05-09 by hskim, 세력 포인트 개선

// 2007-06-14 by cmkwon, 세력전 보상 수정 - 해당 세력 모든 유저에서 아래와 같이 수정됨
//	//////////////////////////////////////////////////////////////////////////
//	// 2007-05-15 by dhjin, WarPoint 증가 (100점)
//	ms_pFieldIOCP->SendWarPointToInflClient(byAttackerCharInflTy, ADD_WARPOINT_STRATEGYPOINT_MONSTER);

	// 2007-06-14 by cmkwon, 세력전 보상 수정 - 현재맵과 이전맵 유저에게 WarPoint 추가
	i_pFMapChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	// 2006-11-30 by cmkwon, 공격측의 이전맵을 가져온다
	CFieldMapChannel		*pBackFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex, 0));
	if(pBackFMChann)
	{
		pBackFMChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 폭파시 백맵2 에 공격측 WarPoint 보상
	CFieldMapChannel		*pBackFMChann2 = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(i_pFMapChann->m_pFieldMapProject->m_nBeforeMapIndex2, 0));
	if(pBackFMChann2)
	{
		pBackFMChann2->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER, FALSE, byAttackerCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
	}
	
	// 2008-01-07 by dhjin, 세력 보상 수정 - 모선전이 아닐때만 보상 지급
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(byAttackerCharInflTy))
	{
		i_pFMapChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
		if(pBackFMChann)
		{
			pBackFMChann->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 폭파시 백맵2 에 방어측 WarPoint 보상
		if(pBackFMChann2)
		{
			pBackFMChann2->AddWarPointInMap(ADD_WARPOINT_STRATEGYPOINT_MONSTER_BY_LOSE, FALSE, byLoseCharInflTy, byWPUpdateTy);	// 2009-01-22 by cmkwon, 전쟁 관련 게임 로그 수정 - CFieldMapChannel::AddWarPointInMap()에 인자(, BYTE i_byWPUpdateTy=WPUT_GENERAL) 추가
		}

		//////////////////////////////////////////////////////////////////////////
		// 2008-12-23 by dhjin, 전쟁 보상 추가안
		ms_pFieldIOCP->PayCStrategyPointWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex, byAttackerCharInflTy);
		ms_pFieldIOCP->DeleteCStrategyPointWarContributionCalculation(i_pFMapChann->GetMapChannelIndex().MapIndex);	
		// 2009-02-11 by dhjin, 시스템 로그 보완
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] OutPostWarNoti StrategyPoint WarContributionEnd : Dead\r\n");
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-20 by cmkwon, 현재맵 유저에게 아이템 지급
	vectMONSTER2ITEMPtr		vectDropItemList;
	ms_pFieldIOCP->GetDropItemList(&vectDropItemList, i_pFMon->MonsterInfoPtr->MonsterUnitKind);
	for(int i=0; i < vectDropItemList.size(); i++)
	{
		i_pFMapChann->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		if(pBackFMChann)
		{// 2006-11-30 by cmkwon, 공격측의 이전맵의 유저에게도 지급한다.
			pBackFMChann->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		}
		
		///////////////////////////////////////////////////////////////////////////////
		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 폭파시 백맵2 에 공격측 아이템 보상
		if(pBackFMChann2)
		{// 2006-11-30 by cmkwon, 공격측의 이전맵의 유저에게도 지급한다.
			pBackFMChann2->InsertItemInMap(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byAttackerCharInflTy);
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-09-05 by dhjin, 모선전시 파괴 된 건지 체크하여 텔레포트 시스템 적용
	if(ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(byAttackerCharInflTy))
	{
		// 2007-09-20 by cmkwon, 텔레포트 수정 - 기본값으로 초기화 한다
		i_pFMapChann->SetTelePortState(TELEPORT_STATE_NONE);

		INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_TELEPORT_SUMMON, T_FN_MONSTER_TELEPORT_SUMMON, pSummon, SendBuf2);
		pSummon->mapChann	= i_pFMapChann->GetMapChannelIndex();
		pSummon->bell1		= (INFLUENCE_TYPE_VCN == byAttackerCharInflTy) ? BELL_INFLUENCE_TELEPORT_VCN : BELL_INFLUENCE_TELEPORT_ANI;
		i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_TELEPORT_SUMMON));
	}
	else
	{
		//////////////////////////////////////////////////////////////////////////
		// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 거점전 종료 시 정보 설정
		ms_pFieldIOCP->m_InflWarManager.SetSPWarInfoResultByWarEnd(i_pFMapChann->GetMapChannelIndex().MapIndex, byAttackerCharInflTy);
		ms_pFieldIOCP->m_InflWarManager.SendLogSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);
		ms_pFieldIOCP->m_InflWarManager.DeleteSPWarInfoResult(i_pFMapChann->GetMapChannelIndex().MapIndex);

// 2009-12-04 by cmkwon, 거점전시 백맵/백맵2 몬스터 소환 처리 버그 수정 - 		
// 		//////////////////////////////////////////////////////////////////////////
// 		// 2007-08-29 by dhjin, 모선전이 아니면 몬스터 생성이 가능하게 다시 설정
// 		INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);		
// 		pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
// 		i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 		if(pBackFMChann)
// 		{
// 			pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
// 			pBackFMChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 		}
// 		
// 		///////////////////////////////////////////////////////////////////////////////
// 		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 전략포인트 폭파시 백맵2 에 몬스터 소환 가능하게 변경
// 		if(pBackFMChann2)
// 		{
// 			pMonster->mapChann			= pBackFMChann2->GetMapChannelIndex();
// 			pBackFMChann2->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
// 		}	
		///////////////////////////////////////////////////////////////////////////////
		// 2009-12-04 by cmkwon, 거점전시 백맵/백맵2 몬스터 소환 처리 버그 수정 - 몬스터 생성 가능 체크를 하고 처리
 		INIT_MSG_WITH_BUFFER(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, T_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE, pMonster, SendBuf2);
		if(ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(i_pFMapChann->GetMapChannelIndex().MapIndex))
		{
			pMonster->mapChann			= i_pFMapChann->GetMapChannelIndex();
	 		i_pFMapChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
		}
		if(pBackFMChann && ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(pBackFMChann->GetMapChannelIndex().MapIndex))
		{
			pMonster->mapChann			= pBackFMChann->GetMapChannelIndex();
			pBackFMChann->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
		}
		if(pBackFMChann2 && ms_pFieldIOCP->m_InflWarManager.CheckCreateableMonsterInMap(pBackFMChann2->GetMapChannelIndex().MapIndex))
		{
			pMonster->mapChann			= pBackFMChann2->GetMapChannelIndex();
			pBackFMChann2->Send2NPCServerW(SendBuf2, MSG_SIZE(MSG_FN_MONSTER_CREATE_IN_MAPCHANNEL_BYVALUE));
		}
	}

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnTeleportMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정
/// \author		cmkwon
/// \date		2007-09-20 ~ 2007-09-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnTeleportMonsterCreated(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	if(0 != i_pFMapChann->GetMapChannelIndex().ChannelIndex)
	{// 2007-09-20 by cmkwon, 텔레포트 수정 - 0번 채널만 처리
		return;
	}

	// 2007-09-20 by cmkwon, 텔레포트 수정 - 해당 세력의 모선전이 진행중일때만 처리
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl( (BELL_INFLUENCE_TELEPORT_VCN == i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_VCN : INFLUENCE_TYPE_ANI ))
	{
		return;
	}

	i_pFMapChann->SetTelePortState(TELEPORT_STATE_READY);			// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정 - 기본 무적 모드	

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 - 
	ms_pFieldIOCP->m_InflWarManager.SetMSWarInfo(i_pFMapChann->GetMapChannelIndex().MapIndex, T_MSWARINFO_MODIFY_CREATE_TELEPORT, MS_WAR_HP_RATE, TELEPORT_STATE_READY, i_pFMon->MonsterInfoPtr->Belligerence);

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnTeleportMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
/// \brief		// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정
/// \author		cmkwon
/// \date		2007-09-20 ~ 2007-09-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnTeleportMonsterDead(CFieldMonster *i_pFMon, CFieldMapChannel *i_pFMapChann)
{
	if(0 != i_pFMapChann->GetMapChannelIndex().ChannelIndex)
	{// 2007-09-20 by cmkwon, 텔레포트 수정 - 0번 채널만 처리
		return;
	}

	// 2007-09-20 by cmkwon, 텔레포트 수정 - 해당 세력의 모선전이 진행중일때만 처리
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl( (BELL_INFLUENCE_TELEPORT_VCN == i_pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_VCN : INFLUENCE_TYPE_ANI ))
	{
		return;
	}
	
	// 2007-11-06 by dhjin, 텔레포트 파괴 보상 추가
	if(i_pFMapChann->GetTelePortSummonFirst())
	{// 2007-11-06 by dhjin, 텔레포트를 처음 파괴 했으므로 세력 유저에게 보상을 지급한다.
		BYTE byDefenderCharInflTy = GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(i_pFMon->MonsterInfoPtr->Belligerence);
		if(INFLUENCE_TYPE_VCN == byDefenderCharInflTy)
		{
			byDefenderCharInflTy		= INFLUENCE_TYPE_ANI;
		}
		else
		{
			byDefenderCharInflTy		= INFLUENCE_TYPE_VCN;
		}

// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
#else
		ms_pFieldIOCP->m_InflWarManager.AddContributionPoint(byDefenderCharInflTy, ADD_CONTRIBUTIONPOINT_STRATEGYPOINT_MONSTER);
#endif
// end 2013-05-09 by hskim, 세력 포인트 개선

		ms_pFieldIOCP->SendWarPointToInflClient(byDefenderCharInflTy, ADD_WARPOINT_STRATEGYPOINT_MONSTER);

		// 2007-11-06 by dhjin, 아이템 지급
		vectMONSTER2ITEMPtr		vectDropItemList;
		ms_pFieldIOCP->GetDropItemList(&vectDropItemList, i_pFMon->MonsterInfoPtr->MonsterUnitKind);
		for(int i=0; i < vectDropItemList.size(); i++)
		{
			ms_pFieldIOCP->InsertItemAllCharacter(vectDropItemList[i]->ItemNumber, vectDropItemList[i]->MinCount, byDefenderCharInflTy);
		}
	}

	ms_pFieldIOCP->m_InflWarManager.DeleteTelePortInfoBuing(i_pFMapChann->GetMapChannelIndex().MapIndex);

	i_pFMapChann->SetTelePortState(TELEPORT_STATE_NONE);			// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정 - 
	i_pFMapChann->SetTelePortSummonFirst(FALSE);

	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_TELEPORT_DESTROY, T_FC_EVENT_TELEPORT_DESTROY, pSTeleport, SendBuf);
	pSTeleport->MapIndex					= i_pFMapChann->GetMapChannelIndex().MapIndex;
	pSTeleport->bInactivateByOtherTeleport	= FALSE;
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_EVENT_TELEPORT_DESTROY),INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 - 
	ms_pFieldIOCP->m_InflWarManager.SetMSWarInfo(i_pFMapChann->GetMapChannelIndex().MapIndex, T_MSWARINFO_MODIFY_CHANGE_TELEPORT_STATE, MS_WAR_MIN_HP_RATE, TELEPORT_STATE_NONE, i_pFMon->MonsterInfoPtr->Belligerence);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsValidCharacterEnemy(CFieldIOCPSocket *i_pAttFISoc, CFieldIOCPSocket *i_pTarFISoc, BOOL i_bTargetLiveCheck/*=TRUE*/)
/// \brief		
/// \author		dhjin
/// \date		2006-12-04 ~ 2006-12-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsValidCharacterEnemy(CFieldIOCPSocket *i_pAttFISoc, CFieldIOCPSocket *i_pTarFISoc, BOOL i_bTargetLiveCheck/*=TRUE*/)
{
	if(NULL == i_pAttFISoc
		|| NULL == i_pTarFISoc
		|| FALSE == i_pAttFISoc->IsValidCharacter(FALSE)
		|| FALSE == i_pTarFISoc->IsValidCharacter(i_bTargetLiveCheck))
	{
		return FALSE;
	}

	if(COMPARE_INFLUENCE(i_pAttFISoc->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL)
		&& COMPARE_INFLUENCE(i_pTarFISoc->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL))
	{// 2006-12-04 by dhjin, 둘다 일반 세력 - 1:1 PK만 체크(파티불가, 여단가입불가)

		if(FALSE == IS_VALID_CLIENT_INDEX(i_pAttFISoc->m_peerP2PPKClientIndex)
			|| FALSE == IS_VALID_CLIENT_INDEX(i_pTarFISoc->m_peerP2PPKClientIndex))
		{
			return FALSE;
		}

		if(i_pAttFISoc->m_peerP2PPKClientIndex != i_pTarFISoc->GetCharacter()->ClientIndex)
		{
			return FALSE;
		}
		
		return TRUE;
	}
	else if(COMPARE_INFLUENCE(i_pAttFISoc->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL)
		|| COMPARE_INFLUENCE(i_pTarFISoc->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL))
	{// 2006-12-04 by dhjin, 둘중에 하나가 일반 세력

		return FALSE;
	}

	if(i_pAttFISoc->GetCharacter()->InfluenceType != i_pTarFISoc->GetCharacter()->InfluenceType)
	{// 2006-12-04 by dhjin, 두 세력이 다르다
		return TRUE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-04 by dhjin, 1:1 PK 체크
	if(IS_VALID_CLIENT_INDEX(i_pAttFISoc->m_peerP2PPKClientIndex) && i_pAttFISoc->m_bP2PPKStarted		// 2009-02-03 by cmkwon, 1:1 PK 신청 도중에 빅붐 사용 버그 수정 - 실제 1:1 PK가 시작된 상태 체크 추가
		&& IS_VALID_CLIENT_INDEX(i_pTarFISoc->m_peerP2PPKClientIndex) && i_pTarFISoc->m_bP2PPKStarted	// 2009-02-03 by cmkwon, 1:1 PK 신청 도중에 빅붐 사용 버그 수정 - 실제 1:1 PK가 시작된 상태 체크 추가
		&& i_pAttFISoc->m_peerP2PPKClientIndex == i_pTarFISoc->GetCharacter()->ClientIndex)
	{
		return TRUE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-04 by dhjin, 파티전 체크
	CFieldParty *pAttFParty = i_pAttFISoc->m_pFieldParty;
	CFieldParty *pTarFParty = i_pTarFISoc->m_pFieldParty;
	if(pAttFParty && pTarFParty
		&& pAttFParty->m_PeerBattlePartyID == pTarFParty->m_PartyID	&& pTarFParty->m_PeerBattlePartyID == pAttFParty->m_PartyID
		&& pAttFParty->m_PartyBattle.IsUsing() && pTarFParty->m_PartyBattle.IsUsing())
	{
		return TRUE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-04 by dhjin, 여단전 체크
	if(IS_VALID_UNIQUE_NUMBER(i_pAttFISoc->GetCharacter()->GuildUniqueNumber)
		&& IS_VALID_UNIQUE_NUMBER(i_pTarFISoc->GetCharacter()->GuildUniqueNumber))
	{
		mt_auto_lock mtGW(ms_pFieldIOCP->m_GuildWarManager.GetmtmapGuildWarPtr());	

		CGuildWar *pGuildWar = ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(i_pAttFISoc->GetCharacter()->GuildUniqueNumber);
		if (pGuildWar
			&& i_pTarFISoc->GetCharacter()->GuildUniqueNumber == pGuildWar->GetPeerGuildForGuildWar(i_pAttFISoc->GetCharacter()->GuildUniqueNumber)->uidGuildUID)
		{// 2006-12-04 by dhjin, 두 여단이 여단전을 하고 있다
			return TRUE;
		}
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsValidCharacterFriend(CFieldIOCPSocket *i_pAttFISoc, CFieldIOCPSocket *i_pTarFISoc, BOOL i_bTargetLiveCheck/*=TRUE*/)
/// \brief		유효한 아군 캐릭터 인가?
/// \author		cmkwon
/// \date		2007-03-07 ~ 2007-03-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsValidCharacterFriend(CFieldIOCPSocket *i_pAttFISoc, CFieldIOCPSocket *i_pTarFISoc, BOOL i_bTargetLiveCheck/*=TRUE*/)
{
	if(NULL == i_pAttFISoc
		|| NULL == i_pTarFISoc
		|| FALSE == i_pAttFISoc->IsValidCharacter(FALSE)
		|| FALSE == i_pTarFISoc->IsValidCharacter(i_bTargetLiveCheck))
	{
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-03-07 by cmkwon, 두 세력이 다르면 아군이 아니다
	if(i_pAttFISoc->GetCharacter()->InfluenceType != i_pTarFISoc->GetCharacter()->InfluenceType)
	{
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-03-07 by cmkwon, 둘이 PvP 중이면 아군이 아니다
	if(IS_VALID_CLIENT_INDEX(i_pAttFISoc->m_peerP2PPKClientIndex)
		&& IS_VALID_CLIENT_INDEX(i_pTarFISoc->m_peerP2PPKClientIndex)
		&& i_pAttFISoc->m_peerP2PPKClientIndex == i_pTarFISoc->GetCharacter()->ClientIndex)
	{
		return FALSE;
	}		
	
	///////////////////////////////////////////////////////////////////////////////
	// 2007-03-07 by cmkwon, 파티전 체크
	CFieldParty *pAttFParty = i_pAttFISoc->m_pFieldParty;
	CFieldParty *pTarFParty = i_pTarFISoc->m_pFieldParty;
	if(pAttFParty && pTarFParty
		&& pAttFParty->m_PeerBattlePartyID == pTarFParty->m_PartyID	&& pTarFParty->m_PeerBattlePartyID == pAttFParty->m_PartyID
		&& pAttFParty->m_PartyBattle.IsUsing() && pTarFParty->m_PartyBattle.IsUsing())
	{
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-03-07 by cmkwon, 여단전 체크
	if(IS_VALID_UNIQUE_NUMBER(i_pAttFISoc->GetCharacter()->GuildUniqueNumber)
		&& IS_VALID_UNIQUE_NUMBER(i_pTarFISoc->GetCharacter()->GuildUniqueNumber))
	{
		mt_auto_lock mtGW(ms_pFieldIOCP->m_GuildWarManager.GetmtmapGuildWarPtr());	

		CGuildWar *pGuildWar = ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(i_pAttFISoc->GetCharacter()->GuildUniqueNumber);
		if (pGuildWar
			&& i_pTarFISoc->GetCharacter()->GuildUniqueNumber == pGuildWar->GetPeerGuildForGuildWar(i_pAttFISoc->GetCharacter()->GuildUniqueNumber)->uidGuildUID)
		{// 2007-03-07 by cmkwon, 두 여단이 여단전을 하고 있다
			return FALSE;
		}
	}
	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsAllSameMap(CFieldMapChannel *pFMChann, vector<CFieldIOCPSocket*> *i_pvectFISockList)
/// \brief		
/// \author		cmkwon
/// \date		2007-02-12 ~ 2007-02-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsAllSameMap(CFieldMapChannel *pFMChann, vector<CFieldIOCPSocket*> *i_pvectFISockList)
{
	int nCnts = i_pvectFISockList->size();
	for(int i=0; i < nCnts; i++)
	{
		CFieldIOCPSocket *pFIS = (*i_pvectFISockList)[i];
		if(NULL == pFIS
			|| FALSE == pFIS->IsValidCharacter(FALSE)
			|| pFMChann != pFIS->GetCurrentFieldMapChannel())
		{
			return FALSE;
		}
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::OnPrimaryAttack( BYTE i_Atktype ) // 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리 (공격시 펫 공격을 구분하게 인자추가)
{
	// stealth 상태이면 return함
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{
		return FALSE;
	}

	if(IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{// 튜토리얼 맵에서는 총알 소모가 없다
		
		return TRUE;
	}
	// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리 (공격시 펫 공격이면 탄알 감소 없음)
	else if(i_Atktype==ATT_TYPE_PET_ATK)
	{ // 펫 어택 타입이면 탄알 감소가 필요 없다.
		return TRUE;
	}
	// END 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리 (공격시 펫 공격이면 탄알 감소 없음)

	ITEM_GENERAL *pItemGeneralPri = (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
	switch(pItemGeneralPri->ItemNum)
	{
	case 7002710:	// 1형 무기 - 훈련용 머신건
	case 7002750:	// 1형 무기 - 훈련용 그레네이드
	case 7002770:	// 1형 무기 - 훈련용 캐논
	case 7002740:	// 1형 무기 - 훈련용 개틀링
		{
			// 레벨에 상관없이 항상 총알 소모가 없다
		}
		return TRUE;
	}

// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//	///////////////////////////////////////////////////////////////////////////
//	// shotnum, multinum 등 관련 계산
//	DWORD	dwCurTick = timeGetTime();
//
//#ifdef _DEBUG
//	//DBGOUT("%d %d %d %d\n", (int)dwCurTick, (int)dwCurTick - (int)m_PrimaryTimeStamp, (int)m_ItemProwOut.ReAttacktime, (int)m_PrimaryShotNumCount);
//	SendString128(STRING_128_DEBUG_L3, "shotnum: %d vs %d, re-att time: %d vs %d"
//		, m_PrimaryShotNumCount
//		, CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor)
//		, dwCurTick - m_PrimaryTimeStamp
//		, CAtumSJ::GetReattackTime(&m_ItemProwOut, &m_ParamFactor));
//#endif
//
//	INT nPrimaryTimeDiff = dwCurTick - m_PrimaryTimeStamp;
//	INT nPrimaryReattackTime = CAtumSJ::GetReattackTime(&m_ItemProwOut, &m_ParamFactor);
//	INT nTotalPrimaryShotCount = CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor);
//
//	if (nPrimaryTimeDiff >= nPrimaryReattackTime)
//	{
//		m_PrimaryTimeStamp = dwCurTick;
//		m_PrimaryShotNumCount = nTotalPrimaryShotCount - 1;
//	}
//	else if (nPrimaryTimeDiff < nPrimaryReattackTime)
//	{
//		if (m_PrimaryShotNumCount <= 0)
//		{
//			//return FALSE;
//		}
//		else
//		{
//			m_PrimaryShotNumCount--;
//		}
//	}

	///////////////////////////////////////////////////////////////////////////
	// 탄통 처리
	if (IS_PRIMARY_WEAPON_1(m_ItemProwOut.Kind))		// 1-1형인 경우
	{
		// 2007-01-23 by cmkwon, _ATUM_LOAD_TEST부분 복구함
#ifdef _ATUM_LOAD_TEST	// 2004-03-11 by cmkwon, dummy 테스트 캐릭은 탄알을 체크하지 않는다.
		// 탄알을 감소
		if(0 != strnicmp(m_character.AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
		{	// 캐릭터 명이 loadtest로 시작하지 않으면

			ITEM_GENERAL *pItemGeneralPri = (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
			if (pItemGeneralPri->CurrentCount <= 0)
			{
				RechargeBullet(pItemGeneralPri);
				return FALSE;
			}
			pItemGeneralPri->CurrentCount--;
		}
#else
		// 탄알을 감소
		if (pItemGeneralPri->CurrentCount <= 0)
		{
			RechargeBullet(pItemGeneralPri);
			return FALSE;
		}
		pItemGeneralPri->CurrentCount--;
#endif // END - _ATUM_LOAD_TEST

//#ifdef _DEBUG
//		ITEM_GENERAL *pItemGeneralSec = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
//		int SecCount = ((pItemGeneralSec == NULL)?-1:pItemGeneralSec->CurrentCount);
//		SendString128Static(STRING_128_ADMIN_CMD, "1st: %d, 2nd: %d", pItemGeneralPri->CurrentCount, SecCount);
//#endif
	}
	else if (IS_PRIMARY_WEAPON_2(m_ItemProwOut.Kind))	// 1-2형(BEAM류)인 경우
	{
		// fuel을 감소
		if (m_character.CurrentEP <= 0)
		{
			// fuel이 부족함
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_NOT_ENOUGH_EP);
			return FALSE;
		}

		ChangeCurrentEP(-0.1f);
	}

// 2006-03-09 by cmkwon, 필요 없음
// 	else
// 	{
// 		// not reachable
// 		assert(0);
// 	}

// check: "그냥 쏘게 하기" 하면서 같이 삭제, 20041030, kelovon with ClientTeam
//	///////////////////////////////////////////////////////////////////
//	// 공격시는 DP 회복 처리를 위한 시간을 조금 줄인다.
//	if (m_PrimaryShotNumCount < CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor))
//	{
//		m_TimerManager.m_fDPRecoveryWeight = max(m_TimerManager.m_fDPRecoveryWeight-0.05f, 0.05f);
//	}

	return TRUE;
}

//int CFieldIOCPSocket::OnSecondaryAttack(int shotCount)
int CFieldIOCPSocket::OnSecondaryAttack( int shotCount, BYTE i_atktype /* = NULL */ )
{
	if (shotCount <= 0){				return 0;}
	
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK))
	if(this->IsInvisibleCharacter())
	{// stealth 상태이면 return함
		return 0;
	}

	if(IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{// 튜토리얼 맵에서는 총알 소모가 없다
		
		return shotCount;
	}

	// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리 (공격시 펫 공격이면 탄알 감소 처리 안함)
	else if( i_atktype == ATT_TYPE_PET_ATK )
	{ // 펫 어택 타입이면 탄알 감소가 필요 없다.
		return shotCount;
	}
	// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리 (공격시 펫 공격이면 탄알 감소 처리 안함)

	ITEM_GENERAL *pItemGeneralSec = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
	switch(pItemGeneralSec->ItemNum)
	{
	case 7900910:	// 2형 무기 - 초급용 로켓
	case 7900920:	// 2형 무기 - 초급용 미사일
	case 7900930:	// 2형 무기 - 초급용 번들
	case 7900940:	// 2형 무기 - 초급용 마인
		{
			// 레벨에 상관없이 항상 총알 소모가 없다
		}
		return shotCount;
	}

	int retShotCount = 0;				// 발사 가능한 shotCount수

// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
	retShotCount = shotCount;			// 그냥 할당
//	///////////////////////////////////////////////////////////////////////////
//	// shotnum, multinum 등 관련 계산
//	DWORD	dwCurTick = timeGetTime();
//
//	if (shotCount > CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor))
//	{
//		g_pFieldGlobal->WriteSystemLogEX(TRUE, "  Secondary Attack Error %s %s: recvd shot(%d) > total shot(%d)\r\n",
//			GetCharacterString(&m_character, string()),
//			GetItemString((ITEM_BASE*)m_ItemWingOut.ItemNum, string()),
//			shotCount,
//			CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor)
//		);
//		return 0;
//	}
//
//	if (m_ItemWingOut.ReAttacktime > 0)
//	{
//		INT nSecondaryTimeDiff = dwCurTick - m_SecondaryTimeStamp;
//		INT nSecondaryReattackTime = CAtumSJ::GetReattackTime(&m_ItemWingOut, &m_ParamFactor);
//		INT nTotalSecondaryShotCount = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);
//
//		if (nSecondaryTimeDiff >= nSecondaryReattackTime)
//		{
//			m_SecondaryTimeStamp = dwCurTick;
//
//			retShotCount = shotCount;
//			m_SecondaryShotNumCount = nTotalSecondaryShotCount - shotCount;
//		}
//		else if (nSecondaryTimeDiff < nSecondaryReattackTime)
//		{
//			if (m_SecondaryShotNumCount <= 0)
//			{
//				return 0;
//			}
//			else
//			{
//				retShotCount = min(shotCount, m_SecondaryShotNumCount);
//				m_SecondaryShotNumCount = max(m_SecondaryShotNumCount-shotCount, 0);
//			}
//		}
//	}

	///////////////////////////////////////////////////////////////////////////
	// 탄통 처리
	if (m_ItemWingOut.Kind == ITEMKIND_SHIELD)
	{
		if (pItemGeneralSec->CurrentCount <= 0)
		{
			// 남은 양 부족
			return 0;
		}
		retShotCount = shotCount;
	}
	else
	{
#ifdef _ATUM_LOAD_TEST	// 2004-03-11 by cmkwon, dummy 테스트 캐릭은 탄알을 체크하지 않는다.
		if(0 != strnicmp(m_character.AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
		{
			// shield류 이외의 무기는 탄알 감소
			if (pItemGeneralSec->CurrentCount <= 0)
			{
				RechargeBullet(pItemGeneralSec);
				return 0;
			}
			retShotCount = min(retShotCount, pItemGeneralSec->CurrentCount);
			pItemGeneralSec->CurrentCount = max(0, pItemGeneralSec->CurrentCount - retShotCount);

		}
#else
		// shield류 이외의 무기는 탄알 감소
		if (pItemGeneralSec->CurrentCount <= 0)
		{
			RechargeBullet(pItemGeneralSec);
			return 0;
		}
		retShotCount = min(retShotCount, pItemGeneralSec->CurrentCount);
		pItemGeneralSec->CurrentCount = max(0, pItemGeneralSec->CurrentCount - retShotCount);
#endif // END - _ATUM_LOAD_TEST

	}

	return retShotCount;
}

// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - 인자추가(, BYTE i_byRechargeBulletTy/*=BULLET_RECHARGE_TYPE_NORMAL*/)
int CFieldIOCPSocket::RechargeBullet(ITEM_GENERAL *pItemWeapon, BOOL bBulletConsumption, BYTE i_byRechargeBulletTy/*=BULLET_RECHARGE_TYPE_NORMAL*/)
{
	// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다
	int nMaxChargingCnt = pItemWeapon->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout()); // 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
	if(nMaxChargingCnt <= pItemWeapon->CurrentCount)
	{
		return pItemWeapon->CurrentCount;
	}

// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 위와 같이 수정함
//	if(pItemWeapon->ItemInfo->Charging <= pItemWeapon->CurrentCount)
//	{
//		return pItemWeapon->CurrentCount;
//	}
	///////////////////////////////////////////////////////////////////////////
	// 데모 계정 등에 사용 - 총알 소모 안 됨
	///////////////////////////////////////////////////////////////////////////
	//bBulletConsumption = FALSE;
	///////////////////////////////////////////////////////////////////////////
	// 데모 계정 등에 사용 - 총알 소모 안 됨
	///////////////////////////////////////////////////////////////////////////

	// 구경에 따른 탄알 정보 찾기
	multimap<BYTE, ITEM*>::iterator itrBullet = ms_pFieldIOCP->m_multiMapCaliber2Bullet.find(pItemWeapon->ItemInfo->Caliber);
	if (itrBullet == ms_pFieldIOCP->m_multiMapCaliber2Bullet.end())
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0018);
		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0019, pItemWeapon->ItemInfo->ItemName, pItemWeapon->ItemInfo->Caliber);

		return 0;
	}
	ITEM *pItemBulletInfo = itrBullet->second;

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

	// 캐릭터가 탄알 아이템을 소유하고 있는지에 대한 여부 확인
	ITEM_GENERAL *pItemBullet = m_ItemManager.GetFirstItemGeneralByItemNum(pItemBulletInfo->ItemNum);
	if (pItemBullet == NULL && bBulletConsumption)
	{
		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0020, pItemBulletInfo->ItemName, pItemBulletInfo->ItemNum);

		SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_NOT_ENOUGH_BULLET, (IS_PRIMARY_WEAPON(pItemWeapon->Kind)?ITEMKIND_PRIMARY_WEAPON_ALL:ITEMKIND_SECONDARY_WEAPON_ALL));
		return 0;
	}

	int nRechargeCount = 0;
	if (bBulletConsumption)
	{
		// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 아래와 같이 수정함
		//nRechargeCount = min(pItemBullet->CurrentCount, pItemWeapon->ItemInfo->Charging - pItemWeapon->CurrentCount);
		nRechargeCount = min(pItemBullet->CurrentCount, nMaxChargingCnt - pItemWeapon->CurrentCount);
	}
	else
	{
		// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 아래와 같이 수정함
		//nRechargeCount = pItemWeapon->ItemInfo->Charging - pItemWeapon->CurrentCount;
		nRechargeCount = nMaxChargingCnt - pItemWeapon->CurrentCount;
	}

// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다 - 주석 처리 함
//#ifdef _DEBUG
//	ASSERT_ASSERT(nRechargeCount >= 0);
//	ASSERT_ASSERT(pItemWeapon->ItemInfo->Charging > 0);
//	ASSERT_ASSERT(nRechargeCount <= pItemWeapon->ItemInfo->Charging);
//#endif

	// Weapon의 count 변경
	m_ItemManager.UpdateItemCountByPointer(pItemWeapon, nRechargeCount, IUT_BULLET, ITEM_IN_CHARACTER, TRUE, FALSE);
	// Bullet의 count 변경
	if (bBulletConsumption)
	{
		m_ItemManager.UpdateItemCountByPointer(pItemBullet, -1*nRechargeCount, IUT_BULLET);
	}

	if (IS_PRIMARY_WEAPON(pItemWeapon->ItemInfo->Kind))
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_PRI_BULLET_RELOADED, T_FC_BATTLE_PRI_BULLET_RELOADED, pPriBulletReloded, pPriBulletRelodedBuf);
		pPriBulletReloded->BulletCount = pItemWeapon->CurrentCount;
		pPriBulletReloded->RechargeCount	= nRechargeCount;			// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - 추가된 필드 설정
		pPriBulletReloded->RechargeType		= i_byRechargeBulletTy;		// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - 추가된 필드 설정
		SendAddData(pPriBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_PRI_BULLET_RELOADED));
// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//		m_PrimaryShotNumCount = CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor);
	}
	else if (IS_SECONDARY_WEAPON(pItemWeapon->ItemInfo->Kind))
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SEC_BULLET_RELOADED, T_FC_BATTLE_SEC_BULLET_RELOADED, pSecBulletReloded, pSecBulletRelodedBuf);
		pSecBulletReloded->BulletCount = pItemWeapon->CurrentCount;
		pSecBulletReloded->RechargeCount	= nRechargeCount;			// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - 추가된 필드 설정
		pSecBulletReloded->RechargeType		= i_byRechargeBulletTy;		// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - 추가된 필드 설정
		SendAddData(pSecBulletRelodedBuf, MSG_SIZE(MSG_FC_BATTLE_SEC_BULLET_RELOADED));
// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//		m_SecondaryShotNumCount = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);
	}
	else
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "FATAL ERROR: Invalid Item Kind @RechargeBullet(), %s %s\r\n",
			GetCharacterString(&m_character, string()),
			GetItemGeneralString(pItemWeapon, string()));
		return FALSE;
	}

//#ifdef _DEBUG
//	ITEM_GENERAL *pItemGeneralPri = (ITEM_GENERAL*)m_ItemProwOut.ItemNum;
//	int PriCount = ((pItemGeneralPri == NULL)?-1:pItemGeneralPri->Count);
//	ITEM_GENERAL *pItemGeneralSec = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
//	int SecCount = ((pItemGeneralSec == NULL)?-1:pItemGeneralSec->Count);
//	SendString128Static(STRING_128_ADMIN_CMD, "Recharged! 1st: %d, 2nd: %d", PriCount, SecCount);
//#endif

	return nRechargeCount;
}

void CFieldIOCPSocket::SaveCurrentBulletCount(ITEM_GENERAL *pItemWeapon)
{
	if (pItemWeapon != NULL)
	{
		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 밑과 같이 수정, 인피 진행 중 아이템 수정
// 		QPARAM_UPDATEITEMCOUNT *pQParam = new QPARAM_UPDATEITEMCOUNT;
// 		pQParam->ItemUniqueNumber		= pItemWeapon->UniqueNumber;
// 		pQParam->Count					= pItemWeapon->CurrentCount;
// 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemCount, this, m_character.AccountUniqueNumber, pQParam);
		if(TRUE == g_pFieldGlobal->IsArenaServer()) {
			this->m_ItemManager.ItemUpdateByInfinityPlaying(pItemWeapon);
		}
		else {
			QPARAM_UPDATEITEMCOUNT *pQParam = new QPARAM_UPDATEITEMCOUNT;
			pQParam->ItemUniqueNumber		= pItemWeapon->UniqueNumber;
			pQParam->Count					= pItemWeapon->CurrentCount;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemCount, this, m_character.AccountUniqueNumber, pQParam);
		}
	}
}

// check: 필요할 때 살리자
//void CFieldIOCPSocket::SaveCurrentEndurance(ITEM_GENERAL *i_pItem)
//{
//	if (i_pItem != NULL)
//	{
//		QPARAM_UPDATE_ENDURANCE *pQParam = new QPARAM_UPDATE_ENDURANCE;
//		pQParam->ItemUniqueNumber = i_pItem->UniqueNumber;
//		pQParam->Endurance = i_pItem->CurrentEndurance;
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(this, pQParam, QT_UpdateEndurance);
//	}
//}

// Character의 변경된 정보를 Client로 전송하는 함수
void CFieldIOCPSocket::SendCharacterInfo(MessageType_t msgType)
{
	int		nUsedBytes = 0;
	BYTE	buffer[SIZE_MAX_PACKET];
	BYTE	SendBufNPC[SIZE_MAX_PACKET];

	*(MessageType_t*)buffer = msgType;
	nUsedBytes = SIZE_FIELD_TYPE_HEADER;
	switch(msgType)
	{
	case T_FC_CHARACTER_CHANGE_HPDPSPEP:
		{
			MSG_FC_CHARACTER_CHANGE_HPDPSPEP	*pChangeHPDPSPEP = NULL;
			pChangeHPDPSPEP = (MSG_FC_CHARACTER_CHANGE_HPDPSPEP*)(buffer + nUsedBytes);
			pChangeHPDPSPEP->ClientIndex = m_character.ClientIndex;
			pChangeHPDPSPEP->HP = m_character.HP;
			pChangeHPDPSPEP->DP = m_character.DP;
			pChangeHPDPSPEP->EP = m_character.EP;
			pChangeHPDPSPEP->SP = m_character.SP;
			pChangeHPDPSPEP->CurrentHP = m_character.CurrentHP;
			pChangeHPDPSPEP->CurrentDP = m_character.CurrentDP;
			pChangeHPDPSPEP->CurrentEP = m_character.CurrentEP;
			pChangeHPDPSPEP->CurrentSP = m_character.CurrentSP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_HPDPSPEP);

			CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if (pFParty)
			{
				// send CurrentHP
				int offset = 0;
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_UPDATE_MEMBER_INFO_HP, T_FC_PARTY_UPDATE_MEMBER_INFO_HP, pPartyHP, PartySendBuf);
				pPartyHP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyHP->HP = m_character.HP;
				pPartyHP->CurrentHP = m_character.CurrentHP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_HP);
				INIT_MSG(MSG_FC_PARTY_UPDATE_MEMBER_INFO_DP, T_FC_PARTY_UPDATE_MEMBER_INFO_DP, pPartyDP, PartySendBuf+offset);
				pPartyDP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyDP->DP = m_character.DP;
				pPartyDP->CurrentDP = m_character.CurrentDP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_DP);
				INIT_MSG(MSG_FC_PARTY_UPDATE_MEMBER_INFO_EP, T_FC_PARTY_UPDATE_MEMBER_INFO_EP, pPartyEP, PartySendBuf+offset);
				pPartyEP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyEP->EP = m_character.EP;
				pPartyEP->CurrentEP = m_character.CurrentEP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_EP);
				pFParty->SendMsgToMembersMap(PartySendBuf, offset, m_pCurrentFieldMapChannel);
			}
		}
		break;
	case T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP:
		{
			MSG_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP	*pHPDPSPEP = NULL;
			pHPDPSPEP = (MSG_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP*)(buffer + nUsedBytes);
			pHPDPSPEP->ClientIndex = m_character.ClientIndex;
			pHPDPSPEP->CurrentHP = m_character.CurrentHP;
			pHPDPSPEP->CurrentDP = m_character.CurrentDP;
			pHPDPSPEP->CurrentEP = m_character.CurrentEP;
			pHPDPSPEP->CurrentSP = m_character.CurrentSP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
#ifdef _DEBUG
			SendString128(STRING_128_DEBUG_L3, "DP: %d, Current %4.2f", m_character.DP, m_character.CurrentDP);
#endif

			CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if (pFParty)
			{
				// send CurrentHP
				int offset = 0;
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP, pPartyHP, PartySendBuf);
				pPartyHP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyHP->CurrentHP = m_character.CurrentHP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP);
				INIT_MSG(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP, pPartyDP, PartySendBuf+offset);
				pPartyDP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyDP->CurrentDP = m_character.CurrentDP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP);
				INIT_MSG(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP, pPartyEP, PartySendBuf+offset);
				pPartyEP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyEP->CurrentEP = m_character.CurrentEP;
				offset += MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP);
				pFParty->SendMsgToMembersMap(PartySendBuf, offset, m_pCurrentFieldMapChannel);
			}
			///////////////////////////////////////////////////////////////////
			// NPC 서버에도 클라이언트의 HP 변경 정보를 전송한다.
			INIT_MSG(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, T_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, pSendChangeHPDPSPEP, SendBufNPC);
			pSendChangeHPDPSPEP->ChannelIndex = m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			pSendChangeHPDPSPEP->ClientIndex = m_character.ClientIndex;
			pSendChangeHPDPSPEP->CurrentHP = m_character.CurrentHP;
			pSendChangeHPDPSPEP->CurrentDP = m_character.CurrentDP;
			pSendChangeHPDPSPEP->CurrentEP = m_character.CurrentEP;
			pSendChangeHPDPSPEP->CurrentSP = m_character.CurrentSP;
			m_pCurrentFieldMapChannel->Send2NPCServerW(SendBufNPC, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP));
		}
		break;
	case T_FC_CHARACTER_CHANGE_CURRENTHP:
		{
			MSG_FC_CHARACTER_CHANGE_CURRENTHP	*pHP = NULL;
			pHP = (MSG_FC_CHARACTER_CHANGE_CURRENTHP*)(buffer + nUsedBytes);
			pHP->ClientIndex = m_character.ClientIndex;
			pHP->CurrentHP = m_character.CurrentHP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_CURRENTHP);

			CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if (pFParty)
			{
				// send CurrentHP
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP, pPartyHP, pPartyHPBuf);
				pPartyHP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyHP->CurrentHP = m_character.CurrentHP;
				pFParty->SendMsgToMembersMap(pPartyHPBuf, MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_HP), m_pCurrentFieldMapChannel);
			}

			///////////////////////////////////////////////////////////////////
			// NPC 서버에도 클라이언트의 HP 변경 정보를 전송한다.
			INIT_MSG(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, T_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, pSendChangeHPDPSPEP, SendBufNPC);
			pSendChangeHPDPSPEP->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			pSendChangeHPDPSPEP->ClientIndex	= m_character.ClientIndex;
			pSendChangeHPDPSPEP->CurrentHP	= m_character.CurrentHP;
			pSendChangeHPDPSPEP->CurrentDP	= m_character.CurrentDP;
			pSendChangeHPDPSPEP->CurrentEP	= m_character.CurrentEP;
			pSendChangeHPDPSPEP->CurrentSP	= m_character.CurrentSP;
			m_pCurrentFieldMapChannel->Send2NPCServerW(SendBufNPC, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP));
		}
		break;
	case T_FC_CHARACTER_CHANGE_CURRENTDP:
		{
			MSG_FC_CHARACTER_CHANGE_CURRENTDP	*pDP = NULL;
			pDP = (MSG_FC_CHARACTER_CHANGE_CURRENTDP*)(buffer + nUsedBytes);
			pDP->ClientIndex = m_character.ClientIndex;
			pDP->CurrentDP = m_character.CurrentDP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_CURRENTDP);

			CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if (pFParty)
			{
				// send CurrentDP
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP, pPartyDP, pPartyDPBuf);
				pPartyDP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyDP->CurrentDP = m_character.CurrentDP;
				pFParty->SendMsgToMembersMap(pPartyDPBuf, MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_DP), m_pCurrentFieldMapChannel);
			}

			///////////////////////////////////////////////////////////////////
			// NPC 서버에도 클라이언트의 DP 변경 정보를 전송한다.
			INIT_MSG(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, T_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP, pSendChangeHPDPSPEP, SendBufNPC);
			pSendChangeHPDPSPEP->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			pSendChangeHPDPSPEP->ClientIndex	= m_character.ClientIndex;
			pSendChangeHPDPSPEP->CurrentHP	= m_character.CurrentHP;
			pSendChangeHPDPSPEP->CurrentDP	= m_character.CurrentDP;
			pSendChangeHPDPSPEP->CurrentEP	= m_character.CurrentEP;
			pSendChangeHPDPSPEP->CurrentSP	= m_character.CurrentSP;
			m_pCurrentFieldMapChannel->Send2NPCServerW(SendBufNPC, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_CURRENTHPDPSPEP));

#ifdef _DEBUG
//			SendString128Static(STRING_128_USER_NOTICE, "Damage: 0, DP: %4.2f/%d, HP: %4.2f/%d",
//					m_character.CurrentDP, m_character.DP,
//					m_character.CurrentHP, m_character.HP);
//			DBGOUT("%s Damage: %4.2f, DP: %4.2f/%d, HP: %4.2f/%d\r\n",
//					m_character.CharacterName, i_fChangeValue,
//					m_character.CurrentDP, m_character.DP,
//					m_character.CurrentHP, m_character.HP);
#endif
		}
		break;
	case T_FC_CHARACTER_CHANGE_CURRENTEP:
		{
			MSG_FC_CHARACTER_CHANGE_CURRENTEP	*pEP = NULL;
			pEP = (MSG_FC_CHARACTER_CHANGE_CURRENTEP*)(buffer + nUsedBytes);
			pEP->ClientIndex = m_character.ClientIndex;
			pEP->CurrentEP = m_character.CurrentEP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_CURRENTEP);

			CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
			if (pFParty)
			{
				// send CurrentEP
				INIT_MSG_WITH_BUFFER(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP, T_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP, pPartyEP, pPartyEPBuf);
				pPartyEP->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
				pPartyEP->CurrentEP = m_character.CurrentEP;
				pFParty->SendMsgToMembersMap(pPartyEPBuf, MSG_SIZE(MSG_FC_PARTY_UPDATE_MEMBER_INFO_CURRENT_EP), m_pCurrentFieldMapChannel);
			}
		}
		break;
	case T_FC_CHARACTER_CHANGE_CURRENTSP:
		{
			MSG_FC_CHARACTER_CHANGE_CURRENTSP	*pSP = NULL;
			pSP = (MSG_FC_CHARACTER_CHANGE_CURRENTSP*)(buffer + nUsedBytes);
			pSP->ClientIndex = m_character.ClientIndex;
			pSP->CurrentSP = m_character.CurrentSP;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_CURRENTSP);
		}
		break;
	case T_FC_CHARACTER_CHANGE_EXP:
		{	// 캐릭터가 공격하던 몬스터가 폭발했을경우 캐릭터의 경험치가 변경된다.

			MSG_FC_CHARACTER_CHANGE_EXP		*pEXP = NULL;
			pEXP = (MSG_FC_CHARACTER_CHANGE_EXP*)(buffer + nUsedBytes);
			pEXP->ClientIndex = m_character.ClientIndex;
			pEXP->Experience = m_character.Experience;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_EXP);
		}
		break;
	case T_FC_CHARACTER_CHANGE_LEVEL:
		{
			MSG_FC_CHARACTER_CHANGE_LEVEL	*pLevel = NULL;
			pLevel = (MSG_FC_CHARACTER_CHANGE_LEVEL*)(buffer + nUsedBytes);
			pLevel->ClientIndex = m_character.ClientIndex;
			pLevel->Level = m_character.Level;
			pLevel->BonusStat = m_character.BonusStat;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_LEVEL);

			INIT_MSG_WITH_BUFFER(MSG_FI_CHARACTER_CHANGE_LEVEL, T_FI_CHARACTER_CHANGE_LEVEL, msgFIChangeLevel, msgFIChangeLevelBuf);
			msgFIChangeLevel->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
			msgFIChangeLevel->Level = m_character.Level;
			ms_pFieldIOCP->m_pIMWinSocket->Write(msgFIChangeLevelBuf, MSG_SIZE(MSG_FI_CHARACTER_CHANGE_LEVEL));

			// start 2012-10-08 by khkim, GLog
			// CharactLevelUp 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 (일반유저만 기록)	
			{
				INT nPay = 0;
				{
					mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
					
					ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
					if (pMoney == NULL )
					{
						nPay = 0;
					}
					else
					{
						nPay = pMoney->CurrentCount;
					}
				}
				MSG_FL_LOG_CHARDATA LogCharDataParameter;
				MEMSET_ZERO(&LogCharDataParameter, sizeof(LogCharDataParameter));		// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
				LogCharDataParameter.LogType			= GLOG_CD_LT_CHARACTLEVELUP;
				LogCharDataParameter.UserSerial			= (UID64_t)m_character.AccountUniqueNumber;
				LogCharDataParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
				LogCharDataParameter.Class				= (SHORT)m_character.UnitKind;
				LogCharDataParameter.Lv					= (SHORT)m_character.Level;
				LogCharDataParameter.Exp				= (UID64_t)m_character.Experience;
				LogCharDataParameter.GameMoney			= (UID64_t)nPay;
				LogCharDataParameter.Playtime			= (UID64_t)GetTotalPlayTimeInSeconds();		// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅		// 2013-01-18 by khkim, GLog (총 플레이시간 수정)
				LogCharDataParameter.GameServerID		= (int)g_pFieldGlobal->GetMGameServerID();
// 2013-01-03 by khkim, GLog (버그 확인용)
#ifdef S_KOR_TEST_GLOG_CHARDATA
				if(LogCharDataParameter.UserSerial < 0 || LogCharDataParameter.UserSerial > 7000000 )
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE,"[DEBUG] GLog #005 [%d,%I64d,%I64d,%d,%d,%I64d,%I64d,%I64d,%d]\r\n ", 
						LogCharDataParameter.LogType,	LogCharDataParameter.UserSerial,	LogCharDataParameter.CharSerial,
						LogCharDataParameter.Class,		LogCharDataParameter.Lv,			LogCharDataParameter.Exp, 
						LogCharDataParameter.GameMoney, LogCharDataParameter.Playtime,		LogCharDataParameter.GameServerID);
				}
#endif 
// end 2013-01-03 by khkim, GLog (버그 확인용)	
				CAtumLogSender::SendLogCharData(&LogCharDataParameter);
			}
			// end 2012-10-08 by khkim, GLog
/*
			// 아이템 상태정보 
			MSG_FL_LOG_ITEMSTATE LogItemStateParameter;
			LogItemStateParameter.LogType			= GLOG_ISL_CHARACTLEVELUP;
			LogItemStateParameter.ItemSerial		= 0;
			LogItemStateParameter.Count				= 0;
			LogItemStateParameter.CharSerial		= m_character.CharacterUniqueNumber;
			LogItemStateParameter.CharLv			= m_character.Level;
			LogItemStateParameter.GameServerID		= g_pFieldGlobal->GetMGameServerID();
			CAtumLogSender::SendLogItemState(&LogItemStateParameter);
			// end 2012-10-08 by khkim, GLog
*/
		}
		break;
	case T_FC_CHARACTER_CHANGE_PKPOINT:
		{
			MSG_FC_CHARACTER_CHANGE_PKPOINT *pPKPoint = NULL;
			pPKPoint = (MSG_FC_CHARACTER_CHANGE_PKPOINT*)(buffer + nUsedBytes);
			pPKPoint->ClientIndex = m_character.ClientIndex;
			pPKPoint->Propensity = m_character.Propensity;
			pPKPoint->PKWinPoint = m_character.PKWinPoint;
			pPKPoint->PKLossPoint = m_character.PKLossPoint;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_PKPOINT);
//#ifdef _DEBUG
//			SendString128(STRING_128_ADMIN_CMD, "%s %d(%d/%d)", m_character.CharacterName,
//				m_character.Propensity, m_character.PKWinPoint, m_character.PKLossPoint);
//#endif
		}
		break;
	case T_FC_CHARACTER_CHANGE_BODYCONDITION:
		{
			MSG_FC_CHARACTER_CHANGE_BODYCONDITION *pBodyCon = NULL;
			pBodyCon = (MSG_FC_CHARACTER_CHANGE_BODYCONDITION*)(buffer + nUsedBytes);
			pBodyCon->ClientIndex = m_character.ClientIndex;
			pBodyCon->BodyCondition = m_character.BodyCondition;
			nUsedBytes += sizeof(MSG_FC_CHARACTER_CHANGE_BODYCONDITION);
		}
		break;
	default:
		{
			DBGOUT2(DO2_ALL, "ERROR: SendCharacterInfo(%s) NOT IMPLEMENTED!!\r\n", GetProtocolTypeString(msgType));
			ASSERT_NOT_IMPLEMENTED_YET();
			return;
		}
	}
	SendAddData(buffer, nUsedBytes);
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-03 by cmkwon, 특정 메시지 일때만 옵저버 유저에게 정보를 전송한다.
	switch(msgType)
	{
	case T_FC_CHARACTER_CHANGE_HPDPSPEP:
	case T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP:
	case T_FC_CHARACTER_CHANGE_CURRENTHP:
	case T_FC_CHARACTER_CHANGE_CURRENTDP:
	case T_FC_CHARACTER_CHANGE_CURRENTEP:
	case T_FC_CHARACTER_CHANGE_CURRENTSP:
		{
			mt_auto_lock mta(&m_mtvectObersverCharacter);
			mtvectObersverCharacter::iterator itr = m_mtvectObersverCharacter.begin();
			while(itr != m_mtvectObersverCharacter.end())
			{
				CFieldIOCPSocket *pTargetSocket = *itr;//this->ms_pFieldIOCP->GetFieldIOCPSocket(*(itr));
				
				if(NULL == pTargetSocket
					|| FALSE == this->ObserverTargetCharacterCheck(pTargetSocket))
				{
					m_mtvectObersverCharacter.erase(itr);
					continue;
				}

				// 지금 현재 상태의 옵저버 대상의 정보를 전송한다.
				INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_OBSERVER_INFO, T_FC_CHARACTER_OBSERVER_INFO, pMsg, SendBuf);
				pMsg->ClientIndex	= 	m_character.ClientIndex;
				pMsg->HP			= 	m_character.HP;
				pMsg->DP			= 	m_character.DP;
				pMsg->SP			= 	m_character.SP;
				pMsg->EP			= 	m_character.EP;
				pMsg->CurrentHP		= 	m_character.CurrentHP;
				pMsg->CurrentDP		= 	m_character.CurrentDP;
				pMsg->CurrentSP		= 	m_character.CurrentSP;
				pMsg->CurrentEP		= 	m_character.CurrentEP;
				pTargetSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_OBSERVER_INFO));

				itr++;
			}
		}
		break;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-06-19 by dhjin, 관전자에게 정보를 보낸다.
	switch(msgType)
	{
	case T_FC_CHARACTER_CHANGE_HPDPSPEP:
	case T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP:
	case T_FC_CHARACTER_CHANGE_CURRENTHP:
	case T_FC_CHARACTER_CHANGE_CURRENTDP:
		{
			mt_auto_lock mta(&m_mtvectWatchCharacter);
			mtvectObersverCharacter::iterator itr = m_mtvectWatchCharacter.begin();
			while(itr != m_mtvectWatchCharacter.end())
			{
				CFieldIOCPSocket *pTargetSocket = *itr;
				
				if(NULL == pTargetSocket
					|| FALSE == this->WatchTargetCharacterCheck(pTargetSocket))
				{
					m_mtvectWatchCharacter.erase(itr);
					continue;
				}

				// 지금 현재 상태의 옵저버 대상의 정보를 전송한다.
				INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_WATCH_INFO, T_FC_CHARACTER_WATCH_INFO, pMsg, SendBuf);
				pMsg->ClientIndex	= 	m_character.ClientIndex;
				pMsg->HP			= 	m_character.HP;
				pMsg->DP			= 	m_character.DP;
				pMsg->CurrentHP		= 	m_character.CurrentHP;
				pMsg->CurrentDP		= 	m_character.CurrentDP;
				pTargetSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_WATCH_INFO));

				itr++;
			}
		}
		break;
	}
}

// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::SendInRangeMessageAroundMe#, 인자추가(i_nStartCityMapIdx)
void CFieldIOCPSocket::SendInRangeMessageAroundMe(BYTE *pData, int Size, BOOL bIncludeMe, BYTE i_byInfluenceMask/*=INFLUENCE_TYPE_ALL_MASK*/, MapIndex_t i_nStartCityMapIdx/*=VCN_CITY_MAP_INDEX*/)
{
	if (m_pCurrentFieldMapChannel == NULL || !IS_VALID_CLIENT_INDEX(m_character.ClientIndex))
	{
		return;
	}
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pData, Size
		, m_pCurrentFieldMapChannel, bIncludeMe, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW(), i_byInfluenceMask, i_nStartCityMapIdx);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SendInRangeMessageExactAroundMe(BYTE *pData, int Size, int i_radius, BOOL bIncludeMe, BYTE i_byInfluenceMask=INFLUENCE_TYPE_ALL_MASK)
/// \brief		
/// \author		dhjin
/// \date		2006-11-27 ~ 2006-11-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SendInRangeMessageExactAroundMe(BYTE *pData, int Size, int i_radius, BOOL bIncludeMe, BYTE i_byInfluenceMask/*=INFLUENCE_TYPE_ALL_MASK*/)
{
	CFieldMapChannel *pFieldMapChannel = m_pCurrentFieldMapChannel;
	if (NULL == pFieldMapChannel
		|| FALSE == IsValidCharacter(FALSE))
	{
		return;
	}

	if(FALSE == IS_TUTORIAL_MAP_INDEX(pFieldMapChannel->GetMapChannelIndex().MapIndex))
	{
		// 2009-11-23 by cmkwon, 자신포함 데이터 전송 보내기 버그 수정 - 아래와 같이 자신에게 전송을 따로 처리
		//ms_pFieldIOCP->SendInRangeMessageExactAroundPosition(GetCharacter()->PositionVector, pData, Size, i_radius, pFieldMapChannel, (bIncludeMe)?0:m_character.ClientIndex, i_byInfluenceMask);
		ms_pFieldIOCP->SendInRangeMessageExactAroundPosition(GetCharacter()->PositionVector, pData, Size, i_radius, pFieldMapChannel, m_character.ClientIndex, i_byInfluenceMask);
		if(bIncludeMe)
		{// 2009-11-23 by cmkwon, 자신포함 데이터 전송 보내기 버그 수정 - 자신것은 따로 전송 처리한다.
			this->SendAddData(pData, Size);
		}
	}
	else
	{
		if(FALSE == bIncludeMe){					return;}
		this->SendAddData(pData, Size);
	}	
}

void CFieldIOCPSocket::SendParamFactorToOthers(BYTE i_nItemPosition, ClientIndex_t i_ToClientIndex, BOOL i_bSendInRange)	
{
	int nCount = 0;

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_OTHER_PARAMFACTOR_OK, T_FC_CHARACTER_GET_OTHER_PARAMFACTOR_OK, pMsgParamFactorOK, pMsgParamFactorOKBuf);
	pMsgParamFactorOK->ClientIndex = m_character.ClientIndex;
	pMsgParamFactorOK->ItemPosition = i_nItemPosition;

	DES_PARAM_VALUE *arrDesParamValue
		= (DES_PARAM_VALUE*)(pMsgParamFactorOKBuf+MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_PARAMFACTOR_OK));

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// 2006-01-11 by cmkwon, lock m_mapItemGeneral, @SendParamFactorToOthers

	ITEM *pItem = GetAttachedItem(i_nItemPosition);
	if (pItem == NULL || pItem->ItemNum == 0)
	{
		return;
	}
	pMsgParamFactorOK->ItemNum = ((ITEM_GENERAL*)pItem->ItemNum)->ItemNum;

	if (m_ParamFactor.pfp_SHOTNUM_01 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_SHOTNUM_01;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfp_SHOTNUM_01;
		nCount++;
	}

	if (m_ParamFactor.pfp_SHOTNUM_02 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_SHOTNUM_02;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfp_SHOTNUM_02;
		nCount++;
	}

	if (m_ParamFactor.pfp_MULTINUM_01 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_MULTINUM_01;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfp_MULTINUM_01;
		nCount++;
	}

	if (m_ParamFactor.pfp_MULTINUM_02 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_MULTINUM_02;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfp_MULTINUM_02;
		nCount++;
	}

	if (m_ParamFactor.pfm_REATTACKTIME_01 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_REATTACKTIME_01;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfm_REATTACKTIME_01;
		nCount++;
	}

	if (m_ParamFactor.pfm_REATTACKTIME_02 != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_REATTACKTIME_02;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfm_REATTACKTIME_02;
		nCount++;
	}

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-11 by cmkwon, 탄두의 속도 - 다른 유저들에게 전송해야 함
	if (m_ParamFactor.pfm_WARHEAD_SPEED != 0.0f)
	{
		arrDesParamValue[nCount].DestParameter = DES_WARHEAD_SPEED;
		arrDesParamValue[nCount].ParameterValue = m_ParamFactor.pfm_WARHEAD_SPEED;
		nCount++;
	}

	pMsgParamFactorOK->NumOfParamValues = nCount;

	if (IS_VALID_CLIENT_INDEX(i_ToClientIndex))
	{
		CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(i_ToClientIndex);
		// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
		//if (pTargetSocket != NULL && pTargetSocket->IsUsing())
		if (pTargetSocket
			&& pTargetSocket->IsValidCharacter(FALSE))
		{
			pTargetSocket->SendAddData(pMsgParamFactorOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_PARAMFACTOR_OK)+nCount*sizeof(DES_PARAM_VALUE));
		}
	}

	if (i_bSendInRange)
	{
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector,
			pMsgParamFactorOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_PARAMFACTOR_OK)+nCount*sizeof(DES_PARAM_VALUE),
			m_pCurrentFieldMapChannel, i_ToClientIndex);
	}
}


struct Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx
{
	Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(MessageType_t i_msgTy, ClientIndex_t i_cliIdx): m_nMsgType(i_msgTy), m_nCliIdx(i_cliIdx){};
	bool operator()(SSendedOverlappedInfo i_sendedOver)
	{
		if(m_nMsgType != *(MessageType_t*)i_sendedOver.pbyData)
		{// 2008-03-17 by cmkwon, MessageType 이 다르면 flase 를 리턴
			return false;
		}

		switch(m_nMsgType)
		{
		case T_FC_MOVE_OK:
			{
				MSG_FC_MOVE_OK *pMoveOK = (MSG_FC_MOVE_OK*)(i_sendedOver.pbyData + SIZE_FIELD_TYPE_HEADER);
				return pMoveOK->ClientIndex == m_nCliIdx;
			}
		case T_FC_MONSTER_MOVE_OK:
			{
				MSG_FC_MONSTER_MOVE_OK *pMonMoveOK = (MSG_FC_MONSTER_MOVE_OK*)(i_sendedOver.pbyData + SIZE_FIELD_TYPE_HEADER);
				return pMonMoveOK->MonsterIndex == m_nCliIdx;
			}
		case T_FC_CHARACTER_GET_OTHER_INFO_OK:		// 2008-03-18 by cmkwon, 패킷 최적화에 추가한 것
			{
				MSG_FC_CHARACTER_GET_OTHER_INFO_OK *pCharInfoOK = (MSG_FC_CHARACTER_GET_OTHER_INFO_OK*)(i_sendedOver.pbyData + SIZE_FIELD_TYPE_HEADER);
				return pCharInfoOK->CharacterInfo.ClientIndex == m_nCliIdx;
			}
		case T_FC_MOVE_WEAPON_VEL_OK:					// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_MOVE_WEAPON_VEL_OK
			{
				MSG_FC_MOVE_WEAPON_VEL_OK *pMoveVelOK = (MSG_FC_MOVE_WEAPON_VEL_OK*)(i_sendedOver.pbyData + SIZE_FIELD_TYPE_HEADER);
				return pMoveVelOK->ClientIndex == m_nCliIdx;
			}
		case T_FC_CHARACTER_CHANGE_BODYCONDITION:		// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_CHARACTER_CHANGE_BODYCONDITION
			{
				MSG_FC_CHARACTER_CHANGE_BODYCONDITION *pChangeBodyCon = (MSG_FC_CHARACTER_CHANGE_BODYCONDITION*)(i_sendedOver.pbyData + SIZE_FIELD_TYPE_HEADER);
				return pChangeBodyCon->ClientIndex == m_nCliIdx;
			}
		}
		return false;
	}
	MessageType_t	m_nMsgType;
	ClientIndex_t	m_nCliIdx;
};

#define IOCPSOCKET_WRITE_BUFF_CHECK_COUNT		3		// 2008-03-19 by cmkwon, 대규모 전쟁시 클라이언트 랙(lack) 현상 수정 - 추가함

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::PreSendAddData(BYTE *i_pbyData, int i_nSize, int i_nWriteBufCnts, vectSSendedOverlappedInfo *i_pSendedOverInfoList)
/// \brief		// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
/// \author		cmkwon
/// \date		2008-03-12 ~ 2008-03-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::PreSendAddData(BYTE *i_pbyData, int i_nSize, int i_nWriteBufCnts, vectSSendedOverlappedInfo *i_pSendedOverInfoList)
{
	if(ST_CLIENT_TYPE != this->m_PeerSocketType)
	{
		return TRUE;
	}

 	if(IOCPSOCKET_WRITE_BUFF_CHECK_COUNT > i_nWriteBufCnts)
 	{
 		return TRUE;
 	}

	MessageType_t msgTy = *(MessageType_t*)i_pbyData;
	switch(msgTy)
	{
	case T_FC_MOVE_OK:
		{
			if(MSG_SIZE(MSG_FC_MOVE_OK) == i_nSize)
			{
				MSG_FC_MOVE_OK *pMoveOK = (MSG_FC_MOVE_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				vectSSendedOverlappedInfo::iterator itr = find_if(i_pSendedOverInfoList->begin(), i_pSendedOverInfoList->end(), Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(msgTy, pMoveOK->ClientIndex));
				if(itr != i_pSendedOverInfoList->end())
				{
					MSG_FC_MOVE_OK	*pAddedMoveOK = (MSG_FC_MOVE_OK*)(itr->pbyData + SIZE_FIELD_TYPE_HEADER);
					*pAddedMoveOK	= *pMoveOK;
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_BATTLE_ATTACK_OK:
		{
			if(MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK) == i_nSize)
			{
				MSG_FC_BATTLE_ATTACK_OK *pAttOK = (MSG_FC_BATTLE_ATTACK_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				if(0 == pAttOK->SkillNum
					&& GetCharacter()->ClientIndex != pAttOK->AttackIndex 
					&& GetCharacter()->ClientIndex != pAttOK->TargetInfo.TargetIndex)
				{

//  						g_pFieldGlobal->WriteSystemLogEX(TRUE, "임시용 CFieldIOCPSocket::PreSendAddData CliIdx|%4d| MsgTy|%s| AttIdx|%d| TarIdx|%d| WriteBufCnt|%d| %d, %d, %d\r\n"
//  							, this->GetClientArrayIndex(), GetProtocolTypeString(msgTy), pAttOK->AttackIndex, pAttOK->TargetInfo.TargetIndex, i_nWriteBufCnts
// 							, pAttOK->SkillNum, pAttOK->AttackIndex, pAttOK->TargetInfo.TargetIndex);
					// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
					//						 네트워크 상태가 좋지 않으면 공폭/지폭 스킬 사용안한 상태거나, 내가 공격한 정보, 나를 공격한 정보를 제외한 나머지 공격 정보를 전송하지 않는다.
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_BATTLE_ATTACK_FIND_OK:
		{
			if(MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK) == i_nSize)
			{
				MSG_FC_BATTLE_ATTACK_FIND_OK *pAttOK = (MSG_FC_BATTLE_ATTACK_FIND_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				if(GetCharacter()->ClientIndex != pAttOK->AttackIndex 
					&& GetCharacter()->ClientIndex != pAttOK->TargetIndex)
				{
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_MONSTER_MOVE_OK:
		{
			if(MSG_SIZE(MSG_FC_MONSTER_MOVE_OK) == i_nSize)
			{
				MSG_FC_MONSTER_MOVE_OK	*pCurMsg			= (MSG_FC_MONSTER_MOVE_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				vectSSendedOverlappedInfo::iterator itr = find_if(i_pSendedOverInfoList->begin(), i_pSendedOverInfoList->end(), Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(msgTy, pCurMsg->MonsterIndex));
				if(itr != i_pSendedOverInfoList->end())
				{
					MSG_FC_MONSTER_MOVE_OK	*pAddedMsg	= (MSG_FC_MONSTER_MOVE_OK*)(itr->pbyData + SIZE_FIELD_TYPE_HEADER);
					*pAddedMsg	= *pCurMsg;
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_CHARACTER_GET_OTHER_INFO_OK:		// 2008-03-18 by cmkwon, 패킷 최적화에 추가한 것
		{
			if(MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK) == i_nSize)
			{
				MSG_FC_CHARACTER_GET_OTHER_INFO_OK *pCurMsg = (MSG_FC_CHARACTER_GET_OTHER_INFO_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				vectSSendedOverlappedInfo::iterator itr = find_if(i_pSendedOverInfoList->begin(), i_pSendedOverInfoList->end(), Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(msgTy, pCurMsg->CharacterInfo.ClientIndex));
				if(itr != i_pSendedOverInfoList->end())
				{
					MSG_FC_CHARACTER_GET_OTHER_INFO_OK	*pAddedMsg	= (MSG_FC_CHARACTER_GET_OTHER_INFO_OK*)(itr->pbyData + SIZE_FIELD_TYPE_HEADER);
					*pAddedMsg	= *pCurMsg;
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_MOVE_WEAPON_VEL_OK:					// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_MOVE_WEAPON_VEL_OK
		{
			if(MSG_SIZE(MSG_FC_MOVE_WEAPON_VEL_OK) == i_nSize)
			{
				MSG_FC_MOVE_WEAPON_VEL_OK *pCurMsg = (MSG_FC_MOVE_WEAPON_VEL_OK*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				vectSSendedOverlappedInfo::iterator itr = find_if(i_pSendedOverInfoList->begin(), i_pSendedOverInfoList->end(), Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(msgTy, pCurMsg->ClientIndex));
				if(itr != i_pSendedOverInfoList->end())
				{
					MSG_FC_MOVE_WEAPON_VEL_OK	*pAddedMsg	= (MSG_FC_MOVE_WEAPON_VEL_OK*)(itr->pbyData + SIZE_FIELD_TYPE_HEADER);
					*pAddedMsg	= *pCurMsg;
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	case T_FC_CHARACTER_CHANGE_BODYCONDITION:		// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_CHARACTER_CHANGE_BODYCONDITION
		{
			if(MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION) == i_nSize)
			{
				MSG_FC_CHARACTER_CHANGE_BODYCONDITION *pCurMsg = (MSG_FC_CHARACTER_CHANGE_BODYCONDITION*)(i_pbyData + SIZE_FIELD_TYPE_HEADER);
				vectSSendedOverlappedInfo::iterator itr = find_if(i_pSendedOverInfoList->begin(), i_pSendedOverInfoList->end(), Sfind_if_SSendedOverlappedInfo_BY_MsgTypeAndCliIdx(msgTy, pCurMsg->ClientIndex));
				if(itr != i_pSendedOverInfoList->end())
				{
					MSG_FC_CHARACTER_CHANGE_BODYCONDITION *pAddedMsg	= (MSG_FC_CHARACTER_CHANGE_BODYCONDITION*)(itr->pbyData + SIZE_FIELD_TYPE_HEADER);
					*pAddedMsg	= *pCurMsg;
					m_nDeletedPacketCount++;
					return FALSE;
				}
			}
		}
		break;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnSendAddData(SSendedOverlappedInfo *i_pSendedOverInfo, int i_nSize, int i_nWriteBufCnts)
/// \brief		// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
/// \author		cmkwon
/// \date		2008-03-14 ~ 2008-03-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnSendAddData(SSendedOverlappedInfo *i_pSendedOverInfo, int i_nSize, int i_nWriteBufCnts)
{
	if(ST_CLIENT_TYPE != this->m_PeerSocketType)
	{
		return;
	}

	// 2008-03-19 by cmkwon, 수치를 조정 함 
	if(IOCPSOCKET_WRITE_BUFF_CHECK_COUNT > i_nWriteBufCnts)
	{
		return;
	}

	MessageType_t msgTy = *(MessageType_t*)i_pSendedOverInfo->pbyData;
	if( (T_FC_MOVE_OK == msgTy && MSG_SIZE(MSG_FC_MOVE_OK) == i_nSize)
		|| (T_FC_MONSTER_MOVE_OK == msgTy && MSG_SIZE(MSG_FC_MONSTER_MOVE_OK) == i_nSize)
		|| (T_FC_CHARACTER_GET_OTHER_INFO_OK == msgTy && MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK) == i_nSize) 		// 2008-03-18 by cmkwon, 패킷 최적화에 추가한 것
		|| (T_FC_MOVE_WEAPON_VEL_OK == msgTy && MSG_SIZE(MSG_FC_MOVE_WEAPON_VEL_OK) == i_nSize) 							// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_MOVE_WEAPON_VEL_OK
		|| (T_FC_CHARACTER_CHANGE_BODYCONDITION == msgTy && MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION) == i_nSize) )	// 2009-03-16 by cmkwon, 패킷 최적화에 프로토콜 2개 추가 - T_FC_CHARACTER_CHANGE_BODYCONDITION
	{
		this->AddSendedOverlappedInfo(i_pSendedOverInfo);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::SaveDataOfWriteBufList(void)
/// \brief		// 2008-03-19 by cmkwon, 대규모 전쟁시 클라이언트 랙(lack) 현상 수정 - 
/// \author		cmkwon
/// \date		2008-03-19 ~ 2008-03-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::SaveDataOfWriteBufList(void)
{
	mt_auto_lock mtA(&m_mtlistWriteBuf);
	if(m_mtlistWriteBuf.empty())
	{
		return;
	}
	
	time_t		ltime;
	struct tm	*today = NULL;
	char		szCurrTime[128];
	_tzset();
	time(&ltime);
	strftime(szCurrTime, 128, "%Y%m%d_%H%M%S.dat", localtime(&ltime));	

	char szLogFileFullPath[MAX_PATH];		MEMSET_ZERO(szLogFileFullPath, MAX_PATH);
	sprintf(szLogFileFullPath, "%s%s(%s_%d)_%s", (string(CONFIG_ROOT) + "../log/SystemLog/").c_str(), "WriteBufData", m_character.AccountName, m_mtlistWriteBuf.size(), szCurrTime);
	HANDLE	hFile = CreateFile(szLogFileFullPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
	if(INVALID_HANDLE_VALUE == hFile)
	{
		return;
	}

	mtlistCOverlappedPtr::iterator itr(m_mtlistWriteBuf.begin());
	for(; itr != m_mtlistWriteBuf.end(); itr++)
	{
		COverlapped *pOver = *itr;

		DWORD nWritten = 0;
		if(FALSE == WriteFile(hFile, pOver->GetWSABUFPtr()->buf, pOver->GetDataSize(), &nWritten, NULL))
		{
			break;
		}
	}
	CloseHandle(hFile);
	hFile = NULL;
}

BOOL CFieldIOCPSocket::OnRecvdPacketFieldServer(const char* pPacket, int nLength, BYTE nSeq, char* pPeerIP, int nPeerPort, SThreadInfo *i_pThreadInfo)
{
	int						nBytesUsed		= 0;
	MessageType_t			nRecvType		= 0;
	MessageType_t			prevMsgType = 0;
	int						nRecvTypeSize	= 0;
	BYTE					SendBuf[SIZE_MAX_PACKET];
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;
	ProcessResult			procRes				= RES_BREAK;
	int						tmpSeq;
	int						nPacketCnt			= 1;		// 2008-12-02 by cmkwon, 체크 추가

	// UDP 처리 루틴 - NPC 와의 통신
	if(m_bUDPFlag == TRUE)
	{
// 2006-05-19 by cmkwon
// 		if(strncmp(m_szPeerIP, pPeerIP, SIZE_MAX_IPADDRESS) != 0 || m_nPeerPort != nPeerPort)
// 		{
// 			// Protocl Error 처리
// 			// - UDP로 받은 패킷의 IP와 Port가 서버에 설정된 Client의 IP, Port와 같지 않다
// 			// Error Code : ERR_PROTOCOL_INVALID_PEER
// 			//SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVALID_PEER);
// 
// 			char szSystemLog[256];
// 			sprintf(szSystemLog, "  ERR_PROTOCOL_INVALID_PEER SocketIndex[%3d] RecvIP[%15s] Port[%4d]\r\n",
// 				this->GetClientArrayIndex(), pPeerIP, nPeerPort);
// 			g_pFieldGlobal->WriteSystemLog(szSystemLog);
// 			DBGOUT(szSystemLog);
// 
// 			return FALSE;
// 		}

		while(this->IsUsing() && nBytesUsed < nLength)
		{
			nRecvType			= 0;

			nRecvType = *(MessageType_t*)(pPacket+nBytesUsed);
			nBytesUsed += SIZE_FIELD_TYPE_HEADER;
			//DbgOut("    [NPCServer]index[%#d] RecvType[%#04X]\n", this->GetClientArrayIndex(), nRecvType);

			if(i_pThreadInfo)
			{
				i_pThreadInfo->dwSocketIndex = m_nClientArrayIndex;
				i_pThreadInfo->dwMessageType = nRecvType;
			}

			// 2013-04-01 by hskim, NPCServer 패킷으로 위조 공격 방어
			// 현재는 NPC 서버만 UDP 패킷을 사용하고 있다
			// 이후 다른 서버 패킷도 같이 처리할 경우에는
			// 해당 부분을 서버에 맞게 검사하도록 잘 수정하세요.
			if( FALSE == g_pFieldGlobal->CheckAllowedNPCServerIP(this->GetPeerIP()) )
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect %s Command Using: HackingIP(%15s)\r\n", GetProtocolTypeString(nRecvType), this->GetPeerIP());

				return FALSE;
			}
			// end 2013-04-01 by hskim, NPCServer 패킷으로 위조 공격 방어

			switch(nRecvType)
			{
			////////////////////////////////////////////////////////////////////////
			// FieldServer <-- NPC Server,
			case T_FN_MAPPROJECT_START:
				procRes = Process_FN_MAPPROJECT_START(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MAPPROJECT_START_OK_ACK:
				{
					m_pFieldMapProjectForNPC->SetNPCServerStartFlag(TRUE);
				}
				break;
			case T_FN_MONSTER_CREATE:
				procRes = Process_FN_MONSTER_CREATE(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_MOVE:
				procRes = Process_FN_MONSTER_MOVE(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_GET_CHARACTER_INFO:
				procRes = Process_FN_GET_CHARACTER_INFO(pPacket, nLength, nBytesUsed);
				break;
//			case T_FN_MOVE_LOCKON:
//				procRes = Process_FC_MOVE_LOCKON(pPacket, nLength, nBytesUsed);
//				break;
//			case T_FN_MOVE_LOCKON_AVOID:
//				procRes = Process_FC_MOVE_LOCKON_AVOID(pPacket, nLength, nBytesUsed);
//				break;
			case T_FN_BATTLE_ATTACK_PRIMARY:
				procRes = Process_FN_BATTLE_ATTACK_PRIMARY(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_ATTACK_SECONDARY:
				procRes = Process_FN_BATTLE_ATTACK_SECONDARY(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_ATTACK_FIND:
				procRes = Process_FN_BATTLE_ATTACK_FIND(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_DROP_FIXER_OK:
				procRes = Process_FN_BATTLE_DROP_FIXER_OK(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND:
				procRes = Process_FN_BATTLE_ATTACK_HIDE_ITEM_W_KIND(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_ATTACK_SKILL:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - N -> F
				procRes = Process_FN_BATTLE_ATTACK_SKILL(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_DELETE:
				procRes = Process_FN_MONSTER_DELETE(pPacket, nLength, nBytesUsed);
				break;
			// start 2011-05-11 by hskim, 인피니티 3차 - 시네마 관련 기능 추가 - 해당 맵채널 특정 몬스터 변경 기능 추가
			case T_FN_MONSTER_CHANGE_OK:
				procRes = Process_FN_MONSTER_CHANGE_OK(pPacket, nLength, nBytesUsed);
				break;
			// end 2011-05-11 by hskim, 인피니티 3차 - 시네마 관련 기능 추가 - 해당 맵채널 특정 몬스터 변경 기능 추가
			case T_FN_MISSILE_MOVE:
				procRes = Process_FN_MISSILE_MOVE(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_HPRECOVERY:
				procRes = Process_FN_MONSTER_HPRECOVERY(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_HIDE:
				procRes = Process_FN_MONSTER_HIDE(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_SHOW:
				procRes = Process_FN_MONSTER_SHOW(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_CHANGE_BODYCONDITION:
				procRes = Process_FN_MONSTER_CHANGE_BODYCONDITION(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_SKILL_USE_SKILL:
				procRes = Process_FN_MONSTER_SKILL_USE_SKILL(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_SKILL_END_SKILL:
				procRes = Process_FN_MONSTER_SKILL_END_SKILL(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_MONSTER_AUTO_DESTROYED:
				procRes = Process_FN_MONSTER_AUTO_DESTROYED(pPacket, nLength, nBytesUsed);
				break;
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			case T_FN_MONSTER_HPTALK:
				procRes = Process_FN_MONSTER_HPTALK(pPacket, nLength, nBytesUsed);
				break;
			case T_FN_BATTLE_ATTACK_SKILL_CANCEL:		// 2010-03-31 by dhjin, 인피니티(기지방어) -
				procRes = Process_FN_BATTLE_ATTACK_SKILL_CANCEL(pPacket, nLength, nBytesUsed);
				break;	

			case T_ERROR:
				{
					MSG_ERROR *pRecvMsg;
					pRecvMsg = (MSG_ERROR*)(pPacket + nBytesUsed);
					nBytesUsed += sizeof(MSG_ERROR) + pRecvMsg->StringLength;
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "  T_ERROR %s(%#04X) received from %s[%s]\r\n",
						GetErrorString(pRecvMsg->ErrorCode), pRecvMsg->ErrorCode,
						GGetENServerTypeString(m_PeerSocketType), m_szPeerIP);
					procRes = RES_RETURN_TRUE;
				}
				break;
			default:
				{
					// Protocol Error 처리(Close 처리함)
					// - Client로 부터 받은 Field Type이 유효하지 않다
					// Error Code : ERR_PROTOCOL_INVALID_PROTOCOL_TYPE
					SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVALID_PROTOCOL_TYPE, 0, 0, NULL, TRUE);

					//char	szSystemLog[256];
					// 2008-06-25 by cmkwon, 아래와 같이 수정 함
					//sprintf(szSystemLog, "[Error] CFieldIOCPSocket::OnRecvdPacketFieldServer1 invalid protocol type, RecvType[%s(%#04X)]\r\n", GetProtocolTypeString(nRecvType), nRecvType);
					// 2008-12-02 by cmkwon, 체크 추가
					//sprintf(szSystemLog, "[Error] CFieldIOCPSocket::OnRecvdPacketFieldServer1 invalid protocol type, RecvType[%s(%#04X)], PrevType[%s(%#04X)], %s\r\n",
					// 2009-11-25 by cmkwon, FieldServer 죽는 버그 수정 - 아래와 같이 저장되는 정보 수정
					//sprintf(szSystemLog, "[Error] CFieldIOCPSocket::OnRecvdPacketFieldServer1 invalid protocol type, PacketCount(%2d), PacketBytes(%4d) RecvType[%s(%#04X)], PrevType[%s(%#04X)], %s\r\n",
					//	GetProtocolTypeString(nRecvType), nRecvType,
					//	GetProtocolTypeString(m_LastRecvedMsgType), m_LastRecvedMsgType,
					//	GetCharacterString(&m_character, string())
					//	);
					//g_pFieldGlobal->WriteSystemLog(szSystemLog);
					//DBGOUT(szSystemLog);
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CFieldIOCPSocket::OnRecvdPacketFieldServer1 invalid protocol type, %s PrevType[%s(%#04X)], RecvType[%s(%#04X)] ProcessedPacketCnt(%d) PacketSize(%d) UsedBytes(%d) \r\n"
						, GetCharacterString(&m_character, string()), GetProtocolTypeString(m_LastRecvedMsgType), m_LastRecvedMsgType, GetProtocolTypeString(nRecvType), nRecvType, nPacketCnt, nLength, nBytesUsed);
					return FALSE;
				}
			}	// end switch

			m_LastRecvedMsgType = nRecvType;	// 2008-03-06 by cmkwon, IOCPSocket 에 마지막 메시지 타입 체크 시스템 추가 - 
			nPacketCnt++;						// 2008-12-02 by cmkwon, 체크 추가

			// MSG 결과 처리
			if (procRes == RES_BREAK)
			{
				// 경미한 에러들. 연결을 끊지 않는다.
				// do nothing, 그냥 남아있는 다음 packet을 처리한다
			}
			else if (procRes == RES_PACKET_ERROR)
			{
				// 패킷이 손상된 경우. 남은 packet을 처리하지 않고 바로 리턴한다. 서버간 연결에만 사용.
				return TRUE;
			}
			else if (procRes == RES_RETURN_TRUE)
			{
				// 정상
				// do nothing, 그냥 남아있는 다음 packet을 처리한다
			}
			else if (procRes == RES_RETURN_FALSE)
			{
				return FALSE;
			}

		}	// end while

		return TRUE;
	} // end UDP 처리 루틴

	// TCP 처리 루틴
	if(m_bPeerSequenceNumberInitFlag == FALSE)
	{
		tmpSeq = (nSeq + SEQNO_VAR_A) * SEQNO_VAR_B;
		if(tmpSeq > SEQNO_VAR_C)
		{
			tmpSeq = tmpSeq % SEQNO_VAR_C;
		}
		m_byPeerSequenceNumber = ++tmpSeq;
		m_bPeerSequenceNumberInitFlag = TRUE;
	}
	else
	{
		//DBGOUT("%s[%d]: Sequence Number ==> server %d, client %d\n", m_character.CharacterName , m_character.ClientIndex, nSeq, m_byPeerSequenceNumber);
		if(m_byPeerSequenceNumber != nSeq)
		{
			// Protocl Error 처리
			// - 받은 패킷의 Sequence Number가 유효하지 않음
			// Error Code : ERR_PROTOCOL_INVALID_SEQUENCE_NUMBER
			SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVALID_SEQUENCE_NUMBER);
			Close(0x14002);
			return FALSE;
		}
		tmpSeq = (nSeq + SEQNO_VAR_A) * SEQNO_VAR_B;
		if(tmpSeq > SEQNO_VAR_C)
		{
			tmpSeq = tmpSeq % SEQNO_VAR_C;
		}
		m_byPeerSequenceNumber = ++tmpSeq;
	} // end TCP 처리 루틴


	while(this->IsUsing() && nBytesUsed < nLength)
	{
		nRecvType			= 0;
		pFieldIOCPSocket	= NULL;
		pCharacter			= NULL;
		prevMsgType = 0;

		nRecvType = *(MessageType_t*)(pPacket+nBytesUsed);
		nBytesUsed += SIZE_FIELD_TYPE_HEADER;

		if(i_pThreadInfo)
		{
			i_pThreadInfo->dwSocketIndex = m_nClientArrayIndex;
			i_pThreadInfo->dwMessageType = nRecvType;
		}

#ifdef _DEBUG
		PrintExchangeMsg(RECV_TYPE, nRecvType, m_szPeerIP, m_PeerSocketType, GGetexchangeMsgPrintLevel());
#endif

#ifdef _DEBUG
		// 메세지 찍기
		if (m_PeerSocketType == ST_CLIENT_TYPE
			&& m_bSendMessgeTypeDBG
			&& !IsTrivialMessageType(nRecvType)
		)
		{
			SendString128(STRING_128_USER_NOTICE, "[C->F]%s", GetProtocolTypeString(nRecvType));
		}
#endif

#ifdef S_EP4_DEBUG_HSKIM
// start 2011-10-10 by hskim, EP4 [버그 디버깅]
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Debug Info] Type(%s) IP(%15s)\r\n", GetProtocolTypeString(nRecvType), this->GetPeerIP());
// end 2011-10-10 by hskim, EP4 [버그 디버깅]
#endif		


		// 2015-07-07 by bckim, 게임포지 해킹보완 소켓타입확인
#ifdef SC_ANTI_HACKING_CODE_BCKIM_JWLEE	
		if ( FALSE == CheckAntiHackingFieldSever(nRecvType) )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ANTI_HACKING_CODE_FIELD_Abnormal] Type(%s) IP(%15s) socket_type(%d) \r\n", GetProtocolTypeString(nRecvType), this->GetPeerIP(), m_PeerSocketType );
			Close(0x12000);
			return FALSE ;
		}

#endif	// End. 2015-07-07 by bckim, 게임포지 해킹보완 소켓타입확인


		switch(nRecvType)
		{
		////////////////////////////////////////////////////////////////////////
		// FieldServer <-- Client, FieldServer <-- Monitor, FieldServer <-- NPCServer
		case T_FC_CONNECT_ALIVE:
		case T_FN_CONNECT_ALIVE:
		case T_PM_CONNECT_ALIVE:
		case T_IM_CONNECT_ALIVE:
		case T_FM_CONNECT_ALIVE:
		case T_NM_CONNECT_ALIVE:
		case T_FtoA_ALIVE:				// 2007-12-27 by dhjin, 아레나 통합 -
			OnRecvdAlivePacket();
			procRes = RES_RETURN_TRUE;
			break;

		////////////////////////////////////////////////////////////////////////
		// FieldServer <-- NPCServer
		case T_FN_NPCSERVER_START:

			// 2013-04-01 by hskim, NPCServer 패킷으로 위조 공격 방어
			if( FALSE == g_pFieldGlobal->CheckAllowedNPCServerIP(this->GetPeerIP()) )
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FN_NPCSERVER_START Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());

				return FALSE;
			}
			// end 2013-04-01 by hskim, NPCServer 패킷으로 위조 공격 방어

			ms_pFieldIOCP->CloseUDPPortForOtherServer();
			Sleep(200);													// 즉시 Open할 경우 상대방에 에러를 일으킨다
			if(ms_pFieldIOCP->OpenUDPPortForOtherServer() == FALSE)
			{
				return FALSE;
			}

			strcpy(m_character.CharacterName, "NPC Server");
			*(MessageType_t*)SendBuf = T_FN_NPCSERVER_START_OK;
			SendAddData(SendBuf, SIZE_FIELD_TYPE_HEADER);

			m_PeerSocketType = ST_NPC_SERVER;
			ms_pFieldIOCP->m_pNPCTCPSocket = this;	// NPC Server와의 TCP 세션 저장

			procRes = RES_RETURN_TRUE;
			break;
		case T_FN_MONSTER_AUTO_DESTROYED:		// 2007-11-26 by cmkwon, 몬스터 자동삭제 메시지 TCP로 전송(N->F) - 
			procRes = Process_FN_MONSTER_AUTO_DESTROYED(pPacket, nLength, nBytesUsed);
			break;

		//////////////////////////////////////////////////////////////////
		// FieldServer <-- AdminTool
		case T_FA_ADMIN_CONNECT:
			{
				MSG_FA_ADMIN_CONNECT* msgAdminConnect = (MSG_FA_ADMIN_CONNECT*)(pPacket + nBytesUsed);
				nBytesUsed += sizeof(MSG_FA_ADMIN_CONNECT);

				// 인증하기
				INIT_MSG(MSG_FA_ADMIN_CONNECT_OK, T_FA_ADMIN_CONNECT_OK, msgAdminConnectOK, SendBuf);
// 2006-04-15 by cmkwon
//				msgAdminConnectOK->AuthOK = bRet;
				msgAdminConnectOK->AccountType0 = g_pGlobalGameServer->AuthAdminToolUser(msgAdminConnect->UID, msgAdminConnect->PWD);
				SendAddData(SendBuf, MSG_SIZE(MSG_FA_ADMIN_CONNECT_OK));
				if (!msgAdminConnectOK->AccountType0)
				{
					procRes = RES_RETURN_FALSE;
					Close();
					break;
				}

				// 인증 성공
				m_PeerSocketType = ST_ADMIN_TOOL;

				ms_pFieldIOCP->InsertMonitorIOCPSocketPtr(this);
			}
			break;
		////////////////////////////////////////////////////////////////////////
		// From Monitor Client
		case T_FM_CONNECT:
			{
				// 2008-06-05 by cmkwon, AdminTool, Monitor 접근 가능 IP를 server config file 에 설정하기 - 아래와 같이 수정 함
				//if(FALSE == IS_SCADMINTOOL_CONNECTABLE_IP(GetPeerIP()))
				if(FALSE == g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))		// 2008-06-05 by cmkwon, AdminTool, Monitor 접근 가능 IP를 server config file 에 설정하기 - 
				{
					return FALSE;
				}
// 2007-11-01 by cmkwon, 아래와 같이 수정 함
//				char szSystemLog[256];
//				sprintf(szSystemLog, "Monitor Client Connected, IP[%s]\r\n", GetPeerIP());
//				DBGOUT(szSystemLog);
//				g_pFieldGlobal->WriteSystemLog(szSystemLog);
				g_pGlobal->WriteSystemLogEX(TRUE, "[Notify] SCMonitor connected !!, IP(%s)\r\n", GetPeerIP());

				m_PeerSocketType = ST_MONITOR_SERVER;
				ms_pFieldIOCP->InsertMonitorIOCPSocketPtr(this);

				strcpy(m_character.CharacterName, "Monitoring Client");
				MSG_FM_CONNECT_OK	*pSendFMConnectOK = NULL;

				*(MessageType_t*)SendBuf = T_FM_CONNECT_OK;
				pSendFMConnectOK = (MSG_FM_CONNECT_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
				STRNCPY_MEMSET(pSendFMConnectOK->IPAddress, g_pFieldGlobal->GetPublicIPLocal(), SIZE_MAX_IPADDRESS);
				pSendFMConnectOK->NumOfClients = 1;
				pSendFMConnectOK->Port = ms_pFieldIOCP->m_nListenerPort;
				pSendFMConnectOK->CalcBandwidth = ms_pFieldIOCP->GetFlagCalcTrafficInfo();
				pSendFMConnectOK->LoadedMapCounts = ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectCounts();
				pSendFMConnectOK->StartedTime = ms_pFieldIOCP->m_dwTimeStarted;
				STRNCPY_MEMSET(pSendFMConnectOK->ServerName, "Field Server", SIZE_MAX_SERVER_NAME);
				SendAddData(SendBuf, MSG_SIZE(MSG_FM_CONNECT_OK));

				//////////////////////////////////////////////////////////
				// Loaded Map Info
				int nMapProjectCounts = ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectCounts();
				for(int i = 0; i < nMapProjectCounts; i++)
				{
					CFieldMapProject *pMapProject = (CFieldMapProject*)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByIndex(i);

					INIT_MSG(MSG_FM_SEND_CHANNEL_INFO, T_FM_SEND_CHANNEL_INFO, pSendChannelInfo, SendBuf);
					int nMapChannelCounts = pMapProject->GetNumberOfMapChannels();
					for (int j = 0; j < nMapChannelCounts; j++)
					{
						CFieldMapChannel *pFieldMapChannel = pMapProject->GetFieldMapChannelByIndex(j);
						if (pFieldMapChannel == NULL)
						{
							continue;
						}
						pSendChannelInfo->ChannelIndex			= pFieldMapChannel->m_MapChannelIndex.ChannelIndex;
						pSendChannelInfo->IsEnabled				= pFieldMapChannel->IsEnabled();
						pSendChannelInfo->projectInfo			= *((PROJECTINFO*)pMapProject);
						pSendChannelInfo->bCityWarMap			= FALSE;

						if(pFieldMapChannel->m_pRefCityWar1
							&& IS_CITYWAR_MAP_INDEX(pFieldMapChannel->GetMapChannelIndex().MapIndex))
						{
							pSendChannelInfo->bCityWarMap		= TRUE;
							pSendChannelInfo->cityWarOccupyInfo	= *(pFieldMapChannel->m_pRefCityWar1->GetCITY_OCCUPY_INFO());
						}
						SendAddData(SendBuf, MSG_SIZE(MSG_FM_SEND_CHANNEL_INFO));
					}
				}
			}
			break;
		case T_FM_GET_NUM_CLIENTS:
			{
				mt_auto_lock mtB(&ms_pFieldIOCP->m_mapCharacterUniqueNumber); // 2013-10-01 by jekim, 툴에 각 세력별 접속 유저 수 추가.
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_GET_NUM_CLIENTS Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				MSG_FM_GET_NUM_CLIENTS_OK	*pSendFMGetNumClientsOK = NULL;

				*(MessageType_t*)SendBuf = T_FM_GET_NUM_CLIENTS_OK;
				pSendFMGetNumClientsOK = (MSG_FM_GET_NUM_CLIENTS_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
				pSendFMGetNumClientsOK->NumOfClients = ms_pFieldIOCP->m_mapCharacterUniqueNumber.size();
				// 2013-10-01 by jekim, 툴에 각 세력별 접속 유저 수 추가.
				pSendFMGetNumClientsOK->NumOfANI = 0;
				pSendFMGetNumClientsOK->NumOfBCU = 0;
				for(mtmapUID2FieldIOCPSocket::iterator it=ms_pFieldIOCP->m_mapCharacterUniqueNumber.begin();it!=ms_pFieldIOCP->m_mapCharacterUniqueNumber.end();++it) {
					if(COMPARE_INFLUENCE(it->second->m_character.InfluenceType,INFLUENCE_TYPE_ANI) && FALSE == COMPARE_RACE(it->second->m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO|RACE_DELETED_CHARACTER))
					{
						pSendFMGetNumClientsOK->NumOfANI++;
					}
					else if(COMPARE_INFLUENCE(it->second->m_character.InfluenceType,INFLUENCE_TYPE_VCN) && FALSE == COMPARE_RACE(it->second->m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO|RACE_DELETED_CHARACTER))
					{
						pSendFMGetNumClientsOK->NumOfBCU++;
					}
				}
				// end 2013-10-01 by jekim, 툴에 각 세력별 접속 유저 수 추가.
				SendAddData(SendBuf, MSG_SIZE(MSG_FM_GET_NUM_CLIENTS_OK));
			}
			break;
		case T_FM_SHUTDOWN:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				break; // 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 추가 명령문 삭제
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_SHUTDOWN Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				
				*(MessageType_t*)SendBuf = T_FM_SHUTDOWN_OK;
				SendAddData(SendBuf, SIZE_FIELD_TYPE_HEADER);
				PostMessage(g_pFieldGlobal->GetMainWndHandle(), WM_CLOSE, 0, 0);
			}
			break;
		case T_FM_PING:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_PING Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				*(MessageType_t*)SendBuf = T_FM_PING_OK;
				SendAddData(SendBuf, SIZE_FIELD_TYPE_HEADER);
			}
			break;
		case T_FM_SAVE_MAPBLOCK_INFO:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_SAVE_MAPBLOCK_INFO Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_SAVE_MAPBLOCK_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_PRINTMAP:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_PRINTMAP Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_PRINTMAP(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_PRINT_DEBUG_MSG:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_PRINT_DEBUG_MSG Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_PRINT_DEBUG_MSG(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_CHANGE_BANDWIDTH_FLAG:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_CHANGE_BANDWIDTH_FLAG Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				ms_pFieldIOCP->SetFlagCalcTrafficInfo(!ms_pFieldIOCP->GetFlagCalcTrafficInfo());

				// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 맵 밴스위스 체크는 거의 필요 하지 않음
				//ms_pFieldIOCP->GetMapWorkspace()->SetLogFlagMapBandwidth(ms_pFieldIOCP->GetFlagCalcTrafficInfo());

				*(MessageType_t*)SendBuf = T_FM_CHANGE_BANDWIDTH_FLAG_OK;
				MSG_FM_CHANGE_BANDWIDTH_FLAG_OK		*pChangeFlag
					 = (MSG_FM_CHANGE_BANDWIDTH_FLAG_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
				pChangeFlag->bChagedFlag = ms_pFieldIOCP->GetFlagCalcTrafficInfo();

				SendAddData(SendBuf, MSG_SIZE(MSG_FM_CHANGE_BANDWIDTH_FLAG_OK));
			}
			break;
		case T_FM_SET_MSG_PRINT_LEVEL:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_SET_MSG_PRINT_LEVEL Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				BYTE tmpLevel = *(BYTE*)(pPacket + nBytesUsed);
				nBytesUsed += sizeof(MSG_FM_SET_MSG_PRINT_LEVEL);

				// set msg print level
				GSetexchangeMsgPrintLevel(tmpLevel);
			}
			break;
		case T_FM_GET_CHARACTER_INFO:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_GET_CHARACTER_INFO Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				MSG_FM_GET_CHARACTER_INFO *pMsgGetCharacInfo = (MSG_FM_GET_CHARACTER_INFO*)(pPacket + nBytesUsed);
				nBytesUsed += sizeof(MSG_FM_GET_CHARACTER_INFO);

				INIT_MSG_WITH_BUFFER(MSG_FM_GET_CHARACTER_INFO_OK, T_FM_GET_CHARACTER_INFO_OK, pMsgGetOK, pMsgGetOKBuf);
				memset(pMsgGetOK, 0x00, sizeof(CHARACTER));

				CFieldIOCPSocket *pSock = NULL;
				BOOL bFound = FALSE;

				pSock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pMsgGetCharacInfo->CharacterName);
				if (pSock && pSock->IsUsing())
				{
					pMsgGetOK->CharacterInfo = pSock->m_character;
					bFound = TRUE;
				}
				
				if (pMsgGetCharacInfo->CharacterUniqueNumber != INVALID_UNIQUE_NUMBER && !bFound)
				{
					pSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(pMsgGetCharacInfo->CharacterUniqueNumber);
					if (pSock != NULL)
					{
						pMsgGetOK->CharacterInfo = pSock->m_character;
						bFound = TRUE;
					}
				}

				if (pMsgGetCharacInfo->ClientIndex != INVALID_CLIENT_INDEX && !bFound)
				{
					CHARACTER *pCharac = ms_pFieldIOCP->GetCharacterByArrayIndex(pMsgGetCharacInfo->ClientIndex);
					if (pCharacter != NULL)
					{
						pMsgGetOK->CharacterInfo = *pCharac;
						bFound = TRUE;
					}
				}

				if (bFound)
				{
					SendAddData(pMsgGetOKBuf, MSG_SIZE(MSG_FM_GET_CHARACTER_INFO_OK));
				}
				else
				{
					SendErrorMessage(T_FM_GET_CHARACTER_INFO, ERR_COMMON_NO_SUCH_CHARACTER,
						pMsgGetCharacInfo->CharacterUniqueNumber,
						pMsgGetCharacInfo->ClientIndex,
						pMsgGetCharacInfo->CharacterName
					);
				}
			}
			break;
		case T_FM_GET_MAP_USER_COUNTS:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_GET_MAP_USER_COUNTS Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_GET_MAP_USER_COUNTS(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_RELOAD_ITEM_INFO:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_RELOAD_ITEM_INFO Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				ms_pFieldIOCP->ReloadIteminfo();
				*(MessageType_t*)SendBuf = T_FM_RELOAD_ITEM_INFO_OK;
				SendAddData(SendBuf, SIZE_FIELD_TYPE_HEADER);
			}
			break;
		case T_FM_SET_SERVICE_STATE:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_SET_SERVICE_STATE Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_SET_SERVICE_STATE(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_RELOAD_SERVER_INFO:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_RELOAD_SERVER_INFO Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_RELOAD_SERVER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_RESET_NPC_SERVER:
			{
				// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_RESET_NPC_SERVER Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
					break;
				}
				// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
				// NPC와의 연결을 끊는다. 이후 NPC 서버는 새로이 접속을 시도함.
				if (ms_pFieldIOCP->m_pNPCTCPSocket != NULL)
				{
					ms_pFieldIOCP->m_pNPCTCPSocket->Close();
					ms_pFieldIOCP->m_pNPCTCPSocket = NULL;
				}

				// Monster Info를 다시 로딩한다.
				CMonsterDBAccess MonsterDBAccess;
				MonsterDBAccess.GetAllMonsters(ms_pFieldIOCP->m_mapMonsterInfo, &ms_pFieldIOCP->m_mapItemInfo, MONSTER_LOAD_TYPE_SIZE_FOR_CLIENT, &(g_pFieldGlobal->m_Localization));

				// Map Object Info
				ms_pFieldIOCP->GetMapWorkspace()->LoadAllObjectInfofromDB();

				*(MessageType_t*)SendBuf = T_FM_RESET_NPC_SERVER_OK;
				SendAddData(SendBuf, SIZE_FIELD_TYPE_HEADER);
			}
			break;
		case T_FM_INCREASE_CHANNEL:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_INCREASE_CHANNEL Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_INCREASE_CHANNEL(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_SET_CHANNEL_STATE:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_SET_CHANNEL_STATE Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_SET_CHANNEL_STATE(pPacket, nLength, nBytesUsed);
			break;
		case T_FM_CITYWAR_CHANGE_WAR_TIME:
			// 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			if(FALSE==g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Connect T_FM_CITYWAR_CHANGE_WAR_TIME Command Using: HackingIP(%15s)\r\n", this->GetPeerIP());
				break;
			}
			// end 2011-11-18 by shcho, 서버다운 프리페어서버다운 제거 처리 - 등록된 IP가 아니면 처리안되도록 한다.
			procRes = Process_FM_CITYWAR_CHANGE_WAR_TIME(pPacket, nLength, nBytesUsed);
			break;

		////////////////////////////////////////////////////////////////////////
		// From Field Client
		case T_FC_CONNECT_LOGIN:
			procRes = Process_FC_CONNECT_LOGIN(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CONNECT_NETWORK_CHECK:	// 2008-02-15 by cmkwon, Client<->FieldServer 간 네트워크 상태 체크 - 
			procRes = Process_FC_CONNECT_NETWORK_CHECK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CONNECT_ARENASERVER_LOGIN:			// 2007-12-28 by dhjin,  아레나 통합 -
			procRes = Process_FC_CONNECT_ARENASERVER_LOGIN(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CONNECT_ARENASERVER_TO_IMSERVER:			// 2008-03-03 by dhjin,  아레나 통합 -
			procRes = Process_FC_CONNECT_ARENASERVER_TO_IMSERVER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_CHARACTER:
			procRes = Process_FC_CHARACTER_GET_CHARACTER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CREATE:
			procRes = Process_FC_CHARACTER_CREATE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_DELETE:
			procRes = Process_FC_CHARACTER_DELETE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_OTHER_INFO:
			procRes = Process_FC_CHARACTER_GET_OTHER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_OTHER_MOVE:
			procRes = Process_FC_CHARACTER_GET_OTHER_MOVE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_OTHER_RENDER_INFO:
			procRes = Process_FC_CHARACTER_GET_OTHER_RENDER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_ACCOUNTUNIQUENUMBER:
			procRes = Process_FC_CHARACTER_GET_ACCOUNTUNIQUENUMBER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_APPLY_COLLISION_DAMAGE:
			procRes = Process_FC_CHARACTER_APPLY_COLLISION_DAMAGE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GAMESTART:
			procRes = Process_FC_CHARACTER_GAMESTART(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CONNECT_GAMESTART:
			procRes = Process_FC_CHARACTER_CONNECT_GAMESTART(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_DEAD_GAMESTART:
			procRes = Process_FC_CHARACTER_DEAD_GAMESTART(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GAMEEND:
			procRes = Process_FC_CHARACTER_GAMEEND(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_REPAIR:
			procRes = Process_FC_CHARACTER_REPAIR(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_DOCKING:
			procRes = Process_FC_CHARACTER_DOCKING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_UNDOCKING:
			procRes = Process_FC_CHARACTER_UNDOCKING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CHANGE_BODYCONDITION:
			procRes = Process_FC_CHARACTER_CHANGE_BODYCONDITION(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CHANGE_BODYCONDITION_ALL:
			procRes = Process_FC_CHARACTER_CHANGE_BODYCONDITION_ALL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_SHOW_EFFECT:
			procRes = Process_FC_CHARACTER_SHOW_EFFECT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_OTHER_PARAMFACTOR:
			procRes = Process_FC_CHARACTER_GET_OTHER_PARAMFACTOR(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE:
			procRes = Process_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_SPEED_HACK_USER:
			procRes = Process_FC_CHARACTER_SPEED_HACK_USER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_CASH_MONEY_COUNT:
			procRes = Process_FC_CHARACTER_GET_CASH_MONEY_COUNT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_TUTORIAL_SKIP:
			procRes = Process_FC_CHARACTER_TUTORIAL_SKIP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CHANGE_CHARACTER_MODE:
			procRes = Process_FC_CHARACTER_CHANGE_CHARACTER_MODE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_FALLING_BY_FUEL_ALLIN:
			procRes = Process_FC_CHARACTER_FALLING_BY_FUEL_ALLIN(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_WARP_BY_AGEAR_LANDING_FUEL_ALLIN:
			procRes = Process_FC_CHARACTER_WARP_BY_AGEAR_LANDING_FUEL_ALLIN(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK:
			procRes = Process_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK:
			procRes = Process_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK:
			procRes = Process_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_MEMORY_HACK_USER:
			procRes = Process_FC_CHARACTER_MEMORY_HACK_USER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_UPDATE_SUBLEADER:			// 2007-02-14 by dhjin
			procRes = Process_FC_CHARACTER_UPDATE_SUBLEADER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_OBSERVER_START:			// 2007-03-27 by dhjin
			procRes = Process_FC_CHARACTER_OBSERVER_START(pPacket, nLength, nBytesUsed);
			break;		///////////////////////////////////////////////////////////////////////
		case T_FC_CHARACTER_OBSERVER_END:			// 2007-03-27 by dhjin
			procRes = Process_FC_CHARACTER_OBSERVER_END(pPacket, nLength, nBytesUsed);
			break;		///////////////////////////////////////////////////////////////////////
		case T_FC_CHARACTER_SHOW_MAP_EFFECT:		// 2007-04-20 by cmkwon
			procRes = Process_FC_CHARACTER_SHOW_MAP_EFFECT(pPacket, nLength, nBytesUsed);
			break;		///////////////////////////////////////////////////////////////////////
		// 2008-01-10 by dhjin,  아레나 통합 - 
		case T_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER:
			procRes = Process_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER:
			procRes = Process_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CHARACTER_GET_USER_INFO:		// 2008-06-23 by dhjin, EP3 유저정보옵션 -
			procRes = Process_FC_CHARACTER_GET_USER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET:			// 2008-06-23 by dhjin, EP3 유저정보옵션 -
			procRes = Process_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CHARACTER_CHANGE_NICKNAME:			// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
			procRes = Process_FC_CHARACTER_CHANGE_NICKNAME(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX:		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
			procRes = Process_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_CHARACTER_DEBUFF_DOT_INFO:	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - F -> C
			procRes = Process_FC_CHARACTER_DEBUFF_DOT_INFO(pPacket, nLength, nBytesUsed);
			break;					
		case T_FC_CHARACTER_GET_USER_ITEM_INFO:		// 2012-06-05 by jhseol, 아템미리보기 - 살펴볼 케릭터 UID
			procRes = Process_FC_CHARACTER_GET_USER_ITEM_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET:		// 2012-07-12 by jhseol, 아템미리보기 On / Off 기능 - 공개 여부
			procRes = Process_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// MOVE
		case T_FC_MOVE:
			procRes = Process_FC_MOVE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_LOCKON:
			procRes = Process_FC_MOVE_LOCKON(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_UNLOCKON:
			procRes = Process_FC_MOVE_UNLOCKON(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_LANDING:
			procRes = Process_FC_MOVE_LANDING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_LANDING_DONE:
			procRes = Process_FC_MOVE_LANDING_DONE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_TAKEOFF:
			procRes = Process_FC_MOVE_TAKEOFF(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_TARGET:
			procRes = Process_FC_MOVE_TARGET(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_WEAPON_VEL:
			procRes = Process_FC_MOVE_WEAPON_VEL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_ROLLING:
			procRes = Process_FC_MOVE_ROLLING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_HACKSHIELD_GuidAckMsg:
			procRes = Process_FC_MOVE_HACKSHIELD_GuidAckMsg(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_HACKSHIELD_CRCAckMsg:
			procRes = Process_FC_MOVE_HACKSHIELD_CRCAckMsg(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_HACKSHIELD_HACKING_CLIENT:
			procRes = Process_FC_MOVE_HACKSHIELD_HACKING_CLIENT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK:	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
			procRes = Process_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK:	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
			procRes = Process_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK:	// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 
			procRes = Process_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK:	// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
			procRes = Process_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_XTRAP_REQ_STEP_OK:	// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
			procRes = Process_FC_MOVE_XTRAP_REQ_STEP_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MOVE_APEX_REQ_APEXDATA_OK:	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
			procRes = Process_FC_MOVE_APEX_REQ_APEXDATA_OK(pPacket, nLength, nBytesUsed);
			break;


		///////////////////////////////////////////////////////////////////////
		// BATTLE
		case T_FC_BATTLE_ATTACK:
			procRes = Process_FC_BATTLE_ATTACK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_ATTACK_FIND:
			procRes = Process_FC_BATTLE_ATTACK_FIND(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_DROP_MINE:
			procRes = Process_FC_BATTLE_DROP_MINE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_MINE_ATTACK:
			procRes = Process_FC_BATTLE_MINE_ATTACK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_MINE_ATTACK_FIND:
			procRes = Process_FC_BATTLE_MINE_ATTACK_FIND(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_DROP_DUMMY:
			procRes = Process_FC_BATTLE_DROP_DUMMY(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_DROP_FIXER:
			procRes = Process_FC_BATTLE_DROP_FIXER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_TOGGLE_SHIELD:
			procRes = Process_FC_BATTLE_TOGGLE_SHIELD(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_TOGGLE_DECOY:
			procRes = Process_FC_BATTLE_TOGGLE_DECOY(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_ATTACK_EVASION:
			procRes = Process_FC_BATTLE_ATTACK_EVASION(pPacket, nLength, nBytesUsed);
			break;

// 2004-12-27 by cmkwon, 사용하지 않음
//		case T_FC_BATTLE_REQUEST_PK:
//			procRes = Process_FC_BATTLE_REQUEST_PK(pPacket, nLength, nBytesUsed);
//			break;
		case T_FC_BATTLE_REQUEST_P2P_PK:
			procRes = Process_FC_BATTLE_REQUEST_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK:
			procRes = Process_FC_BATTLE_ACCEPT_REQUEST_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_REJECT_REQUEST_P2P_PK:
			procRes = Process_FC_BATTLE_REJECT_REQUEST_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_SURRENDER_P2P_PK:
			procRes = Process_FC_BATTLE_SURRENDER_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK:
			procRes = Process_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BATTLE_REJECT_SURRENDER_P2P_PK:
			procRes = Process_FC_BATTLE_REJECT_SURRENDER_P2P_PK(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// EVENT
// 2004-12-16 by cmkwon, 다른 필드서버로의 워프는 없으므로 삭제함
//		case T_FC_EVENT_WARP_CONNECT:
//			procRes = Process_FC_EVENT_WARP_CONNECT(pPacket, nLength, nBytesUsed);
//			break;
		case T_FC_EVENT_WARP_SAME_MAP_DONE:
			procRes = Process_FC_EVENT_WARP_SAME_MAP_DONE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_WARP_SAME_FIELD_SERVER_DONE:
			procRes = Process_FC_EVENT_WARP_SAME_FIELD_SERVER_DONE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_ENTER_BUILDING_OK:
			procRes = Process_FC_EVENT_ENTER_BUILDING_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_LEAVE_BUILDING:
			procRes = Process_FC_EVENT_LEAVE_BUILDING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_REQUEST_WARP:
			procRes = Process_FC_EVENT_REQUEST_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_REQUEST_OBJECT_EVENT:
			procRes = Process_FC_EVENT_REQUEST_OBJECT_EVENT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_SELECT_CHANNEL:
			procRes = Process_FC_EVENT_SELECT_CHANNEL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY:
			procRes = Process_FC_EVENT_SELECT_CHANNEL_WITH_PARTY(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_REQUEST_RACING_WARP:
			procRes = Process_FC_EVENT_REQUEST_RACING_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST:
			procRes = Process_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_REQUEST_SHOP_WARP:
			procRes = Process_FC_EVENT_REQUEST_SHOP_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING:
			procRes = Process_FC_EVENT_CHARACTERMODE_ENTER_BUILDING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK:		// 2006-07-21 by cmkwon
			procRes = Process_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_CLICK_TELEPORT:			// 2007-09-06 by dhjin
			procRes = Process_FC_EVENT_CLICK_TELEPORT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_NOTIFY_MSG_GET:			// 2007-11-28 by cmkwon, 통지시스템 구현 -
			procRes = Process_FC_EVENT_NOTIFY_MSG_GET(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_NOTIFY_MSG_DELETE:			// 2007-11-28 by cmkwon, 통지시스템 구현 -
			procRes = Process_FC_EVENT_NOTIFY_MSG_DELETE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_EVENT_COUPON_EVENT_USE_COUPON:	// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - 
			procRes = Process_FC_EVENT_COUPON_EVENT_USE_COUPON(pPacket, nLength, nBytesUsed);
			break;


		///////////////////////////////////////////////////////////////////////
		// SHOP
		case T_FC_SHOP_GET_ITEMINFO:
			procRes = Process_FC_SHOP_GET_ITEMINFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_BUY_ITEM:
			procRes = Process_FC_SHOP_BUY_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_SELL_ITEM:
			procRes = Process_FC_SHOP_SELL_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_GET_USED_ITEM_PRICE:
			procRes = Process_FC_SHOP_GET_USED_ITEM_PRICE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_GET_SHOP_ITEM_LIST:
			procRes = Process_FC_SHOP_GET_SHOP_ITEM_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_REQUEST_REPAIR:
			procRes = Process_FC_SHOP_REQUEST_REPAIR(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_BUY_CASH_ITEM:
			procRes = Process_FC_SHOP_BUY_CASH_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_BUY_COLOR_ITEM:
			procRes = Process_FC_SHOP_BUY_COLOR_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_BUY_WARPOINT_ITEM:
			procRes = Process_FC_SHOP_BUY_WARPOINT_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_CHECK_GIVE_TARGET:	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 
			procRes = Process_FC_SHOP_CHECK_GIVE_TARGET(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_INFLUENCE_BUFF:		// 2013-05-09 by hskim, 세력 포인트 개선
			procRes = Process_FC_SHOP_INFLUENCE_BUFF(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////
		// ITEM
		case T_FC_STORE_GET_ITEM:
			procRes = Process_FC_STORE_GET_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_STORE_MOVE_ITEM:
			procRes = Process_FC_STORE_MOVE_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_STORE_EXPIRE_USINGITEM:		// 2006-10-11 by cmkwon
			procRes = Process_FC_STORE_EXPIRE_USINGITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_STORE_REQUEST_QUICKSLOT:
			procRes = Process_FC_STORE_REQUEST_QUICKSLOT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_STORE_SAVE_QUICKSLOT:
			procRes = Process_FC_STORE_SAVE_QUICKSLOT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_STORE_LOG_GUILD_ITEM:
			procRes = Process_FC_STORE_LOG_GUILD_ITEM(pPacket, nLength, nBytesUsed);
			break;	

		case T_FC_ITEM_GET_ITEM:
			procRes = Process_FC_ITEM_GET_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_DELETE_ITEM_ADMIN:
			procRes = Process_FC_ITEM_DELETE_ITEM_ADMIN(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_DELETE_DROP_ITEM:
			procRes = Process_FC_ITEM_DELETE_DROP_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_USE_BONUSSTAT:
			procRes = Process_FC_CHARACTER_USE_BONUSSTAT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_CHANGE_WINDOW_POSITION:
			procRes = Process_FC_ITEM_CHANGE_WINDOW_POSITION(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_UPDATE_WINDOW_ITEM_LIST:
			procRes = Process_FC_ITEM_UPDATE_WINDOW_ITEM_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_THROW_AWAY_ITEM:
			procRes = Process_FC_ITEM_THROW_AWAY_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_ENERGY:
			procRes = Process_FC_ITEM_USE_ENERGY(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_ITEM:
			procRes = Process_FC_ITEM_USE_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_ENCHANT:
			procRes = Process_FC_ITEM_USE_ENCHANT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_MIX_ITEMS:
			procRes = Process_FC_ITEM_MIX_ITEMS(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_GUILDSUMMON:
			procRes = Process_FC_ITEM_USE_CARDITEM_GUILDSUMMON(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_RESTORE:
			procRes = Process_FC_ITEM_USE_CARDITEM_RESTORE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_GUILD:
			procRes = Process_FC_ITEM_USE_CARDITEM_GUILD(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON:
			procRes = Process_FC_ITEM_USE_CARDITEM_MONSTERSUMMON(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME:
			procRes = Process_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE:
			procRes = Process_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE:
			procRes = Process_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE(pPacket, nLength, nBytesUsed);
			break;
			
			// 2014-06-10 by bckim, 세력변경 아이템
		case T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE:
			procRes = Process_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE(pPacket, nLength, nBytesUsed);
			break;
			// End. 2014-06-10 by bckim, 세력변경 아이템
			
		case T_FC_ITEM_USE_INFLUENCE_BUFF:
			procRes = Process_FC_ITEM_USE_INFLUENCE_BUFF(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_INFLUENCE_GAMEEVENT:
			procRes = Process_FC_ITEM_USE_INFLUENCE_GAMEEVENT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_RANDOMBOX:
			procRes = Process_FC_ITEM_USE_RANDOMBOX(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_SKILL_SUPPORT_ITEM:		// 2006-09-29 by cmkwon
			procRes = Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_USE_LUCKY_ITEM:				// 2008-11-04 by dhjin, 럭키머신
			procRes = Process_FC_ITEM_USE_LUCKY_ITEM(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////////////////////
		// 2011-09-20 by hskim, 파트너 시스템 2차

		case T_FC_ITEM_USE_PET_SOCKET_ITEM:	
			procRes = Process_FC_ITEM_USE_PET_SOCKET_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_CANCEL_PET_SOCKET_ITEM:
			procRes = Process_FC_ITEM_CANCEL_PET_SOCKET_ITEM(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////
		// INFO 요청
		case T_FC_INFO_GET_MONSTER_INFO:
			procRes = Process_FC_INFO_GET_MONSTER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_MAPOBJECT_INFO:
			procRes = Process_FC_INFO_GET_MAPOBJECT_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_ITEM_INFO:
			procRes = Process_FC_INFO_GET_ITEM_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_SIMPLE_ITEM_INFO:
			procRes = Process_FC_INFO_GET_SIMPLE_ITEM_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_RARE_ITEM_INFO:
			procRes = Process_FC_INFO_GET_RARE_ITEM_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_BUILDINGNPC_INFO:
			procRes = Process_FC_INFO_GET_BUILDINGNPC_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_ENCHANT_COST:
			procRes = Process_FC_INFO_GET_ENCHANT_COST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_CURRENT_MAP_INFO:
			procRes = Process_FC_INFO_GET_CURRENT_MAP_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_SERVER_DATE_TIME:
			procRes = Process_FC_INFO_GET_SERVER_DATE_TIME(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO:	// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - C->F
			procRes = Process_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO(pPacket, nLength, nBytesUsed);
			break;

		case T_FC_INFO_CHECK_RESOBJ_CHECKSUM:		// 2007-05-28 by cmkwon
			procRes = Process_FC_INFO_CHECK_RESOBJ_CHECKSUM(pPacket, nLength, nBytesUsed);
			break;
			
		///////////////////////////////////////////////////////////////////////
		// Request
		case T_FC_REQUEST_REQUEST:
			procRes = Process_FC_REQUEST_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_REQUEST_ACCEPT_REQUEST:
			procRes = Process_FC_REQUEST_ACCEPT_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_REQUEST_REJECT_REQUEST:
			procRes = Process_FC_REQUEST_REJECT_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// FC_CITY - 도시용 프로토콜
		case T_FC_CITY_GET_BUILDING_LIST:
			procRes = Process_FC_CITY_GET_BUILDING_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITY_REQUEST_ENTER_BUILDING:
			procRes = Process_FC_CITY_REQUEST_ENTER_BUILDING(pPacket, nLength, nBytesUsed);
			break;
// 2004-11-10 by cmkwon, Process_FC_EVENT_REQUEST_SHOP_WARP, Process_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST로 대체함
//		case T_FC_CITY_GET_WARP_TARGET_MAP_LIST:
//			procRes = Process_FC_CITY_GET_WARP_TARGET_MAP_LIST(pPacket, nLength, nBytesUsed);
//			break;
//		case T_FC_CITY_REQUEST_WARP:
//			procRes = Process_FC_CITY_REQUEST_WARP(pPacket, nLength, nBytesUsed);
//			break;
		case T_FC_CITY_CHECK_WARP_STATE:
			procRes = Process_FC_CITY_CHECK_WARP_STATE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST:
			procRes = Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO:
			procRes = Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITY_POLL_REG_LEADER_CANDIDATE:
			procRes = Process_FC_CITY_POLL_REG_LEADER_CANDIDATE(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE:
			procRes = Process_FC_CITY_POLL_DELETE_LEADER_CANDIDATE(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CITY_POLL_VOTE:
			procRes = Process_FC_CITY_POLL_VOTE(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_CITY_POLL_REQUEST_POLL_DATE:
			procRes = Process_FC_CITY_POLL_REQUEST_POLL_DATE(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CITY_WARINFO_INFLUENCE:
			procRes = Process_FC_CITY_WARINFO_INFLUENCE(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_CITY_WARINFO_OUTPOST:
			procRes = Process_FC_CITY_WARINFO_OUTPOST(pPacket, nLength, nBytesUsed);
			break;	

		///////////////////////////////////////////////////////////////////////
		// Quest
		case T_FC_QUEST_REQUEST_START:
			procRes = Process_FC_QUEST_REQUEST_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_ACCEPT_QUEST:
			procRes = Process_FC_QUEST_ACCEPT_QUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_CANCEL_QUEST:
			procRes = Process_FC_QUEST_CANCEL_QUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_REQUEST_SUCCESS:
			procRes = Process_FC_QUEST_REQUEST_SUCCESS(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_DISCARD_QUEST:
			procRes = Process_FC_QUEST_DISCARD_QUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_MOVE_QUEST_MAP:
			procRes = Process_FC_QUEST_MOVE_QUEST_MAP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_REQUEST_SUCCESS_CHECK:
			procRes = Process_FC_QUEST_REQUEST_SUCCESS_CHECK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_REQUEST_PARTY_WARP_ACK:		// 2006-10-16 by cmkwon
			procRes = Process_FC_QUEST_REQUEST_PARTY_WARP_ACK(pPacket, nLength, nBytesUsed);
			break;
			
		///////////////////////////////////////////////////////////////////////
		// Party & Guild
		case T_FC_PARTY_REQUEST_INVITE:
			procRes = Process_FC_PARTY_REQUEST_INVITE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_ACCEPT_INVITE:
			procRes = Process_FC_PARTY_ACCEPT_INVITE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_REJECT_INVITE:
			procRes = Process_FC_PARTY_REJECT_INVITE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_GET_MEMBER:
			procRes = Process_FC_PARTY_GET_MEMBER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_GET_ALL_MEMBER:
			procRes = Process_FC_PARTY_GET_ALL_MEMBER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_REQUEST_PARTY_WARP:
			procRes = Process_FC_PARTY_REQUEST_PARTY_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME:
			procRes = Process_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT:
			procRes = Process_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_PARTY_GET_OTHER_MOVE:
			procRes = Process_FC_PARTY_GET_OTHER_MOVE(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// Guild
		case T_FC_GUILD_GET_MAP_OWNER_INFO:
			procRes = Process_FC_GUILD_GET_MAP_OWNER_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_GUILD_REQUEST_GUILD_WAR:
			procRes = Process_FC_GUILD_REQUEST_GUILD_WAR(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_GUILD_GET_WAR_INFO:
			procRes = Process_FC_GUILD_GET_WAR_INFO(pPacket, nLength, nBytesUsed);
			break;
// 2004-12-10 by cmkwon, IM Server에서 처리한다, 프로토콜 삭제함
//		case T_FC_GUILD_SURRENDER_GUILD_WAR:
//			procRes = Process_FC_GUILD_SURRENDER_GUILD_WAR(pPacket, nLength, nBytesUsed);
//			break;
		case T_FC_GUILD_SUMMON_MEMBER_OK:
			procRes = Process_FC_GUILD_SUMMON_MEMBER_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_GUILD_DISMEMBER:
			procRes = Process_FC_GUILD_DISMEMBER(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////
		// Trade
		case T_FC_TRADE_REQUEST_TRADE:
			procRes = Process_FC_TRADE_REQUEST_TRADE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_CANCEL_REQUEST:
			procRes = Process_FC_TRADE_CANCEL_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_ACCEPT_TRADE:
			procRes = Process_FC_TRADE_ACCEPT_TRADE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_REJECT_TRADE:
			procRes = Process_FC_TRADE_REJECT_TRADE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_TRANS_ITEM:
			procRes = Process_FC_TRADE_TRANS_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_SEE_ITEM:
			procRes = Process_FC_TRADE_SEE_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_OK_TRADE:
			procRes = Process_FC_TRADE_OK_TRADE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TRADE_CANCEL_TRADE:
			procRes = Process_FC_TRADE_CANCEL_TRADE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_COUNTDOWN_DONE:
			procRes = Process_FC_COUNTDOWN_DONE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_OBJECT_CHANGE_BODYCONDITION:
			procRes = Process_FC_OBJECT_CHANGE_BODYCONDITION(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_AUCTION_REGISTER_ITEM:
			procRes = Process_FC_AUCTION_REGISTER_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_AUCTION_CANCEL_REGISTER:
			procRes = Process_FC_AUCTION_CANCEL_REGISTER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_AUCTION_BUY_ITEM:
			procRes = Process_FC_AUCTION_BUY_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_AUCTION_GET_ITEM_LIST:
			procRes = Process_FC_AUCTION_GET_ITEM_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_USE_SKILLPOINT:
			procRes = Process_FC_SKILL_USE_SKILLPOINT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_SETUP_SKILL:
			procRes = Process_FC_SKILL_SETUP_SKILL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_USE_SKILL:
			procRes = Process_FC_SKILL_USE_SKILL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_CANCEL_SKILL:
			procRes = Process_FC_SKILL_CANCEL_SKILL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_PREPARE_USE:
			procRes = Process_FC_SKILL_PREPARE_USE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_CANCEL_PREPARE:
			procRes = Process_FC_SKILL_CANCEL_PREPARE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_CONFIRM_USE:
			procRes = Process_FC_SKILL_CONFIRM_USE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SKILL_CONFIRM_USE_ACK:
			procRes = Process_FC_SKILL_CONFIRM_USE_ACK(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////
		// FC_TIMER
		case T_FC_TIMER_TIMEOUT:
			procRes = Process_FC_TIMER_TIMEOUT(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// FC_CLIENT_REPORT
		case T_FC_CLIENT_REPORT:
			procRes = Process_FC_CLIENT_REPORT(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// FC_ADMIN
		case T_FC_ADMIN_GET_SERVER_STAT:
			procRes = Process_FC_ADMIN_GET_SERVER_STAT(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// FC_MONSTER
		case T_FC_MONSTER_SKILL_END_SKILL:
			procRes = Process_FC_MONSTER_SKILL_END_SKILL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MONSTER_SUMMON_MONSTER:
			procRes = Process_FC_MONSTER_SUMMON_MONSTER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MONSTER_TUTORIAL_MONSTER_DELETE:
			procRes = Process_FC_MONSTER_TUTORIAL_MONSTER_DELETE(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// T0_FC_RACING
		case T_FC_RACING_RACINGLIST_REQUEST:
			procRes = Process_FC_RACING_RACINGLIST_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_RACING_RACINGINFO_REQUEST:
			procRes = Process_FC_RACING_RACINGINFO_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_RACING_JOIN_REQUEST:
			procRes = Process_FC_RACING_JOIN_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_RACING_CHECKPOINT_CHECK:
			procRes = Process_FC_RACING_CHECKPOINT_CHECK(pPacket, nLength, nBytesUsed);
			break;
		///////////////////////////////////////////////////////////////////////
		// T0_FC_CITYWAR
		case T_FC_CITYWAR_GET_OCCUPYINFO:
			procRes = Process_FC_CITYWAR_GET_OCCUPYINFO(pPacket, nLength, nBytesUsed);
			break;			
		case T_FC_CITYWAR_SET_SETTINGTIME:
			procRes = Process_FC_CITYWAR_SET_SETTINGTIME(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITYWAR_SET_TEX:
			procRes = Process_FC_CITYWAR_SET_TEX(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITYWAR_SET_BRIEFING:
			procRes = Process_FC_CITYWAR_SET_BRIEFING(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CITYWAR_BRING_SUMOFTEX:
			procRes = Process_FC_CITYWAR_BRING_SUMOFTEX(pPacket, nLength, nBytesUsed);
			break;

		case T_FC_WAR_REQ_SIGN_BOARD_STRING_LIST:
			procRes = Process_FC_WAR_REQ_SIGN_BOARD_STRING_LIST(pPacket, nLength, nBytesUsed);
			break;

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 개인 상점 관련
		case T_FC_BAZAAR_SELL_PUT_ITEM:
			procRes = Process_FC_BAZAAR_SELL_PUT_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_SELL_CANCEL_ITEM:
			procRes = Process_FC_BAZAAR_SELL_CANCEL_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_SELL_START:
			procRes = Process_FC_BAZAAR_SELL_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_SELL_REQUEST_ITEMLIST:
			procRes = Process_FC_BAZAAR_SELL_REQUEST_ITEMLIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_SELL_BUY_ITEM:
			procRes = Process_FC_BAZAAR_SELL_BUY_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_BUY_PUT_ITEM:
			procRes = Process_FC_BAZAAR_BUY_PUT_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_BUY_CANCEL_ITEM:
			procRes = Process_FC_BAZAAR_BUY_CANCEL_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_BUY_START:
			procRes = Process_FC_BAZAAR_BUY_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_BUY_REQUEST_ITEMLIST:
			procRes = Process_FC_BAZAAR_BUY_REQUEST_ITEMLIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_BAZAAR_BUY_SELL_ITEM:
			procRes = Process_FC_BAZAAR_BUY_SELL_ITEM(pPacket, nLength, nBytesUsed);
			break;

		//////////////////////////////////////////////////////////////////////////
		// 2007-04-17 by dhjin, ARENA 관련 	
		case T_FC_ARENA_PLAY_CHARACTER_TYPE:		// 2012-06-08 by jhseol, 아레나 추가개발part2 - 케릭터 : 타입 복사
			procRes = Process_FC_ARENA_PLAY_CHARACTER_TYPE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_REQUEST_TEAM:
			procRes = Process_FC_ARENA_REQUEST_TEAM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_CREATE_TEAM:
			procRes = Process_FC_ARENA_CREATE_TEAM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_ENTER_TEAM:
			procRes = Process_FC_ARENA_ENTER_TEAM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_REAVE_TEAM:
			procRes = Process_FC_ARENA_REAVE_TEAM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_TEAM_READY_FINISH:
			procRes = Process_FC_ARENA_TEAM_READY_FINISH(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_TEAM_READY_FINISH_CANCEL:
			procRes = Process_FC_ARENA_TEAM_READY_FINISH_CANCEL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_ENTER_ROOM_WARP:
			procRes = Process_FC_ARENA_ENTER_ROOM_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_FINISH_WARP:
			procRes = Process_FC_ARENA_FINISH_WARP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_REQUEST_CREATE_TEAMINFO:
			procRes = Process_FC_ARENA_REQUEST_CREATE_TEAMINFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ARENA_REQUEST_OTHER_TEAM_INFO:
			procRes = Process_FC_ARENA_REQUEST_OTHER_TEAM_INFO(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_ARENA_QUICK_ENTER_TEAM:
			procRes = Process_FC_ARENA_QUICK_ENTER_TEAM(pPacket, nLength, nBytesUsed);
			break;
		// 2008-01-08 by dhjin, 아레나 통합 - 
		case T_FC_ARENA_CHARACTER_GAMESTART:
			procRes = Process_FC_ARENA_CHARACTER_GAMESTART(pPacket, nLength, nBytesUsed);
			break;

		//////////////////////////////////////////////////////////////////////////
		// 2007-07-06 by dhjin, Tutorial
		case T_FC_TUTORIAL_START:
			procRes = Process_FC_TUTORIAL_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TUTORIAL_COMPLETE:
			procRes = Process_FC_TUTORIAL_COMPLETE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TUTORIAL_END:
			procRes = Process_FC_TUTORIAL_END(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_TUTORIAL_WARP:
			procRes = Process_FC_TUTORIAL_WARP(pPacket, nLength, nBytesUsed);
			break;
//		case T_FC_OUTPOST_RESET_CHECK_START:
//			procRes = Process_FC_OUTPOST_RESET_CHECK_START(pPacket, nLength, nBytesUsed);
//			break;
		case T_FC_OUTPOST_RESET_START:
			procRes = Process_FC_OUTPOST_RESET_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_OUTPOST_NEXTWAR_INFO_REQUEST:
			procRes = Process_FC_OUTPOST_NEXTWAR_INFO_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_OUTPOST_NEXTWAR_SET_TIME:
			procRes = Process_FC_OUTPOST_NEXTWAR_SET_TIME(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_NOTICE_REQUEST:
			procRes = Process_FC_INFO_NOTICE_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_NOTICE_REG:
			procRes = Process_FC_INFO_NOTICE_REG(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_NOTICE_MODIFY:
			procRes = Process_FC_INFO_NOTICE_MODIFY(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_EXPEDIENCYFUND_REQUEST:
			procRes = Process_FC_INFO_EXPEDIENCYFUND_REQUEST(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_EXPEDIENCYFUND_PAYBACK:
			procRes = Process_FC_INFO_EXPEDIENCYFUND_PAYBACK(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD:	// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
			procRes = Process_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD:			// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
			procRes = Process_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_SECONDARYPASSWORD_LOCK:				// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
			procRes = Process_FC_INFO_SECONDARYPASSWORD_LOCK(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFO_GET_GUILDMARK:
			procRes = Process_FC_INFO_GET_GUILDMARK(pPacket, nLength, nBytesUsed);
			break;

		// 2007-12-27 by dhjin, 아레나 통합 -
		case T_FtoA_MFSINFO:
			procRes = Process_FtoA_MFSINFO(pPacket, nLength, nBytesUsed);
			break;	
		case T_FtoA_AUTH_CHARACTER_OK:
			procRes = Process_FtoA_AUTH_CHARACTER_OK(pPacket, nLength, nBytesUsed);
			break;			
		case T_FtoA_ARENA_TEAM_MATCHING_OK:
			procRes = Process_FtoA_ARENA_TEAM_MATCHING_OK(pPacket, nLength, nBytesUsed);
			break;	
			// 2012-12-18 by jhseol, 아레나 캐릭터 리셋 후 캐릭터 정보 다시 로딩하기.
		case T_FtoA_ARENA_CHARACTER_RESET_RELOAD:
			procRes = Process_FtoA_ARENA_CHARACTER_RESET_RELOAD(pPacket, nLength, nBytesUsed);
			break;
			// end 2012-12-18 by jhseol, 아레나 캐릭터 리셋 후 캐릭터 정보 다시 로딩하기.
		case T_FC_INFO_MSWARINFO_DISPLAY_OPTION:			// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 -
			procRes = Process_FC_INFO_MSWARINFO_DISPLAY_OPTION(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_MSWARINFO_RESULT:			// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 
			procRes = Process_FC_INFO_MSWARINFO_RESULT(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_SPWARINFO_RESULT:			// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 
			procRes = Process_FC_INFO_SPWARINFO_RESULT(pPacket, nLength, nBytesUsed);
			break;	

		//////////////////////////////////////////////////////////////////////////
		// 2008-04-29 by dhjin, EP3 편지 시스템 -
		case T_FC_CHAT_LETTER_REQUEST_TITLE:
			procRes = Process_FC_CHAT_LETTER_REQUEST_TITLE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_LETTER_READ:
			procRes = Process_FC_CHAT_LETTER_READ(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_LETTER_DELETE:
			procRes = Process_FC_CHAT_LETTER_DELETE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_LETTER_SEND:
			procRes = Process_FC_CHAT_LETTER_SEND(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_ALLLETTER_REQUEST_TITLE:
			procRes = Process_FC_CHAT_ALLLETTER_REQUEST_TITLE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_ALLLETTER_READ:
			procRes = Process_FC_CHAT_ALLLETTER_READ(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_ALLLETTER_DELETE:
			procRes = Process_FC_CHAT_ALLLETTER_DELETE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHAT_ALLLETTER_SEND:
			procRes = Process_FC_CHAT_ALLLETTER_SEND(pPacket, nLength, nBytesUsed);
			break;
		//////////////////////////////////////////////////////////////////////////
		// 2008-12-08 by dhjin, 미션마스터
		case T_FC_QUEST_REQUEST_MISSIONMASTER_HELP:
			procRes = Process_FC_QUEST_REQUEST_MISSIONMASTER_HELP(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_MISSIONMASTER_HELP_INVITE:
			procRes = Process_FC_QUEST_MISSIONMASTER_HELP_INVITE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_QUEST_MISSIONMASTER_HELP_REJECT:
			procRes = Process_FC_QUEST_MISSIONMASTER_HELP_REJECT(pPacket, nLength, nBytesUsed);
			break;
		//////////////////////////////////////////////////////////////////////////
		// 2009-01-12 by dhjin, 선전 포고 -	
		case T_FC_INFO_DECLARATION_MSWAR_INFO:
			procRes = Process_FC_INFO_DECLARATION_MSWAR_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_DECLARATION_MSWAR_SET:
			procRes = Process_FC_INFO_DECLARATION_MSWAR_SET(pPacket, nLength, nBytesUsed);
			break;

		case T_FC_INFO_WRK_GET_SERVICE_INFO:	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
			procRes = Process_FC_INFO_WRK_GET_SERVICE_INFO(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_WRK_GET_RANKER_LIST:		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
			procRes = Process_FC_INFO_WRK_GET_RANKER_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFO_WRK_GET_SELF_RANKING:	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
			procRes = Process_FC_INFO_WRK_GET_SELF_RANKING(pPacket, nLength, nBytesUsed);
			break;

		case T_FC_INFINITY_MODE_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 리스트 요청, C -> F
			procRes = Process_FC_INFINITY_MODE_LIST(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFINITY_READY_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 리스트 요청, C -> F
			procRes = Process_FC_INFINITY_READY_LIST(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_INFINITY_CREATE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 생성 요청, C -> F
			procRes = Process_FC_INFINITY_CREATE(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_JOIN:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 가입 요청, C -> F
			procRes = Process_FC_INFINITY_JOIN(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 방장에거 가입자 승인 여부 요청, C -> F
			procRes = Process_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_MEMBER_INFO_LIST:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맴버 정보, C -> F
			procRes = Process_FC_INFINITY_MEMBER_INFO_LIST(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_CHANGE_MASTER:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 마스터 변경, C -> F
			procRes = Process_FC_INFINITY_CHANGE_MASTER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_LEAVE:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 탈퇴, C -> F
			procRes = Process_FC_INFINITY_LEAVE(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_BAN:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 추방, C -> F
			procRes = Process_FC_INFINITY_BAN(pPacket, nLength, nBytesUsed);
			break;
		case T_FtoA_INFINITY_IMPUTE_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 귀속 정보.
			procRes = Process_FtoA_INFINITY_IMPUTE_LIST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_READY:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 준비 버튼 누름, C -> F
			procRes = Process_FC_INFINITY_READY(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_READY_CANCEL:						// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 준비취소 버튼 누름, C -> F
			procRes = Process_FC_INFINITY_READY_CANCEL(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_START:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 시작 버튼 누름(인피 시작), C -> F
			procRes = Process_FC_INFINITY_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FtoA_INFINITY_START_OK:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 시작 MainFieldSever준비 완료 전송, MFS -> AFS
			procRes = Process_FtoA_INFINITY_START_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_MAP_LOADED:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵 로딩 종료, C -> F
			procRes = Process_FC_INFINITY_MAP_LOADED(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_FIN_OK:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 종료 확인 후 마을(Main서버로 돌아감), C -> F
			procRes = Process_FC_INFINITY_FIN_OK(pPacket, nLength, nBytesUsed);
			break;
		case T_FtoA_INFINITY_READY_FINISH_MAINSVR_START:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Main서버로 돌아갈 준비가 완료 됨, MFS -> AFS
			procRes = Process_FtoA_INFINITY_READY_FINISH_MAINSVR_START(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_TENDER_PUT_IN_TENDER:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 유저 Tender 버튼 누름
			procRes = Process_FC_INFINITY_TENDER_PUT_IN_TENDER(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_SHOP_INFINITY_BUY_ITEM:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 상점
			procRes = Process_FC_SHOP_INFINITY_BUY_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_JOIN_CANCEL:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 입장 취소
			procRes = Process_FC_INFINITY_JOIN_CANCEL(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_INFINITY_RESTART_BY_DISCONNECT:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
			procRes = Process_FC_INFINITY_RESTART_BY_DISCONNECT(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
			procRes = Process_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT(pPacket, nLength, nBytesUsed);
			break;
		case T_FtoA_INFINITY_START_CHECK_ACK:					// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
			procRes = Process_FtoA_INFINITY_START_CHECK_ACK(pPacket, nLength, nBytesUsed);
			break;
		case T_FtoA_UPDATE_ITEM_NOTI:							// 2010-03-31 by dhjin, 인피니티 입장 캐쉬 아이템 구현 - 
			procRes = Process_FtoA_UPDATE_ITEM_NOTI(pPacket, nLength, nBytesUsed);
			break;

		case T_FC_ITEM_USE_INVOKING_WEAR_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템 사용
			procRes = Process_FC_ITEM_USE_INVOKING_WEAR_ITEM(pPacket, nLength, nBytesUsed);
			break;	
		case T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템 지속 시간 완료
			procRes = Process_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_ITEM_END_COOLINGTIME_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 쿨타임 종료
			procRes = Process_FC_ITEM_END_COOLINGTIME_ITEM(pPacket, nLength, nBytesUsed);
			break;		
		case T_FC_ITEM_GET_COOLINGTIME_INFO:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 쿨타임 정보 요청 C->F
			procRes = Process_FC_ITEM_GET_COOLINGTIME_INFO(pPacket, nLength, nBytesUsed);
			break;

		// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
		case T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL :			// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
			procRes = Process_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL( pPacket , nLength , nBytesUsed );
			break;
		// End 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )

		// 2010. 07. 27 by hsLee 인피니티 2차 거점 방어 시네마 연출 스킵 처리.
		case T_FC_INFINITY_SKIP_ENDING_CINEMA :
			procRes = Process_FC_INFINITY_SKIP_ENDINGCINEMA ( pPacket , nLength , nBytesUsed );
			break;
		// End 2010. 07. 27 by hsLee 인피니티 2차 거점 방어 시네마 연출 스킵 처리.

		// 2010-08-31 by shcho&jskim 아이템용해 시스템 - 용해 시스템 패킷 처리
		case T_FC_DISSOLVED_ITEM :
			procRes = Process_FC_DISSOLVED_ITEM( pPacket , nLength , nBytesUsed );
			break;
		// END 2010-08-31 by shcho&jskim 아이템용해 시스템 - 용해 시스템 패킷 처리

		/////////////////////////////////////////////////////////////
		// start 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현

		case T_FC_ITEM_PET_SET_NAME :
			procRes = Process_FC_ITEM_PET_SET_NAME(pPacket , nLength , nBytesUsed);
			break;
		case T_FC_ITEM_PET_SET_EXP_RATIO :
			procRes = Process_FC_ITEM_PET_SET_EXP_RATIO(pPacket , nLength , nBytesUsed);
			break;

		case T_FC_ITEM_PET_SET_SOCKET :
			procRes = Process_FC_ITEM_PET_SET_SOCKET(pPacket , nLength , nBytesUsed);
			break;
		case T_FC_ITEM_PET_SET_KIT_SLOT :
			procRes = Process_FC_ITEM_PET_SET_KIT_SLOT(pPacket , nLength , nBytesUsed);
			break;
		case T_FC_ITEM_PET_SET_AUTOSKILL_SLOT :
			procRes = Process_FC_ITEM_PET_SET_AUTOSKILL_SLOT(pPacket , nLength , nBytesUsed);
			break;

		// end 2011-08-22 by hskim, 파트너 시스템 2차 - 기능 구현
		//////////////////////////////////////////////////////////		

		// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
		case T_FI_GUILD_BONUS_EXP_RATE:
			procRes = Process_FI_GUILD_BOUNUEXP_RATE(pPacket , nLength , nBytesUsed);
			break;
		// end 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

		// 2012-10-17 by hskim, XignCode작업
		case T_FC_CHARACTER_XIGNCODE_C_ACK_PACKET:
			procRes = Process_FC_CHARACTER_XIGNCODE_C_ACK_PACKET(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_CHARACTER_XIGNCODE_C_ACK_CODE:
			procRes = Process_FC_CHARACTER_XIGNCODE_C_ACK_CODE(pPacket, nLength, nBytesUsed);
			break;
		// end 2012-10-17 by hskim, XignCode작업

			// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 패킷 받기
		case T_FC_COLLECTION_SHAPE_CHANGE:
			procRes = Process_FC_COLLECTION_SHAPE_CHANGE(pPacket, nLength, nBytesUsed);
			break;
			// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 패킷 받기

			// 2014-01-27 by bckim, 버그 트랩
		case T_FC_BUGTRAP_ACCEPT:
			procRes = Process_FC_BUGTRAP_ACCEPT(pPacket, nLength, nBytesUsed);
			break;
			// End. 2014-01-27 by bckim, 버그 트랩

			// 2013-11-25 by jhseol&bckim, 거래소 - 패킷 리시브 루틴
		case T_FC_MARKET_BASE_INFO_REQUEST:
			procRes = Process_FC_MARKET_BASE_INFO_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_SEARCH_REQUEST:
			procRes = Process_FC_MARKET_SEARCH_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_PAGING_REQUEST:
			procRes = Process_FC_MARKET_PAGING_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_SORT_REQUEST:
			procRes = Process_FC_MARKET_SORT_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_BUY_REQUEST:
			procRes = Process_FC_MARKET_BUY_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_SELL_REQUEST:
			procRes = Process_FC_MARKET_SELL_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_GET_REQUEST:
			procRes = Process_FC_MARKET_GET_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_MARKET_MY_LIST_REQUEST:
			procRes = Process_FC_MARKET_MY_LIST_REQUEST(pPacket, nLength, nBytesUsed);
			break;
			// end 2013-11-25 by jhseol&bckim, 거래소 - 패킷 리시브 루틴

			// 2014-01-03 by jhseol&bckim, 파괴경매장 - 패킷 리시브 루틴
		case T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST:
			procRes = Process_FC_DESTROY_AUCTION_BASE_INFO_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_DESTROY_AUCTION_TENDER_REQUEST:
			procRes = Process_FC_DESTROY_AUCTION_TENDER_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_DESTROY_AUCTION_GET_REQUEST:
			procRes = Process_FC_DESTROY_AUCTION_GET_REQUEST(pPacket, nLength, nBytesUsed);
			break;
		case T_FC_DESTROY_AUCTION_MY_LIST_REQUEST:
			procRes = Process_FC_DESTROY_AUCTION_MY_LIST_REQUEST(pPacket, nLength, nBytesUsed);
			break;
			// end 2014-01-03 by jhseol&bckim, 파괴경매장 - 패킷 리시브 루틴
		default:
			{
				// Protocol Error 처리(Close 처리함)
				// - Client로 부터 받은 Field Type이 유효하지 않다
				// Error Code : ERR_PROTOCOL_INVALID_PROTOCOL_TYPE
				SendErrorMessage(T_FIELD_IOCP, ERR_PROTOCOL_INVALID_PROTOCOL_TYPE, 0, 0, NULL, TRUE);

				char	szSystemLog[256];
				sprintf(szSystemLog, "[Error] CFieldIOCPSocket::OnRecvdPacketFieldServer2 invalid protocol type, RecvType[%s(%#04X)], PrevType[%s(%#04X)], %s\r\n",
									GetProtocolTypeString(nRecvType), nRecvType,
									GetProtocolTypeString(m_LastRecvedMsgType), m_LastRecvedMsgType,
									GetCharacterString(&m_character, string())
									);
				g_pFieldGlobal->WriteSystemLog(szSystemLog);
				DBGOUT(szSystemLog);
				return FALSE;
			}
		}	// end switch

		// 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
		if(m_bArenaNoDamage)
		{
			//if ( !(m_character.Race & RACE_ACCOUNT_TYPE_MASK) )
			{
				ATUM_DATE_TIME curTime;
				curTime.SetCurrentDateTime(FALSE);
				curTime.AddDateTime(0,0,0,0,0,-RESPAWN_UNBEATABLE_TIME_BY_SECOND);
				if(curTime > m_atimeArenaNoDamage)
				{
					m_bArenaNoDamage = FALSE;
					SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0108);
				}
			}
		}
		// end 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간

		// 이전 메세지 저장
		prevMsgType = nRecvType;
		m_LastRecvedMsgType = nRecvType;	// 2008-03-06 by cmkwon, IOCPSocket 에 마지막 메시지 타입 체크 시스템 추가 - 

		// MSG 결과 처리
		if (procRes == RES_BREAK)
		{
			// 경미한 에러들. 연결을 끊지 않는다.
			// do nothing, 그냥 남아있는 다음 packet을 처리한다
		}
		else if (procRes == RES_PACKET_ERROR)
		{
			// 패킷이 손상된 경우. 남은 packet을 처리하지 않고 바로 리턴한다. 서버간 연결에만 사용.
			return TRUE;
		}
		else if (procRes == RES_RETURN_TRUE)
		{
			// 정상
			// do nothing, 그냥 남아있는 다음 packet을 처리한다
		}
		else if (procRes == RES_RETURN_FALSE)
		{
			return FALSE;
		}

	}	// end while

	return TRUE;
}

void CFieldIOCPSocket::OnConnect(void)
{
	char szSystemLog[256];
	sprintf(szSystemLog, "Socket Connect SocketIndex[%3d] PeerIP[%15s] Port[%4d]\r\n",
		this->GetClientArrayIndex(), m_szPeerIP, m_nPeerPort);
	g_pFieldGlobal->WriteSystemLog(szSystemLog);
	DBGOUT(szSystemLog);

	this->SetClientState(CS_CONNECTED);
	m_PeerSocketType			= ST_INVALID_TYPE;
	m_dwConnectTime				= ms_pFieldIOCP->GetCurrentServerTime();
	m_bFieldServerChangeFlag	= FALSE;
	m_pCurrentFieldMapChannel	= NULL;

	m_GalaNetAccountIDNum		= 0;			// 2006-06-01 by cmkwon
	m_AccountRegisteredDate.Reset();
	MEMSET_ZERO(m_AccountPasswordFromDB, SIZE_MAX_PASSWORD_MD5_STRING);
	m_nGameContinueTimeInSecondOfToday	= 0;		// 2006-11-15 by cmkwon
	m_nGameContinueTimeInSecondOfToday4Viet	= 0;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - 소켓 연결시 초기화
	m_atimeLastGameEndDate.Reset();					// 2006-11-15 by cmkwon
	m_atmeGameStartTime.SetCurrentDateTime();		// 2006-11-15 by cmkwon


	m_Security_bCheckVersion		= FALSE;	// 2006-06-05 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//	MEMSET_ZERO(m_Security_pbyGuidReqInfo, SIZEOF_GUIDREQINFO);
//	
//	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 
//	//m_Security_plCRCInfo			= NULL;
//	MEMSET_ZERO(&m_Security_ClientContext, sizeof(m_Security_ClientContext));	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 

	m_Security_bSendCRCReqMsg		= FALSE;	// 2006-06-05 by cmkwon
	m_dwSetTickSecurity_bSendCRCReqMsg = timeGetTime();		// 2006-10-21 by cmkwon
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
//	MEMSET_ZERO(m_Security_pbyReqInfo, SIZEOF_REQINFO);
//	// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 'ANTICPSVR_CHECK_ENGINE_FILE' 옵션이 없어지고 'ANTICPSVR_CHECK_NANOENGINE_FILE'로 옵션 변경
//	//m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_ENGINE_FILE;		// 2007-04-02 by cmkwon, ANTICPSVR_CHECK_ENGINE_FILE 추가함
//	m_Security_ulOption				= ANTICPSVR_CHECK_ALL|ANTICPSVR_CHECK_NANOENGINE_FILE;	
	m_hAhnHSClientHandle			= ANTICPX_INVALID_HANDLE_VALUE;		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 

	m_bInitSecurityClient			= FALSE;		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 

	m_nPCBangUID					= 0;		// 2007-01-23 by dhjin, PCBangUID 초기화

	///////////////////////////////////////////////////////////////////////////////
	// 2012-10-05 by jhseol, NPlay pc방 모듈 - NPlay 모듈이면 pc방 채크를 여기서 하지 않는다.
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
	// 아무것도 안함
#else
	m_bIsPCBangClient				= g_pFieldGlobal->m_pPCBangIPManager->IsPCBangIPCheck(this->GetPeerIP(), &m_nPCBangUID);	// 2006-08-22 by dhjin, 피시방 IP 여부 체크.
#endif
	// end 2012-10-05 by jhseol, NPlay pc방 모듈 - NPlay 모듈이면 pc방 채크를 여기서 하지 않는다.

	m_nDeletedPacketCount		= 0;	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 임시용

	m_bXignCodeReceivedReqScanInitOK	= FALSE;	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	m_hXignCodeAntiCheatHandle			= NULL;		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 

	// 2012-10-17 by bhsohn XignCode작업
	m_bXignCodeClient = FALSE;			
	// END 2012-10-17 by bhsohn XignCode작업

	CIOCPSocket::OnConnect();
}

void CFieldIOCPSocket::OnClose(int reason)
{
	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	// 2008-03-24 by cmkwon, 시스템 로그 수정
	if(FALSE == IsValidCharacter(FALSE))
	{
		// 2009-03-19 by cmkwon, 시스템 로그 추가 - FieldServer, SocketType 정보 추가
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "Socket Closed  Client(%15s:%4d) SocketType(%d) |SockIdx(%4d)| MaxWriteBufCounts[%4d] ==> reason %d[%#08X], deletedPacketCount(%d)\r\n",
			m_szPeerIP, m_nPeerPort, m_PeerSocketType, this->GetClientArrayIndex(), m_nMaxWriteBufCounts, reason, reason, m_nDeletedPacketCount);
	}
	else
	{
		// 2009-03-19 by cmkwon, 시스템 로그 추가 - FieldServer, SocketType 정보 추가
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "Socket Closed  Client(%15s:%4d) SocketType(%d) |%s| MaxWriteBufCounts[%4d] ==> reason %d[%#08X], deletedPacketCount(%d)\r\n",
			m_szPeerIP, m_nPeerPort, m_PeerSocketType, GetCharacterString(GetCharacter(), string()), m_nMaxWriteBufCounts, reason, reason, m_nDeletedPacketCount);
	}

	
	// 2014-01-27 by bckim, 버그 트랩
#ifdef	SC_BUGTRAP_BCKIM_SSJUNG
	if( ST_CLIENT_TYPE == m_PeerSocketType  )
	{		
		if( reason != 0x00006 )
		{		
			if( this->m_bExceptionUser )
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, " $$$$$$$$$$$$$$ OnClose(입셉션!!) $$$$$$$$$$$$$$ (%x)\r\n",reason);
				CAtumLogSender::SendLogBugTrap(this,CLOSE_TYPE_EXCEPTIONAL);
			}
			else
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, " $$$$$$$$$$$$$$ OnClose(비정상!!) $$$$$$$$$$$$$$ (%x)\r\n",reason);
				CAtumLogSender::SendLogBugTrap(this,CLOSE_TYPE_ABMORMAL);
			}	
		}
		else
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, " $$$$$$$$$$$$$$ OnClose(정상!!) $$$$$$$$$$$$$$ (%x)\r\n",reason);
			CAtumLogSender::SendLogBugTrap(this,CLOSE_TYPE_NORMAL);
		}
	}
#endif
	// End. 2014-01-27 by bckim, 버그 트랩


// 2009-03-26 by cmkwon, 시스템 로그 추가 - 버그 수정, 아래에서 소켓 종료와 같이 처리
// 	if (m_PeerSocketType == ST_NPC_SERVER)
// 	{
// 		ms_pFieldIOCP->m_pNPCTCPSocket = NULL;
// 	}

	// send MSG_FP_CONNECT_NOTIFY_CLOSE
	if (m_PeerSocketType == ST_CLIENT_TYPE)		
	{
		///////////////////////////////////////////////////////////////////////////////
		// Client 이중 접속 데이타 제거
		ms_pFieldIOCP->m_mtsetAccountName.deleteLock(m_character.AccountName);

		if(GetClientState() > CS_CONNECTED)
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2012-10-05 by jhseol, NPlay pc방 모듈 - 유저 소캣의 연결이 끊어지면 NPlay 과금중단 요청과 NPlay 리스트 삭제 요청을 보낸다
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
			if( FALSE == g_pFieldGlobal->IsArenaServer() )	// 아레나 서버가 아닐때
			{
				INIT_MSG_WITH_BUFFER(MSG_FP_PCBANG_USER_GAME_END, T_FP_PCBANG_USER_GAME_END, msgGAME_END, msgGAME_ENDBuf);
				STRNCPY_MEMSET(msgGAME_END->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
				STRNCPY_MEMSET(msgGAME_END->ServerGroupName, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);
				ms_pFieldIOCP->m_pPreWinSocket->Write(msgGAME_ENDBuf, MSG_SIZE(MSG_FP_PCBANG_USER_GAME_END));
				mt_auto_lock mtB(&ms_pFieldIOCP->m_mapAccountName);
				char tmAccountName[SIZE_MAX_ACCOUNT_NAME];
				ms_pFieldIOCP->m_mapAccountName.deleteLock(GGetLowerCase(tmAccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME));
			}
#endif
			// end 2012-10-05 by jhseol, NPlay pc방 모듈 - 유저 소캣의 연결이 끊어지면 NPlay 과금중단 요청과 NPlay 리스트 삭제 요청을 보낸다

			// check: condition을 정확하게 하기...
			//if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK) == FALSE && m_bNotifyCloseFlag)

			// 2007-11-06 by cmkwon, 체크 필요 없는 루틴 이였음
			//if (m_bNotifyCloseFlag)
			// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - 아래와 같이 인증이된 상태일때에만 처리
			if(this->GetPreServerAuthenticated())
			{
				BYTE		SendBuf[SIZE_MAX_PACKET];

				memset(SendBuf, 0x00, SIZE_MAX_PACKET);
				*(MessageType_t*)SendBuf = T_FP_CONNECT_NOTIFY_CLOSE;
				MSG_FP_CONNECT_NOTIFY_CLOSE *msgNotifyClose = (MSG_FP_CONNECT_NOTIFY_CLOSE*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
				STRNCPY_MEMSET(msgNotifyClose->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);

				ms_pFieldIOCP->m_pPreWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FP_CONNECT_NOTIFY_CLOSE));

				this->SetPreServerAuthenticated(FALSE, TRUE);	// 2007-11-06 by cmkwon, 게임 로그 DB 서버 따로 구축하기 - 게임서버 로그인/로그아웃 처리
				
				// start 2012-10-08 by khkim, GLog 
				// LogOut 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 (일반유저만 기록)	
				{
					MSG_FL_LOG_ACCOUNTCONNECT LogAccountParameter;
					LogAccountParameter.LogType			= GLOG_AC_LT_LOGOUT; 
					LogAccountParameter.UserSerial		= m_character.AccountUniqueNumber;
					LogAccountParameter.IP				= this->GetPeerIP4();
					LogAccountParameter.GameServerID	= g_pFieldGlobal->GetMGameServerID();
					CAtumLogSender::SendLogAccountConnect(&LogAccountParameter);
				}
				// end 2012-10-08 by khkim, GLog

				CAtumLogSender::SendLogMessageLOGOUT(this);	// send log
			}

			///////////////////////////////////////////////////////////////////////
			// 종료 루틴 처리
			this->CharacterGameEndRoutine();
		}
		
		///////////////////////////////////////////////////////////////////////////////
		// 프리미엄 카드 정보를 초기화 한다
		this->m_ItemManager.ResetPremiumCardInfo();
	}

	if (m_PeerSocketType == ST_MONITOR_SERVER)
	{
		ms_pFieldIOCP->DeleteMonitorIOCPSocketPtr(this);
	}

	if(m_PeerSocketType == ST_ADMIN_TOOL)
	{
		ms_pFieldIOCP->DeleteMonitorIOCPSocketPtr(this);
	}

	if (FALSE == m_bUDPFlag							// 2009-03-26 by cmkwon, 시스템 로그 추가 - 버그 수정, TCP 채널 일때에만 처리 해야함. UDP 채널을 처리 필요 없음
		&& m_PeerSocketType == ST_NPC_SERVER)
	{
		ms_pFieldIOCP->m_pNPCTCPSocket = NULL;		// 2009-03-26 by cmkwon, 시스템 로그 추가 - 버그 수정, 위에서 여기로 옮김.
		
		ms_pFieldIOCP->CloseUDPPortForOtherServer();
	}

	// member 변수 초기화
	ResetAllVariables(RVT_ON_CLOSE);

	CIOCPSocket::OnClose(30);
}

BOOL CFieldIOCPSocket::OnError(int errCode)
{
	/*
	switch(errCode)
	{
	case ERROR_PORT_UNREACHABLE:
		{	// UDP 전송일때 상대방의 Port가 열려있지 않을때 발생하는 에러
			// Monster 정보를 모두 초기화, Read를 다시 한번 호출

			char szSystemLog[256];
			sprintf(szSystemLog, "UDP Write Error SocketIndex[%3d] ==> Error[ERROR_PORT_UNREACHABLE]\r\n", this->GetClientArrayIndex());
			g_pFieldGlobal->WriteSystemLog(szSystemLog);
			DBGOUT(szSystemLog);

			if(m_pCurrentFieldMapChannel)
			{
				m_pCurrentFieldMapChannel->FieldDeleteAllMonster();
			}
			this->SetRecvOperationFlag(FALSE);
			this->Read();
		}
		return TRUE;
	}
	//*/
	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			CHARACTER *CFieldIOCPSocket::GetCharacterCacheNoLock(UID32_t i_charUID)
/// \brief		
/// \author		cmkwon
/// \date		2006-09-28 ~ 2006-09-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
CHARACTER *CFieldIOCPSocket::GetCharacterCacheNoLock(UID32_t i_charUID)
{
	for(int i=0; i < m_mtvectCharacterCache.size(); i++)
	{
		if(i_charUID == m_mtvectCharacterCache[i].CharacterUniqueNumber)
		{
			return &m_mtvectCharacterCache[i];
		}
	}
	
	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::UpdateCharacterCacheLock(UID32_t i_charUID, CHARACTER *i_pCharac)
/// \brief		
/// \author		cmkwon
/// \date		2006-09-28 ~ 2006-09-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::UpdateCharacterCacheLock(UID32_t i_charUID, CHARACTER *i_pCharac)
{
	mt_auto_lock mtA(&m_mtvectCharacterCache);
	CHARACTER *pCharac = GetCharacterCacheNoLock(i_charUID);
	if(NULL == pCharac)
	{
		return FALSE;
	}

	*pCharac		= *i_pCharac;
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertEventItem(int i_itemNum, int i_nCnts, BYTE i_nItemUpdateType, int i_nPrefixCodeNum/* = 0*/, int i_nSuffixCodeNum/* = 0*/)
/// \brief		// 2007-07-25 by cmkwon, 이벤트 아이템의 접두/접미 레어 설정 - 인자 추가(, int i_nPrefixCodeNum/*=0*/, int i_nSuffixCodeNum/*=0*/)
/// \author		cmkwon
/// \date		2006-10-09 ~ 2006-10-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertEventItem(int i_itemNum, int i_nCnts, BYTE i_nItemUpdateType, int i_nPrefixCodeNum/*=0*/, int i_nSuffixCodeNum/*=0*/, BYTE i_enumStorage/*=ITEM_IN_CHARACTER*/)	// 2013-04-22 by jhseol, 아이템 이벤트 - 서브타입 추가구조 시스템 보안
{
	mt_auto_lock mtA(&m_ItemManager.m_mapItemGeneral);
	// 2013-04-22 by jhseol, 아이템 이벤트 - 서브타입 추가구조 시스템 보안
	BOOL bPermissionArenaState = FALSE;
#ifdef S_ITEM_EVENT_SUB_TYPE_JHSEOL
	if ( ITEM_IN_STORE == i_enumStorage )
	{
		bPermissionArenaState = TRUE;
	}
#endif
	// end 2013-04-22 by jhseol, 아이템 이벤트 - 서브타입 추가구조 시스템 보안
	
	if(FALSE == IsValidCharacter(FALSE, bPermissionArenaState))	// 2013-04-22 by jhseol, 아이템 이벤트 - 서브타입 추가구조 시스템 보안
	{
		return FALSE;
	}

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(i_itemNum);
	if(NULL == pItemInfo)
	{
		return FALSE;
	}

// 2008-10-20 by cmkwon, 멥버쉽 아이템 체크 ItemAttribute 로 처리 - 
//	if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM)
//		&& pItemInfo->SummonMonster	== CASH_ITEMKIND_PREMIUM_CARD)
	if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
	{// 2006-10-09 by cmkwon, 멤버쉽 서비스 아이템

		///////////////////////////////////////////////////////////////////////////////
		// 프리미엄 아이템을 추가
		Err_t nRetedErr = this->m_ItemManager.CashInsertPremiumCard(pItemInfo);
		if(ERR_NO_ERROR != nRetedErr)
		{
			return FALSE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-01-11 by cmkwon, 로그를 남긴다
		ITEM_GENERAL tmItemG(pItemInfo);
		tmItemG.UniqueNumber			= m_ItemManager.m_cashPremiumCardInfo.n64UniqueNumber10;
		tmItemG.Possess					= m_character.CharacterUniqueNumber;
		tmItemG.CurrentCount			= m_ItemManager.m_cashPremiumCardInfo.atumTimeExpireTime.GetTimeDiffToCurrentTimeInSeconds();
		CAtumLogSender::SendLogMessageITEMGetItemByItemEvent(this, &tmItemG, pItemInfo->Time*24*60*60);	// 2007-01-11 by cmkwon
		return TRUE;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-09 by cmkwon, 일반 아이템
	return m_ItemManager.InsertItemBaseByItemNum(i_itemNum, i_nCnts, i_nItemUpdateType, FALSE, i_enumStorage, TRUE, TRUE, i_nPrefixCodeNum, i_nSuffixCodeNum);	// 2013-04-22 by jhseol, 아이템 이벤트 - 서브타입 추가구조 시스템 보안
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsInvisibleCharacter(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-08 ~ 2006-11-08
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsInvisibleCharacter(void)
{
	return m_bIsInvisibleCharacter;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			int	CFieldIOCPSocket::GetCurGameContinueTimeInSecondOfToday(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-16 ~ 2006-11-16
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
int	CFieldIOCPSocket::GetCurGameContinueTimeInSecondOfToday(void)
{
	ATUM_DATE_TIME atCur(TRUE);

	if(this->m_atmeGameStartTime.Year != atCur.Year
		|| this->m_atmeGameStartTime.Month != atCur.Month
		|| this->m_atmeGameStartTime.Day != atCur.Day)
	{// 2006-11-16 by cmkwon, 게임이 시작된 후 날짜가 변경되었다
		this->m_nGameContinueTimeInSecondOfToday	= 0;				// 2006-11-15 by cmkwon, 게임 지속시간 초기화
		m_nGameContinueTimeInSecondOfToday4Viet		= 0;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - CFieldIOCPSocket::GetCurGameContinueTimeInSecondOfToday() 에서 초기화

		this->m_atmeGameStartTime.Year		= atCur.Year;
		this->m_atmeGameStartTime.Month		= atCur.Month;
		this->m_atmeGameStartTime.Day		= atCur.Day;
		this->m_atmeGameStartTime.Hour		= 0;
		this->m_atmeGameStartTime.Minute	= 0;
		this->m_atmeGameStartTime.Second	= 1;
	}
	
	return this->m_nGameContinueTimeInSecondOfToday + atCur.GetTimeDiffTimeInSeconds(this->m_atmeGameStartTime);	// 2006-11-15 by cmkwon, 오늘 하루 게임 시속 시간 계산(단위:초)
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::GetPlayTimeInfoString(char *o_szPlayTimeString)
/// \brief		
/// \author		cmkwon
/// \date		2006-11-17 ~ 2006-11-17
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::GetPlayTimeInfoString(char *o_szPlayTimeString)
{
///////////////////////////////////////////////////////////////////////////////
// 2007-06-14 by cmkwon, 게임 지속 시간 제한 기본 시스템으로 수정 - 아래와 같이 수정
//	int nGameContinueTimeOfToday = this->GetCurGameContinueTimeInSecondOfToday();
//	int nSecond = nGameContinueTimeOfToday%60;
//	int nMinute	= (nGameContinueTimeOfToday/60)%60;
//	int nHour	= nGameContinueTimeOfToday/3600;
//	int nExpPercent = 100;
//
//	if(ms_pFieldIOCP->m_bUseTimeLimiteSysteOfToday)
//	{
//		if(nHour >= 5)
//		{
//			nExpPercent		= 0;
//		}
//		else if(nHour >= 3)
//		{
//			nExpPercent		= 50;
//		}
//	}
//
//	// 2006-11-23 by cmkwon, SPI도 추가함
//	sprintf(o_szPlayTimeString, "%2dh:%2dm:%2ds, %2d%%(EXP) %2d%%(SPI)", nHour, nMinute, nSecond, nExpPercent, nExpPercent);
	

	int		nGameContinueTimeOfToday = this->GetCurGameContinueTimeInSecondOfToday();
	int		nSecond = nGameContinueTimeOfToday%60;
	int		nMinute	= (nGameContinueTimeOfToday/60)%60;
	int		nHour	= nGameContinueTimeOfToday/3600;
	int		nApplyPercent	= 100;

	float	fApplyRate		= 0.0f;
	BOOL	bRestriction	= this->GPGetApplyRateByGamePlayingTime(&fApplyRate);
	if(bRestriction)
	{
		if(0.0f >= fApplyRate)
		{
			nApplyPercent = 0;
		}
		else
		{
			nApplyPercent *= fApplyRate;
		}
	}

	sprintf(o_szPlayTimeString, "%2dh:%2dm:%2ds, %2d%%(EXP) %2d%%(SPI)", nHour, nMinute, nSecond, nApplyPercent, nApplyPercent);	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GPGetApplyRateByGamePlayingTime(float *o_pfRetRate)
/// \brief		// 2007-06-14 by cmkwon, 게임 지속 시간 제한 기본 시스템으로 수정
///				// 2007-08-13 by cmkwon, 인자명 수정(o_pfRetRate<--i_pfRetRate)
/// \author		cmkwon
/// \date		2007-06-14 ~ 2007-06-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GPGetApplyRateByGamePlayingTime(float *o_pfRetRate)
{
	*o_pfRetRate = 1.0f;

	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_VIETNAMESE:
		{
			int nGameContinueTimeOfToday = this->GetCurGameContinueTimeInSecondOfToday();
			if(TERM_GAME_PLAYTIME_LIMIT_FIRST_SEC > nGameContinueTimeOfToday)
			{// 2007-06-14 by cmkwon, 적용하지 않아도 된다.
				return FALSE;
			}

			if(TERM_GAME_PLAYTIME_LIMIT_LAST_SEC > nGameContinueTimeOfToday)
			{
				*o_pfRetRate = 0.5f;
			}
			else
			{
				*o_pfRetRate = 0.0f;
			}
		}
		break;
	case LANGUAGE_TYPE_CHINESE:
		{
			// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 미성년자 체크 추가
			if(this->IsAdultsUser())
			{// 성년은 제한이 없다

				return FALSE;
			}

			int nGameContinueTimeOfToday = this->GetCurGameContinueTimeInSecondOfToday();
			if(TERM_GAME_PLAYTIME_LIMIT_FIRST_SEC > nGameContinueTimeOfToday)
			{// 2007-06-14 by cmkwon, 적용하지 않아도 된다.
				return FALSE;
			}

			if(TERM_GAME_PLAYTIME_LIMIT_LAST_SEC > nGameContinueTimeOfToday)
			{
				*o_pfRetRate = 0.5f;
			}
			else
			{
				*o_pfRetRate = 0.0f;
			}
		}
		break;
	default:
		{
			return FALSE;
		}
	}
	
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::GPInitGameStartTime(void)
/// \brief		// 2007-06-19 by cmkwon, 게임 지속 시간 수정 - 중국 5시간 후 접속 처리
/// \author		cmkwon
/// \date		2007-06-19 ~ 2007-06-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::GPInitGameStartTime(void)
{
	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
		m_nGameContinueTimeInSecondOfToday4Viet	= 0;	// 2007-10-23 by cmkwon, 베트남 게임 지속 시간 시스템  수정 - CFieldIOCPSocket::GPInitGameStartTime() 에서 초기화
	}
	
	switch(g_pFieldGlobal->GetLanguageType())
	{
	case LANGUAGE_TYPE_CHINESE:
		{
			int nGapSec = m_atmeGameStartTime.GetTimeDiffTimeInSeconds(m_atimeLastGameEndDate);
			if(TERM_GAME_PLAYTIME_LIMIT_LAST_SEC <= nGapSec)
			{// 2007-06-19 by cmkwon, 게임을 종료한지 5시간이 경과되었다면 오늘하루 접속 시간을 초기화 한다.
				m_nGameContinueTimeInSecondOfToday		= 0;		// 2007-06-19 by cmkwon
			}
		}
		break;
	}

	return TRUE;
}

// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 미성년자 관련
//////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsAdultsUser(void)
/// \brief		// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 미성년자 관련
/// \author		cmkwon
/// \date		2007-06-27 ~ 2007-06-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsAdultsUser(void)
{
	return m_bIsAdult;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::SetAdults(ATUM_DATE_TIME i_atBirthday)
/// \brief		// 2007-06-27 by cmkwon, 중국 방심취 시스템 수정 - 미성년자 관련
/// \author		cmkwon
/// \date		2007-06-29 ~ 2007-06-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::SetAdults(ATUM_DATE_TIME i_atBirthday)
{
	ATUM_DATE_TIME atCur(TRUE);
	if(ADULT_YEARS < atCur.Year - i_atBirthday.Year)
	{
		m_bIsAdult		= TRUE;
	}
	else if(ADULT_YEARS == atCur.Year - i_atBirthday.Year)
	{
		if(atCur.Month > i_atBirthday.Month 
			|| (atCur.Month == i_atBirthday.Month && atCur.Day >= i_atBirthday.Day))
		{
			m_bIsAdult		= TRUE;
		}
		else
		{
			m_bIsAdult		= FALSE;
		}
	}
	else
	{
		m_bIsAdult		= FALSE;
	}

// 	// 2008-03-28 by cmkwon, 체크 시스템 로그 - 중국 방심취 관련 시스템 로그 추가, 주민번호 확인 차원
// 	g_pFieldGlobal->WriteSystemLogEX(TRUE, "CFieldIOCPSocket::SetAdults_ %s Birthday(%s) IsAdult(%d)\r\n"
// 		, GetCharacterString(GetCharacter(), string()), i_atBirthday.GetDateTimeString(STRNBUF(SIZE_MAX_SQL_DATETIME_STRING)), IsAdultsUser());
	return IsAdultsUser();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			FIELD_DUMMY* CFieldIOCPSocket::FindFieldDummyNoLock(UINT i_ItemFieldIndex)
/// \brief		
/// \author		dhjin
/// \date		2006-12-04 ~ 2006-12-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
FIELD_DUMMY* CFieldIOCPSocket::FindFieldDummyNoLock(UINT i_ItemFieldIndex)
{
	mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
	for(; itr != m_mtvectFieldDummy.end(); itr++)
	{
		if (i_ItemFieldIndex == (*itr)->ItemFieldIndex)
		{
			return *itr;
		}
	}

	return NULL;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::DeleteFieldDummy(UINT i_ItemFieldIndex)
/// \brief		
/// \author		dhjin
/// \date		2006-12-04 ~ 2006-12-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::DeleteFieldDummy(UINT i_ItemFieldIndex)
{
	mt_auto_lock mtA(&m_mtvectFieldDummy);

	mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
	for(; itr != m_mtvectFieldDummy.end(); itr++)
	{
		FIELD_DUMMY *pFDummy = *itr;
		if (i_ItemFieldIndex == pFDummy->ItemFieldIndex)
		{
			SAFE_DELETE(pFDummy);
			itr	= m_mtvectFieldDummy.erase(itr);
			if(m_mtvectFieldDummy.empty())
			{
				m_bDummyCheck		= FALSE;
			}
			return TRUE;
		}
	}
	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::DeleteAllFieldDummy(void)
/// \brief		
/// \author		cmkwon
/// \date		2006-12-06 ~ 2006-12-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::DeleteAllFieldDummy(void)
{
	mt_auto_lock mtA(&m_mtvectFieldDummy);

	mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
	for(; itr != m_mtvectFieldDummy.end(); itr++)
	{
		FIELD_DUMMY *pFDummy = *itr;
		SAFE_DELETE(pFDummy);		
	}
	m_mtvectFieldDummy.clear();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ApplyFieldDummyDamage(float i_fChangeValue, BYTE i_enumDamageType)
/// \brief		
/// \author		dhjin
/// \date		2006-12-04 ~ 2006-12-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ApplyFieldDummyDamage(float i_fChangeValue, BYTE i_enumDamageType)
{
	if(FALSE == m_bDummyCheck)
	{
		return FALSE;
	}

	mt_auto_lock mtA(&m_mtvectFieldDummy);
	if(m_mtvectFieldDummy.empty())
	{
		m_bDummyCheck		= FALSE;
		return FALSE;
	}

// 2009-09-17 by cmkwon, B기어 체프 하향 - 아래와 같이 수정함.
// 	int nVectIdx = 0;
// 	if(1 < m_mtvectFieldDummy.size())
// 	{
// //		nVectIdx = RANDI(0, m_mtvectFieldDummy.size()-1);
// 	}
// 
// 	FIELD_DUMMY *pFDummy	= m_mtvectFieldDummy[nVectIdx];
// 	pFDummy->Endurance1		-= i_fChangeValue;
// 	if(0.0f < pFDummy->Endurance1)
// 	{
// // 2007-05-18 by cmkwon, 필요 없음
// //		char szTemp[1024];
// //		sprintf(szTemp, "ExactCharacter CharacterName(%s) DummyCount(%d) DummyHP(%d)\r\n"
// //			, GetCharacter()->CharacterName, m_mtvectFieldDummy.size(), pFDummy->Endurance1);
// //		DBGOUT(szTemp);
// 		return TRUE;
// 	}
// 
// // 2007-05-18 by cmkwon, 필요 없음
// //	char szTemp[1024];
// //	sprintf(szTemp, "ExactCharacter CharacterName(%s) DummyCount(%d) DeleteDummy\r\n"
// //		, GetCharacter()->CharacterName, m_mtvectFieldDummy.size());
// //	DBGOUT(szTemp);
// 
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2006-12-04 by dhjin, 체프 삭제 처리
// 	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_EXPLODE_DUMMY_OK, T_FC_BATTLE_EXPLODE_DUMMY_OK, pSMsg, SendBuf);
// 	pSMsg->AttackIndex		= GetCharacter()->ClientIndex;
// 	pSMsg->ItemFieldIndex	= pFDummy->ItemFieldIndex;
// 	this->DeleteFieldDummy(pFDummy->ItemFieldIndex);
// 	mtA.auto_unlock_cancel();
// 
// 	this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_BATTLE_EXPLODE_DUMMY_OK), TRUE);
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-17 by cmkwon, B기어 체프 하향 - 마지막 체프만 기존과 같이 데미지가 사라지게 되고, 그 이전 체프는 모든 데미지를 다 받게 처리 한다.
	vectUINT		deletedDummyList;
	mtvectFieldDummy::iterator	itr = m_mtvectFieldDummy.begin();
	while(itr != m_mtvectFieldDummy.end())
	{
		FIELD_DUMMY *pFDummy = *itr;
		if(pFDummy->Endurance1 > i_fChangeValue)
		{
			pFDummy->Endurance1	-= i_fChangeValue;
			break;
		}
		
		i_fChangeValue -= pFDummy->Endurance1;	// DeleteFieldDummy() 호출전에 처리 해야함.
		deletedDummyList.push_back(pFDummy->ItemFieldIndex);
			
		itr	= m_mtvectFieldDummy.erase(itr);	// vector 에서 제거
		SAFE_DELETE(pFDummy);					// 메모리 삭제

		if(m_mtvectFieldDummy.empty())
		{
			m_bDummyCheck		= FALSE;
			break;		
		}
	}
	mtA.auto_unlock_cancel();

	if(deletedDummyList.empty())
	{// 2009-09-17 by cmkwon, 삭제된 체프 리스트가 없다.
		return TRUE;
	}

	// 2009-09-17 by cmkwon, 삭제된 체프 리스트를 전송한다.
	vectUINT::iterator itrDel(deletedDummyList.begin());
	for(; itrDel != deletedDummyList.end(); itrDel++)
	{
		UINT uiItemFIdx = *itrDel;
		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_EXPLODE_DUMMY_OK, T_FC_BATTLE_EXPLODE_DUMMY_OK, pSMsg, SendBuf);
		pSMsg->AttackIndex		= GetCharacter()->ClientIndex;
		pSMsg->ItemFieldIndex	= uiItemFIdx;
		this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_BATTLE_EXPLODE_DUMMY_OK), TRUE);
	}
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::Make_MSG_FC_BATTLE_DROP_DUMMY_OK(BYTE *o_pSendBuf, int *o_pnSendByte, int i_nBufSize)
/// \brief		
/// \author		dhjin
/// \date		2006-12-04 ~ 2006-12-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::Make_MSG_FC_BATTLE_DROP_DUMMY_OK(BYTE *o_pSendBuf, int *o_pnSendByte, int i_nBufSize)
{
	// 2007-06-21 by cmkwon, 체프 하나의 메시지로 모두 전송 - INIT_MSG를 사용하기 때문에 버퍼는 항상 SIZE_MAX_PACKET 이어야 함
	if(i_nBufSize != SIZE_MAX_PACKET){				return FALSE;}

	if(FALSE == m_bDummyCheck)
	{
		return FALSE;
	}

	mt_auto_lock mtA(&m_mtvectFieldDummy);
	int nDummyCnts = m_mtvectFieldDummy.size();
	if(0 >= nDummyCnts)
	{
		m_bDummyCheck		= FALSE;
		return FALSE;
	}


// 2007-06-21 by cmkwon, 체프 하나의 메시지로 모두 전송 - 위와 같이 수정함
//	int nSendByte		= 0;
//	MSG_FC_BATTLE_DROP_DUMMY_OK	*pMsgDropDummyOK = NULL;
//	MEMSET_ZERO(o_pSendBuf, i_nBufSize);
//	
//	*(MessageType_t*)(o_pSendBuf+nSendByte)	= T_FC_BATTLE_DROP_DUMMY_OK;
//	pMsgDropDummyOK							= (MSG_FC_BATTLE_DROP_DUMMY_OK*)(o_pSendBuf + nSendByte + SIZE_FIELD_TYPE_HEADER);
//	mtvectFieldDummy::iterator itr = m_mtvectFieldDummy.begin();
//	for(; itr != m_mtvectFieldDummy.end(); itr++)
//	{
//		if(i_nBufSize < nSendByte+MSG_SIZE(MSG_FC_BATTLE_DROP_DUMMY_OK))
//		{
//			break;
//		}
//		pMsgDropDummyOK->AttackIndex			= this->GetCharacter()->ClientIndex;
//		pMsgDropDummyOK->ItemFieldIndex			= (*itr)->ItemFieldIndex;
//		pMsgDropDummyOK->ItemNum				= (*itr)->ItemNum;
//
//		nSendByte		+= MSG_SIZE(MSG_FC_BATTLE_DROP_DUMMY_OK);
//		*(MessageType_t*)(o_pSendBuf+nSendByte)	= T_FC_BATTLE_DROP_DUMMY_OK;
//		pMsgDropDummyOK							= (MSG_FC_BATTLE_DROP_DUMMY_OK*)(o_pSendBuf + nSendByte + SIZE_FIELD_TYPE_HEADER);
//	}

	int nSendByte		= 0;
	INIT_MSG(MSG_FC_BATTLE_DROP_DUMMY_OK, T_FC_BATTLE_DROP_DUMMY_OK, pSDummyOK, o_pSendBuf);
	pSDummyOK->AttackIndex		= this->GetCharacter()->ClientIndex;
	pSDummyOK->ItemNum			= m_mtvectFieldDummy[0]->ItemNum;
	pSDummyOK->DummyCounts		= nDummyCnts;
	nSendByte					= MSG_SIZE(MSG_FC_BATTLE_DROP_DUMMY_OK);
	UINT *puiItemFieldIndex		= (UINT*)(o_pSendBuf + nSendByte);	
	for(int i=0; i < nDummyCnts; i++)
	{
		int nAddBytes = sizeof(UINT);
		if(i_nBufSize < nSendByte + nAddBytes)
		{// 2007-06-21 by cmkwon, 버퍼 크기보다 데이터가 많다, 버퍼 크기만큼만 전송
			break;
		}
		*puiItemFieldIndex		= m_mtvectFieldDummy[i]->ItemFieldIndex;
		nSendByte				+= nAddBytes;
		puiItemFieldIndex++;
	}	
	*o_pnSendByte		= nSendByte;

	if(0 >= nSendByte)
	{
		return FALSE;
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			MSG_FC_MOVE_BIT_FLAG CFieldIOCPSocket::Get_MSG_FC_MOVE_BIT_FLAG(void)
/// \brief		
/// \author		cmkwon
/// \date		2007-03-29 ~ 2007-03-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
MSG_FC_MOVE_BIT_FLAG CFieldIOCPSocket::Get_MSG_FC_MOVE_BIT_FLAG(void)
{
	MSG_FC_MOVE_BIT_FLAG moveBit;

	MEMSET_ZERO(&moveBit, sizeof(MSG_FC_MOVE_BIT_FLAG));

	moveBit.CharacterMode0		= m_character.CharacterMode;
	moveBit.Invisible0			= m_UnitRenderInfo.RI_Invisible;
	moveBit.ChargingSkill		= m_SkillManager.m_bChargingSkill;		// 2007-04-02 by cmkwon
	moveBit.HyperShot			= m_SkillManager.m_bHyperShot;
	// 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
	moveBit.bSearchEye_1		= m_structUsingItemBitFlag.bSearchEye_1;
	moveBit.bSearchEye_2		= m_structUsingItemBitFlag.bSearchEye_2;
	// end 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
	moveBit.bUsingBarialSkill	= m_structUsingItemBitFlag.bUsingBarialSkill;	// 2013-01-29 by jhseol, 베리어 스킬 이펙트 버그
	moveBit.bUsingInvicibleSkill	= m_structUsingItemBitFlag.bUsingInvicibleSkill;	// 2013-02-06 by jhseol, M기어 무적스킬 이벡트 버그
	return moveBit;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::AddObserver(CFieldIOCPSocket *i_pObserverFISoc)
/// \brief		
/// \author		cmkwon
/// \date		2007-04-03 ~ 2007-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::AddObserver(CFieldIOCPSocket *i_pObserverFISoc)
{
	mt_auto_lock mtA(&m_mtvectObersverCharacter);

	mtvectObersverCharacter::iterator itr = find(m_mtvectObersverCharacter.begin(), m_mtvectObersverCharacter.end(), i_pObserverFISoc);
	if(itr != m_mtvectObersverCharacter.end())
	{
		return FALSE;
	}
	m_mtvectObersverCharacter.push_back(i_pObserverFISoc);

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::PopObserver(CFieldIOCPSocket *i_pObserverFISoc)
/// \brief		
/// \author		cmkwon
/// \date		2007-04-03 ~ 2007-04-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::PopObserver(CFieldIOCPSocket *i_pObserverFISoc)
{
	BOOL bRet = FALSE;

	mt_auto_lock mtA(&m_mtvectObersverCharacter);
	
	mtvectObersverCharacter::iterator itr(m_mtvectObersverCharacter.begin());
	while(itr != m_mtvectObersverCharacter.end())
	{
		if(*itr == i_pObserverFISoc)
		{
			bRet = TRUE;
			
			itr = m_mtvectObersverCharacter.erase(itr);
			continue;
		}
		itr++;
	}
	
	return bRet;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::AddWatchUser(CFieldIOCPSocket *i_pObserverFISoc)
/// \brief		
/// \author		dhjin
/// \date		2007-06-19 ~ 2007-06-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::AddWatchUser(CFieldIOCPSocket *i_pObserverFISoc)
{
	mt_auto_lock mtA(&m_mtvectWatchCharacter);

	mtvectObersverCharacter::iterator itr = find(m_mtvectWatchCharacter.begin(), m_mtvectWatchCharacter.end(), i_pObserverFISoc);
	if(itr != m_mtvectWatchCharacter.end())
	{
		return FALSE;
	}
	m_mtvectWatchCharacter.push_back(i_pObserverFISoc);

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::PopWatchUser(CFieldIOCPSocket *i_pObserverFISoc)
/// \brief		
/// \author		dhjin
/// \date		2007-06-19 ~ 2007-06-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::PopWatchUser(CFieldIOCPSocket *i_pObserverFISoc)
{
	BOOL bRet = FALSE;

	mt_auto_lock mtA(&m_mtvectWatchCharacter);
	
	mtvectObersverCharacter::iterator itr(m_mtvectWatchCharacter.begin());
	while(itr != m_mtvectWatchCharacter.end())
	{
		if(*itr == i_pObserverFISoc)
		{
			bRet = TRUE;
			
			itr = m_mtvectWatchCharacter.erase(itr);
			continue;
		}
		itr++;
	}
	
	return bRet;
}

CHAR * CFieldIOCPSocket::GetCharacterLevelRank()
{
	return CAtumSJ::GetStatusByLevel(m_character.Level);	// 2010-01-08 by cmkwon, 최대 레벨 상향에 따른 추가 사항(레벨별 계급) - 

// 2010-01-08 by cmkwon, 최대 레벨 상향에 따른 추가 사항(레벨별 계급) - 위와 같이 CAtumSJ::GetStatusByLevel#함수 호출로 변경 수정함.
// 	if(12 <= m_character.Level && 22 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_12_LEVEL_RANK;
// 	}
// 	else if(22 <= m_character.Level && 32 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_22_LEVEL_RANK;
// 	}
// 	else if(32 <= m_character.Level && 42 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_32_LEVEL_RANK;
// 	}
// 	else if(42 <= m_character.Level && 52 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_42_LEVEL_RANK;
// 	}
// 	else if(52 <= m_character.Level && 62 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_52_LEVEL_RANK;
// 	}
// 	else if(62 <= m_character.Level && 72 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_62_LEVEL_RANK;
// 	}
// 	else if(72 <= m_character.Level && 82 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_72_LEVEL_RANK;
// 	}
// 	else if(82 <= m_character.Level && 92 > m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_82_LEVEL_RANK;
// 	}
// 	else if(92 <= m_character.Level)
// 	{
// 		return STRCMD_CS_CHARACTER_92_LEVEL_RANK;
// 	}
// 
// 	return STRCMD_CS_CHARACTER_12_LEVEL_RANK;
}

void CFieldIOCPSocket::Send2MeCharacterOtherInfo(vectorClientIndex *i_pVectCltIndexList)
{
	if(IsUsing() == FALSE || CS_PLAYING != GetClientState()){		return;}

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_OTHER_INFO_OK, T_FC_CHARACTER_GET_OTHER_INFO_OK, pMsgOtherInfo, SendBuf);
	for(int i=0; i < i_pVectCltIndexList->size(); i++)
	{
		// 캐릭터의 정보를 보내는 경우
		CFieldIOCPSocket *ptmFSock = ms_pFieldIOCP->GetFieldIOCPSocket((*i_pVectCltIndexList)[i]);
		if (ptmFSock
			&& ptmFSock->IsValidCharacter(FALSE)
			&& FALSE == COMPARE_BODYCON_BIT(ptmFSock->GetCharacter()->BodyCondition, BODYCON_EVENT_HANDLE_MASK)
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//			&& FALSE == COMPARE_BODYCON_BIT(ptmFSock->GetCharacter()->BodyCondition, BODYCON_STEALTH_MASK))
			&& FALSE == ptmFSock->IsInvisibleCharacter())
		{
			pMsgOtherInfo->CharacterInfo					= ptmFSock->m_character;
			memcpy(pMsgOtherInfo->CharacterInfo.szCharacterMent, ptmFSock->m_szCharacterMent, SIZE_STRING_32);
			pMsgOtherInfo->CharacterInfo.CityWarTeamType	= ptmFSock->m_byCityWarTeamType;
			pMsgOtherInfo->CharacterRenderInfo				= ptmFSock->m_UnitRenderInfo;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK));

			INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_INFO_OK, T_FC_BAZAAR_INFO_OK, pSBazaarInfo, SendBuf2);
			if(ptmFSock->MakeMSG_FC_BAZAAR_INFO_OKW(pSBazaarInfo))
			{// 2006-07-26 by cmkwon, 개인 상점 정보 전송
				this->SendAddData(SendBuf2, MSG_SIZE(MSG_FC_BAZAAR_INFO_OK));
			}

			int nSendByte = 0;
			if(ptmFSock->Make_MSG_FC_BATTLE_DROP_DUMMY_OK(SendBuf2, &nSendByte, SIZE_MAX_PACKET))
			{// 2006-12-04 by dhjin, 체프 정보 전송
				this->SendAddData(SendBuf2, nSendByte);		// 2007-08-09 by cmkwon, 버그 수정(SendBuf2 <== SendBuf)
			}
		}
	}
}

void CFieldIOCPSocket::SendCharacterOtherInfo(int idx, BOOL i_bSendInRange /* = FALSE */)
{
	CFieldIOCPSocket			*pFieldIOCPSocket;
	const CHARACTER				*pCharacter;

	if(IsUsing() == FALSE || CS_PLAYING != GetClientState()){ return;}

	if ( idx >= MONSTER_CLIENT_INDEX_START_NUM )
	{
		CFieldMonster	*pMonster = m_pCurrentFieldMapChannel->GetFieldMonster(idx, 3);
		if(NULL == pMonster || pMonster->m_enMonsterState == MS_NULL)
		{
			return;
		}
		else if(NULL == pMonster->MonsterInfoPtr)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] SendCharacterOtherInfo");
			return;
		}

		MONSTER_INFO * pMonInfo = pMonster->MonsterInfoPtr;
		if(NULL == pMonInfo)
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] SendCharacterOtherInfo2");
			return;
		}

		// 몬스터의 정보를 보내는 경우
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_MONSTER_INFO_OK, T_FC_CHARACTER_GET_MONSTER_INFO_OK, pMsgOtherInfo, SendBuf);
		pMsgOtherInfo->MonsterIndex		= idx;
		pMsgOtherInfo->MonsterUnitKind	= pMonInfo->MonsterUnitKind;
		pMsgOtherInfo->MonsterForm		= pMonInfo->MonsterForm;
		pMsgOtherInfo->BodyCondition	= pMonster->BodyCondition;
		pMsgOtherInfo->PositionVector	= pMonster->PositionVector;
		pMsgOtherInfo->TargetVector		= pMonster->TargetVector*1000.0f;
		pMsgOtherInfo->CurrentHP		= pMonster->CurrentHP;

		// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
		pMsgOtherInfo->MaxHP			= (INT)pMonster->MonsterInfoExtend.fMaxHP;
		// End 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )

		SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_MONSTER_INFO_OK));
	}
	else
	{
		// 캐릭터의 정보를 보내는 경우
		pFieldIOCPSocket = ms_pFieldIOCP->GetFieldIOCPSocket(idx);
		if (pFieldIOCPSocket == NULL 
			|| FALSE == pFieldIOCPSocket->IsValidCharacter(FALSE)
			|| pFieldIOCPSocket->IsInvisibleCharacter())			// 2007-10-02 by cmkwon, 투명 상태의 유저 정보는 전송하지 않는다
		{
			return;
		}

		pCharacter = pFieldIOCPSocket->GetCharacter();
		if (COMPARE_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_EVENT_HANDLE_MASK))
		{
			return;
		}

		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_OTHER_INFO_OK, T_FC_CHARACTER_GET_OTHER_INFO_OK, pMsgOtherInfo, SendBuf)
		pMsgOtherInfo->CharacterInfo					= *pCharacter;
		memcpy(pMsgOtherInfo->CharacterInfo.szCharacterMent, pFieldIOCPSocket->m_szCharacterMent, SIZE_STRING_32);
		pMsgOtherInfo->CharacterInfo.CityWarTeamType	= pFieldIOCPSocket->m_byCityWarTeamType;
		pMsgOtherInfo->CharacterRenderInfo				= pFieldIOCPSocket->m_UnitRenderInfo;

		// 2006-07-26 by cmkwon, 개인 상점 정보 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_BAZAAR_INFO_OK, T_FC_BAZAAR_INFO_OK, pSBazaarInfo, SendBuf2);
		BOOL bBazaar = pFieldIOCPSocket->MakeMSG_FC_BAZAAR_INFO_OKW(pSBazaarInfo);
		
		if (i_bSendInRange)
		{
			ms_pFieldIOCP->SendInRangeMessageAroundCharacter(idx, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK),
															pFieldIOCPSocket->m_pCurrentFieldMapChannel, FALSE, pFieldIOCPSocket->m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
			if(bBazaar)
			{// 2006-07-26 by cmkwon, 개인 상점 정보 전송
				ms_pFieldIOCP->SendInRangeMessageAroundCharacter(idx, SendBuf2, MSG_SIZE(MSG_FC_BAZAAR_INFO_OK),
																pFieldIOCPSocket->m_pCurrentFieldMapChannel, FALSE, pFieldIOCPSocket->m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
			}

			int nSendByte = 0;
			if(pFieldIOCPSocket->Make_MSG_FC_BATTLE_DROP_DUMMY_OK(SendBuf2, &nSendByte, SIZE_MAX_PACKET))
			{// 2006-12-04 by dhjin, 체프 정보 전송
				ms_pFieldIOCP->SendInRangeMessageAroundCharacter(idx, SendBuf2, nSendByte,
															pFieldIOCPSocket->m_pCurrentFieldMapChannel, FALSE, pFieldIOCPSocket->m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());				
			}
		}
		else
		{
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK));
			if(bBazaar)
			{// 2006-07-26 by cmkwon, 개인 상점 정보 전송
				SendAddData(SendBuf2, MSG_SIZE(MSG_FC_BAZAAR_INFO_OK));
			}

			int nSendByte = 0;
			if(pFieldIOCPSocket->Make_MSG_FC_BATTLE_DROP_DUMMY_OK(SendBuf2, &nSendByte, SIZE_MAX_PACKET))
			{// 2006-12-04 by dhjin, 체프 정보 전송
				this->SendAddData(SendBuf2, nSendByte);				
			}
		}
	}
}

// virtual function
BOOL CFieldIOCPSocket::ResCreateCharacter(CHARACTER *pCharacter, int nErr/*=0*/, CHARACTER_RENDER_INFO *i_pRenderInfo/*=NULL*/)
{
	if(IsUsing() == FALSE)
	{
		return FALSE;
	}
	// 2013-01-18 by khkim, GLog 
	USHORT BackupRace = 0;
	BackupRace = m_character.Race;
	// end 2013-01-18 by khkim, GLog 
	if(0 == nErr)
	{
		m_character = *pCharacter;		// 새로 생성된 캐릭터를 설정한다.


		///////////////////////////////////////////////////////////////////////////////
		// 2006-09-28 by cmkwon
		FC_CONNECT_LOGIN_INFO tmLoginInfo;
		MEMSET_ZERO(&tmLoginInfo, sizeof(FC_CONNECT_LOGIN_INFO));
		STRNCPY_MEMSET(tmLoginInfo.CharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		tmLoginInfo.CharacterUniqueNumber		= m_character.CharacterUniqueNumber;
		tmLoginInfo.Race						= m_character.Race;
		tmLoginInfo.PilotFace					= m_character.PilotFace;
		tmLoginInfo.Gender						= m_character.Gender;
		mt_auto_lock mtallcharacter(&m_mtvectAllCharacterInfo);
		m_mtvectAllCharacterInfo.push_back(tmLoginInfo);
		mtallcharacter.auto_unlock_cancel();
		// 
		///////////////////////////////////////////////////////////////////////////////
		

		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CREATE_OK, T_FC_CHARACTER_CREATE_OK, pSCreateOK, SendBuf);
		pSCreateOK->Character				= m_character;
		pSCreateOK->CharacterRenderInfo		= *i_pRenderInfo;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CREATE_OK));

		// send log
		CAtumLogSender::SendLogMessageCREATECHARACTER(pCharacter);

		// start 2012-10-08 by khkim, GLog
		// CharacterCreate GLog 패킷Send 부분
		// 2015-02-10 by bckim, 임시 허용 
		//if(!COMPARE_RACE(BackupRace,RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))		// 2013-01-18 by khkim, GLog (일반유저만 기록)	
		{
			INT nPay = 0;
			{
				mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
			
				ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
				if (pMoney == NULL )
				{
					nPay = 0;
				}
				else
				{
					nPay = pMoney->CurrentCount;
				}
			}
			MSG_FL_LOG_CHARDATA LogCharDataParameter;
			MEMSET_ZERO(&LogCharDataParameter, sizeof(LogCharDataParameter));		// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
			LogCharDataParameter.LogType			= GLOG_CD_LT_CHARACTERCREATE;
			LogCharDataParameter.UserSerial			= (UID64_t)m_character.AccountUniqueNumber;
			LogCharDataParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
			LogCharDataParameter.Class				= (SHORT)m_character.UnitKind;
			LogCharDataParameter.Lv					= (SHORT)m_character.Level;
			LogCharDataParameter.Exp				= (UID64_t)m_character.Experience;
			LogCharDataParameter.GameMoney			= (UID64_t)nPay;
			LogCharDataParameter.Playtime			= (UID64_t)GetTotalPlayTimeInSeconds();		// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅		// 2013-01-18 by khkim, GLog (총 플레이시간 수정)
			LogCharDataParameter.GameServerID		= (int)g_pFieldGlobal->GetMGameServerID();
// 2013-01-03 by khkim, GLog (버그 확인용)
#ifdef S_KOR_TEST_GLOG_CHARDATA
			if(LogCharDataParameter.UserSerial < 0 || LogCharDataParameter.UserSerial > 7000000 )
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE,"[DEBUG] GLog #003 [%d,%I64d,%I64d,%d,%d,%I64d,%I64d,%I64d,%d]\r\n ", 
					LogCharDataParameter.LogType,	LogCharDataParameter.UserSerial,	LogCharDataParameter.CharSerial,
					LogCharDataParameter.Class,		LogCharDataParameter.Lv,			LogCharDataParameter.Exp, 
					LogCharDataParameter.GameMoney, LogCharDataParameter.Playtime,		LogCharDataParameter.GameServerID);
			}
#endif 
// end 2013-01-03 by khkim, GLog (버그 확인용)	
			CAtumLogSender::SendLogCharData(&LogCharDataParameter);
		}
		// end 2012-10-08 by khkim, GLog


//		m_dwNumCharacters++;	// 캐릭터 수 증가, DB서 처리, deleted on 20030815

/*
		// Insert default items
		QPARAM_INSERTDEFAULTITEMS *pParam = new QPARAM_INSERTDEFAULTITEMS;
		pParam->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(this,	pParam, QT_InsertDefaultItems);
*/
	}
	else
	{
		switch(nErr)
		{
		case ERR_COMMON_CHARACTER_ALREADY_EXISTS:
			{
				SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_COMMON_CHARACTER_ALREADY_EXISTS);
			}
			break;
		case ERR_COMMON_NO_SUCH_CHARACTER:
			{
				SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_COMMON_NO_SUCH_CHARACTER, pCharacter->AccountUniqueNumber, 0, pCharacter->CharacterName);
			}
			break;
		default:
			{
				SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_COMMON_UNKNOWN_ERROR, nErr);
			}
		}
	}

	return FALSE;
}

BOOL CFieldIOCPSocket::ResDeleteCharacter(MSG_FC_CHARACTER_DELETE *pMsgCharacterDelete, int nErr)
{
	int		nSendType;

	if(IsUsing() == FALSE)
	{
		return FALSE;
	}

	if(0 == nErr)
	{
		// 로그를 남기기 위해 cache를 검색
		mt_auto_lock ccLock(&m_mtvectCharacterCache);
		CHARACTER *pCharac = this->GetCharacterCacheNoLock(pMsgCharacterDelete->CharacterUniqueNumber);		// 2007-01-15 by cmkwon, 버그 수정(삭제된 캐릭터 정보를 출력 해야함)
		if(pCharac)
		{
			CAtumLogSender::SendLogMessageDELETECHARACTER(pCharac);
		}
		ccLock.auto_unlock_cancel();

		// 2006-09-28 by cmkwon, 체크는 필요 없음
		DeleteCharacterUIDFormAccount(pMsgCharacterDelete->CharacterUniqueNumber);
		
		if(0 == this->m_nNumCharacters)
		{// 2005-12-19 by cmkwon, 캐릭이 모두 지워지면 둘다 선택 가능하도록 
			this->SetSelectableInfluenceMask(INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI);	// 정규세력, 반란세력
		}

		nSendType = T_FC_CHARACTER_DELETE_OK;
		SendAddData((BYTE*)&nSendType, SIZE_FIELD_TYPE_HEADER);

		// start 2012-10-08 by khkim, GLog
		// CharacterDelete 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 (일반유저만 기록)	
		{
			INT nPay = 0;
			{
				mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
				ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
				if (pMoney == NULL )
				{
					nPay = 0;
				}
				else
				{
					nPay = pMoney->CurrentCount;
				}
			}
			MSG_FL_LOG_CHARDATA LogCharDataParameter;
			MEMSET_ZERO(&LogCharDataParameter, sizeof(LogCharDataParameter));		// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
			LogCharDataParameter.LogType			= GLOG_CD_LT_CHARACTERDELETE;
			LogCharDataParameter.UserSerial			= (UID64_t)m_character.AccountUniqueNumber; 
			LogCharDataParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
			LogCharDataParameter.Class				= (SHORT)m_character.UnitKind;
			LogCharDataParameter.Lv					= (SHORT)m_character.Level;
			LogCharDataParameter.Exp				= (UID64_t)m_character.Experience;
			LogCharDataParameter.GameMoney			= (UID64_t)nPay;
			LogCharDataParameter.Playtime			= (UID64_t)GetTotalPlayTimeInSeconds();		// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅		// 2013-01-18 by khkim, GLog (총 플레이시간 수정)
			LogCharDataParameter.GameServerID		= (int)g_pFieldGlobal->GetMGameServerID();
// 2013-01-03 by khkim, GLog (버그 확인용)
#ifdef S_KOR_TEST_GLOG_CHARDATA
			if(LogCharDataParameter.UserSerial < 0 || LogCharDataParameter.UserSerial > 7000000 )
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE,"[DEBUG] GLog #004 [%d,%I64d,%I64d,%d,%d,%I64d,%I64d,%I64d,%d]\r\n ", 
					LogCharDataParameter.LogType,	LogCharDataParameter.UserSerial,	LogCharDataParameter.CharSerial,
					LogCharDataParameter.Class,		LogCharDataParameter.Lv,			LogCharDataParameter.Exp, 
					LogCharDataParameter.GameMoney, LogCharDataParameter.Playtime,		LogCharDataParameter.GameServerID);
			}
#endif 
// end 2013-01-03 by khkim, GLog (버그 확인용)	
			CAtumLogSender::SendLogCharData(&LogCharDataParameter);
		}
		// end 2012-10-08 by khkim, GLog


//		m_dwNumCharacters--;	// 캐릭터 수 감소, DB서 처리, deleted on 20030815
	}
	else
	{
		switch(nErr)
		{
		case ERR_COMMON_NO_SUCH_CHARACTER:
			{
				SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_COMMON_NO_SUCH_CHARACTER, pMsgCharacterDelete->AccountUniqueNumber, pMsgCharacterDelete->CharacterUniqueNumber, m_character.AccountName);
			}
			break;
		default:
			{
				SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_COMMON_UNKNOWN_ERROR, nErr);
			}
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FI_CHARACTER_DELETE_CHARACTER, T_FI_CHARACTER_DELETE_CHARACTER, msgDel, msgDelBuf);
	msgDel->AccountUniqueNumber		= m_character.AccountUniqueNumber;
	msgDel->CharacterUniqueNumber	= pMsgCharacterDelete->CharacterUniqueNumber;
	msgDel->GuildUniqueNumber		= m_character.GuildUniqueNumber;
	ms_pFieldIOCP->m_pIMWinSocket->Write(msgDelBuf, MSG_SIZE(MSG_FI_CHARACTER_DELETE_CHARACTER));
	return FALSE;
}

// 2005-07-21 by cmkwon
//BOOL CFieldIOCPSocket::ResConnectGameStart(CHARACTER *pCharacter, int nErr)
//{
//	if(IsUsing() == FALSE)
//	{
//		return FALSE;
//	}
//
//	if(0 == nErr)
//	{
//		if(strnicmp(m_character.AccountName, pCharacter->AccountName, SIZE_MAX_ACCOUNT_NAME) != 0)
//		{
//			// Protocol Error 처리
//			// - 요청한 처리결과의 AccountName이 접속한 AccountName과 다르다
//			SendErrorMessage(T_FC_CHARACTER_CONNECT_GAMESTART, ERR_DB_NO_SUCH_ACCOUNT, 0, 0, pCharacter->AccountName);
//			Close(0x14005);
//		}
//		else
//		{
//			// DB error check
//			if( FALSE == COMPARE_BODYCON_BIT(pCharacter->BodyCondition, BODYCON_FLY_MASK))
//			{
//				// body condition reset
//				SetBodyConditionBit(pCharacter->BodyCondition, BODYCON_FLY_MASK);
//				QPARAM_CHARACTER_CHANGE_BODYCONDITION *pQChangeBodycon = new QPARAM_CHARACTER_CHANGE_BODYCONDITION;
//				pQChangeBodycon->CharacterUniqueNumber = pCharacter->CharacterUniqueNumber;
//				pQChangeBodycon->BodyCondition = pCharacter->BodyCondition;
//				((CFieldIOCP*)ms_pFieldIOCP )->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeBodyCondition, this
//					, m_character.AccountUniqueNumber, pQChangeBodycon);
//
//				// 마을로 보내기
//				pCharacter->PositionVector.x = 100;
//				pCharacter->PositionVector.y = HEIGHT_FLYING_ALTITUDE;
//				pCharacter->PositionVector.z = 100;
//				QPARAM_CHARACTER_CHANGE_POSITION *pQChangePos = new QPARAM_CHARACTER_CHANGE_POSITION;
//				pQChangePos->CharacterUniqueNumber = pCharacter->CharacterUniqueNumber;
//				pQChangePos->PositionVector = pCharacter->PositionVector;
//				((CFieldIOCP*)ms_pFieldIOCP )->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePosition, this
//					, m_character.AccountUniqueNumber, pQChangePos);
//
//			}
//
//			memcpy(&m_character, pCharacter, sizeof(CHARACTER));		// 게임에서 사용할 Character
//			m_character.ClientIndex = this->GetClientArrayIndex();				// ClientIndex를 다시 설정한다.
//		}
//	}
//	else
//	// Error
//	{
//		switch(nErr)
//		{
//		case ERR_COMMON_NO_SUCH_CHARACTER:
//			{
//				SendErrorMessage(T_FC_CHARACTER_CONNECT_GAMESTART, ERR_COMMON_NO_SUCH_CHARACTER, 0, 0, m_character.AccountName);
//			}
//			break;
//		default:
//			{
//				SendErrorMessage(T_FC_CHARACTER_CONNECT_GAMESTART, ERR_COMMON_UNKNOWN_ERROR);
//			}
//		}
//	}
//
//	BOOL bRet = CharacterGameStartRoutine(GST_CONN_GAMESTART);
//	if (!bRet)
//	{
//		SendErrorMessage (T_FC_CHARACTER_CONNECT_GAMESTART, ERR_PROTOCOL_GAMESTARTROUTINE_FAILED, 0, 0, NULL, TRUE);
//		return FALSE;
//	}
//
//	return TRUE;
//}

void CFieldIOCPSocket::OnAttachItem(ITEM_GENERAL *i_pItemGeneral, BYTE i_nTargetItemWindowIndex)
{
	INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);	// 2012-09-20 by jhseol, 스텔스카드 악세사리 추가 - 패킷 미리 생성
	switch (i_nTargetItemWindowIndex)
	{
	case POS_PROWIN:
		{
			if (i_pItemGeneral->ItemInfo->Kind == ITEMKIND_COMPUTER)
			{
				// 컴퓨터 아이템을 올릴 때
				CheckComputerState(i_pItemGeneral->ItemInfo, TRUE);
			}
		}
		break;
	case POS_WINGOUT:		// 2006-09-08 by cmkwon, // 2형 무기(선두 우측)	--> 우측 1번
		{
///////////////////////////////////////////////////////////////////////////////	
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 초기화 하면 안된다
//			m_WeaponIndexGenerator.Reset();				// 2006-09-08 by cmkwon, 2형 무기 장착 변경 체크를 위해서
		}
		break;
	case POS_CENTER:
		{
// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
// 			if (i_pItemGeneral->ItemInfo->Kind == ITEMKIND_DEFENSE)
// 			{
// 				// 아머 적용 여부에 따른 확인
// 				CheckArmorState();
// 			}

			// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 장착
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 아이템 장착
			if( SHAPE_STAT_INIT_LEVEL < i_pItemGeneral->FixedTermShape.nStatLevel ) // 0 이상 이면 외변킷이 적용된 아머 
			{
				ITEM *pShapeKitItem = ms_pFieldIOCP->GetItemInfo(i_pItemGeneral->FixedTermShape.nStatShapeItemNum);
				if ( NULL != pShapeKitItem )
				{
					if ( TRUE == pShapeKitItem->IsExistDesParam(DES_ALL_PART) )
					{
						CheckAllState(pShapeKitItem->GetParameterValue(DES_ALL_PART)*min(i_pItemGeneral->FixedTermShape.nStatLevel, SHAPE_STAT_MAX_LEVEL), TRUE);
					}
				}
			}
#endif
			// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 장착
		}
		break;

	//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
	case POS_ACCESSORY_UNLIMITED :
		{

// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 아래와 같이 시스템 수정 및 변경됨
//			switch(i_pItemGeneral->ItemInfo->DestParameter1)
//			{
//			case DES_HP:
//				{
//					this->ChangeHP(GetCharacterTotalHP());
//					this->ChangeCurrentHP(max(0.0f, i_pItemGeneral->CurrentCount));
//					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//		 			m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, -i_pItemGeneral->CurrentCount, IUT_GENERAL);	// CurrentCount를 0으로 만들기
//				}
//				break;
//			case DES_DP:
//				{
//					this->ChangeDP(GetCharacterTotalDP());
//					this->ChangeCurrentDP(max(0.0f, i_pItemGeneral->CurrentCount));
//					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//		 			m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, -i_pItemGeneral->CurrentCount, IUT_GENERAL);	// CurrentCount를 0으로 만들기
//				}
//				break;
//			case DES_EP:
//				{
//					this->ChangeEP(GetCharacterTotalEP());
//					this->ChangeCurrentEP(max(0.0f, i_pItemGeneral->CurrentCount));
//					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//		 			m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, -i_pItemGeneral->CurrentCount, IUT_GENERAL);	// CurrentCount를 0으로 만들기
//				}
//				break;
//			default:// 2006-04-04 by cmkwon, 무제한 액세서리는 DES_HP, DES_DP, DES_EP만 유효함
//				{
//					char szErrLog[1024];
//					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem DES_XX(%d) Error1!!\r\n", i_pItemGeneral->ItemInfo->DestParameter1);
//					g_pFieldGlobal->WriteSystemLog(szErrLog);
//					DbgOut(szErrLog);
//					return;
//				}
//			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 기존에 채워주던 Current 값은 채워주지 않도록 수정함
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			this->SetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter1, i_pItemGeneral->ItemInfo->ParameterValue1);
// 			this->SetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter2, i_pItemGeneral->ItemInfo->ParameterValue2);
// 			this->SetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter3, i_pItemGeneral->ItemInfo->ParameterValue3);
// 			this->SetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter4, i_pItemGeneral->ItemInfo->ParameterValue4);

///////////////////////////////////////////////////////////////////////////////
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, ResetAllSkillAndEnchant()로 이동
//			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
//			{
//				this->SetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->ArrDestParameter[i], i_pItemGeneral->ItemInfo->ArrParameterValue[i]);
//			}
//
//			this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();	// 2007-12-13 by cmkwon, DB 에 저장을 위해
		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리 아이템 장착
	case POS_ACCESSORY_TIME_LIMIT : 
		{
			if(ITEMKIND_ACCESSORY_TIMELIMIT != i_pItemGeneral->Kind)
			{
				char szErrLog[1024];
				wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem Kind(%d) Error2!!\r\n", i_pItemGeneral->Kind);
				g_pFieldGlobal->WriteSystemLog(szErrLog);
				DbgOut(szErrLog);
				return;
			}
			if(FALSE == m_ItemManager.Add2UsingTimeLimitedItemList(i_pItemGeneral))
			{
				char szErrLog[1024];
				wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem Kind(%d) Error3!!\r\n", i_pItemGeneral->Kind);
				g_pFieldGlobal->WriteSystemLog(szErrLog);
				DbgOut(szErrLog);
				return;
			}
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//switch(i_pItemGeneral->ItemInfo->DestParameter1)
			switch(i_pItemGeneral->ItemInfo->ArrDestParameter[0])
			{
			case DES_DEFENSE_01:
			case DES_DEFENSE_02:
			case DES_DEFENSEPROBABILITY_01:
			case DES_DEFENSEPROBABILITY_02:
			case DES_MINATTACK_01:
			case DES_MAXATTACK_01:
			case DES_MINATTACK_02:
			case DES_MAXATTACK_02:
			case DES_DROP_EXP:
			case DES_DROP_SPI:
			case DES_DROP_ITEM:
			case DES_RARE_ITEM_DROP_RATE:	// 2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
			case DES_HP_REPAIR_RATE_FLIGHTING:
			case DES_DP_REPAIR_RATE:
			case DES_SP_REPAIR_RATE:
			case DES_ATTACK_RANGE_01:		// 2006-05-30 by cmkwon
			case DES_ATTACK_RANGE_02:		// 2006-05-30 by cmkwon
			case DES_PIERCE_UP_01:		// 2008-09-22 by dhjin, 신규 인첸트, 기본무기 피어스율 증가 카드
			case DES_PIERCE_UP_02:		// 2008-09-22 by dhjin, 신규 인첸트, 고급무기 피어스율 증가 카드
			case DES_ATTACKPROBABILITY_01:		// 2008-09-30 by dhjin, 신규 인첸트, 공격확률 01
			case DES_ATTACKPROBABILITY_02:		// 2008-09-30 by dhjin, 신규 인첸트, 공격확률 02
			case DES_RARE_ITEM_PARTNER_SPEED:	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
				break;
				// 2012-09-20 by jhseol, 스텔스카드 악세사리 추가
			case DES_CASH_STEALTH:
				this->m_bStealthState	= TRUE;
				
				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));
				break;
				// end 2012-09-20 by jhseol, 스텔스카드 악세사리 추가
			default:
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem DES1(%d) DES2(%d) Error4!!\r\n", i_pItemGeneral->ItemInfo->ArrDestParameter[0], i_pItemGeneral->ItemInfo->ArrDestParameter[1]);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
				if(FALSE == m_ItemManager.Add2UsingTimeLimitedItemList(i_pItemGeneral))
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem Kind(%d) Error3!!\r\n", i_pItemGeneral->Kind);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
			}
			ApplyParamFactorWithAccesoryTimeLimiteItem(i_pItemGeneral->ItemInfo);

			// 2008-01-23 by cmkwon, S_F, S_L: 장착/장착해제 게임 로그에 추가 - 현재는 시간제한악세사리 아이템만 로그에 남긴다
			CAtumLogSender::SendLogMessageITEMAttachItem(this, i_pItemGeneral);
			
			INIT_MSG_WITH_BUFFER(MSG_FC_STORE_INSERT_USINGITEM, T_FC_STORE_INSERT_USINGITEM, pSUsingItem, SendBuf);
			pSUsingItem->ItemNum				= i_pItemGeneral->ItemNum;
			pSUsingItem->ItemUID				= i_pItemGeneral->UniqueNumber;
			pSUsingItem->ItemInsertionType		= IUT_USE_ITEM;
			// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 아래와 같이 수정 함.
			//pSUsingItem->nRemainSecond			= i_pItemGeneral->ItemInfo->Time/1000 - i_pItemGeneral->UsingTimeStamp;
			pSUsingItem->nRemainSecond			= CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(i_pItemGeneral->ItemInfo) - i_pItemGeneral->UsingTimeStamp;
			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_INSERT_USINGITEM));
		}
		break;

	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	case POS_PET : 
		{
			if(ITEMKIND_PET_ITEM != i_pItemGeneral->Kind)
			{
				char szErrLog[1024];
				wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem Kind(%d) Error2!!\r\n", i_pItemGeneral->Kind);
				g_pFieldGlobal->WriteSystemLog(szErrLog);
				DbgOut(szErrLog);
			}
			switch(i_pItemGeneral->ItemInfo->ArrDestParameter[0])
			{
			case DES_RARE_ITEM_PARTNER_SPEED:	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
				break;
			default:
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem DES1(%d) DES2(%d) Error4!!\r\n", i_pItemGeneral->ItemInfo->ArrDestParameter[0], i_pItemGeneral->ItemInfo->ArrDestParameter[1]);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
				if(FALSE == m_ItemManager.Add2UsingTimeLimitedItemList(i_pItemGeneral))
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnAttachItem Kind(%d) Error3!!\r\n", i_pItemGeneral->Kind);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
			}
			ApplyParamFactorWithAccesoryTimeLimiteItem(i_pItemGeneral->ItemInfo);
			
			CAtumLogSender::SendLogMessageITEMAttachItem(this, i_pItemGeneral);
			INIT_MSG_WITH_BUFFER(MSG_FC_STORE_INSERT_USINGITEM, T_FC_STORE_INSERT_USINGITEM, pSUsingItem, SendBuf);
			pSUsingItem->ItemNum				= i_pItemGeneral->ItemNum;
			pSUsingItem->ItemUID				= i_pItemGeneral->UniqueNumber;
			pSUsingItem->ItemInsertionType		= IUT_USE_ITEM;
			pSUsingItem->nRemainSecond			= CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(i_pItemGeneral->ItemInfo) - i_pItemGeneral->UsingTimeStamp;
			this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_INSERT_USINGITEM));
		}
		break;
		// end 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	}
	
}

void CFieldIOCPSocket::OnDetachItem(ITEM_GENERAL *i_pItemGeneral, BYTE i_nSourceItemWindowIndex
									, BOOL i_bSendChangeInfo/*=TRUE*/
									, BOOL i_bDeleteUsingTimeLimitedItem/*=TRUE*/)
{
	INIT_MSG_WITH_BUFFER(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE, T_FN_CHARACTER_CHANGE_STEALTHSTATE, pSMsg, BufSend);	// 2012-09-20 by jhseol, 스텔스카드 악세사리 추가 - 패킷 미리 생성
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	this->m_ItemManager.StopInvokingItemList(i_pItemGeneral);

	switch (i_nSourceItemWindowIndex)
	{
	case POS_PROWIN:
		{
			if (i_pItemGeneral->ItemInfo->Kind == ITEMKIND_COMPUTER)
			{
				// 컴퓨터 아이템을 내릴 때
				CheckComputerState(i_pItemGeneral->ItemInfo, FALSE, i_bSendChangeInfo);
			}
		}
		break;
	case POS_CENTER:
		{
// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
// 			if (i_pItemGeneral->ItemInfo->Kind == ITEMKIND_DEFENSE)
// 			{
// 				// 아머 적용 여부에 따른 확인
// 				CheckArmorState();
// 			}
			
			// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 해제
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 아이템 해제
			if( SHAPE_STAT_INIT_LEVEL < i_pItemGeneral->FixedTermShape.nStatLevel ) 
			{	// nStateLevel  >0 이면 외변킷이 적용된 아머 
				ITEM *pShapeKitItem = ms_pFieldIOCP->GetItemInfo(i_pItemGeneral->FixedTermShape.nStatShapeItemNum);
				if ( NULL != pShapeKitItem )
				{
					if ( TRUE == pShapeKitItem->IsExistDesParam(DES_ALL_PART) )
					{
						CheckAllState(pShapeKitItem->GetParameterValue(DES_ALL_PART)*min(i_pItemGeneral->FixedTermShape.nStatLevel, SHAPE_STAT_MAX_LEVEL), FALSE);
					}
				}
			}
#endif
			// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 해제
		}
		break;

	//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
	case POS_ACCESSORY_UNLIMITED :
		{
			if(ITEMKIND_ACCESSORY_UNLIMITED != i_pItemGeneral->Kind)
			{
				return;
			}
// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 아래와 같이 시스템 수정 및 변경됨
//			switch(i_pItemGeneral->ItemInfo->DestParameter1)
//			{
//			case DES_HP:
//				{
//					int nOverCount = max(0, m_character.CurrentHP - GetCharacterTotalHP());
//					this->ChangeHP(GetCharacterTotalHP());
// 					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//					m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, nOverCount, IUT_GENERAL);	// CurrentCount를 계산하기
//				}
//				break;
//			case DES_DP:
//				{
//					int nOverCount = max(0, m_character.CurrentDP - GetCharacterTotalDP());
//					this->ChangeDP(GetCharacterTotalDP());
// 					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//					m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, nOverCount, IUT_GENERAL);	// CurrentCount를 계산하기
//				}
//				break;
//			case DES_EP:
//				{
//					int nOverCount = max(0, m_character.CurrentEP - GetCharacterTotalEP());
//					this->ChangeEP(GetCharacterTotalEP());
// 					this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();
//					m_ItemManager.UpdateItemCountByPointer(i_pItemGeneral, nOverCount, IUT_GENERAL);	// CurrentCount를 계산하기
//				}
//				break;
//			default:// 2006-04-04 by cmkwon, 무제한 액세서리는 DES_HP, DES_DP, DES_EP만 유효함
//				{
//					char szErrLog[1024];
//					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnDetachItem DES_XX(%d) Error1!!\r\n", i_pItemGeneral->ItemInfo->DestParameter1);
//					g_pFieldGlobal->WriteSystemLog(szErrLog);
//					DbgOut(szErrLog);
//					return;
//				}
//			}
			///////////////////////////////////////////////////////////////////////////////
			// 2007-12-13 by cmkwon, 무제한 악세사리 다중기능 구현 - 기존에 채워주던 Current 값은 채워주지 않도록 수정함
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			this->UnsetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter1, i_pItemGeneral->ItemInfo->ParameterValue1);
// 			this->UnsetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter2, i_pItemGeneral->ItemInfo->ParameterValue2);
// 			this->UnsetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter3, i_pItemGeneral->ItemInfo->ParameterValue3);
// 			this->UnsetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->DestParameter4, i_pItemGeneral->ItemInfo->ParameterValue4);
			///////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, ResetAllSkillAndEnchant()로 이동
//			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
//			{
//				this->UnsetParamFactor_POS_ATTACHMENT(i_pItemGeneral->ItemInfo->ArrDestParameter[i], i_pItemGeneral->ItemInfo->ArrParameterValue[i]);
//			}
//
//			this->StoreDB_QPARAM_CHARACTER_CHANGE_STAT();	// 2007-12-13 by cmkwon, DB 에 저장을 위해

			
		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리 아이템 장착 해제
	case POS_ACCESSORY_TIME_LIMIT :
		{
			if(ITEMKIND_ACCESSORY_TIMELIMIT != i_pItemGeneral->Kind)
			{
				char szErrLog[1024];
				wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnDetachItem Kind(%d) Error2!!\r\n", i_pItemGeneral->Kind);
				g_pFieldGlobal->WriteSystemLog(szErrLog);
				DbgOut(szErrLog);
				return;
			}

			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//switch(i_pItemGeneral->ItemInfo->DestParameter1)
			switch(i_pItemGeneral->ItemInfo->ArrDestParameter[0])
			{
			case DES_DEFENSE_01:
			case DES_DEFENSE_02:
			case DES_DEFENSEPROBABILITY_01:
			case DES_DEFENSEPROBABILITY_02:
			case DES_MINATTACK_01:
			case DES_MAXATTACK_01:
			case DES_MINATTACK_02:
			case DES_MAXATTACK_02:
			case DES_DROP_EXP:
			case DES_DROP_SPI:
			case DES_DROP_ITEM:
			case DES_RARE_ITEM_DROP_RATE:	// 2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
			case DES_HP_REPAIR_RATE_FLIGHTING:
			case DES_DP_REPAIR_RATE:
			case DES_SP_REPAIR_RATE:
			case DES_ATTACK_RANGE_01:		// 2006-05-30 by cmkwon
			case DES_ATTACK_RANGE_02:		// 2006-05-30 by cmkwon
			case DES_PIERCE_UP_01:		// 2008-09-22 by dhjin, 신규 인첸트, 기본무기 피어스율 증가 카드
			case DES_PIERCE_UP_02:		// 2008-09-22 by dhjin, 신규 인첸트, 고급무기 피어스율 증가 카드
			case DES_ATTACKPROBABILITY_01:		// 2008-09-30 by dhjin, 신규 인첸트, 공격확률 01
			case DES_ATTACKPROBABILITY_02:		// 2008-09-30 by dhjin, 신규 인첸트, 공격확률 02
			case DES_RARE_ITEM_PARTNER_SPEED:	//	마을 이동 속도 증가 아이템 구현
				break;
				// 2012-09-20 by jhseol, 스텔스카드 악세사리 추가
			case DES_CASH_STEALTH:
				this->m_bStealthState	= FALSE;
				
				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));
				break;
				// end 2012-09-20 by jhseol, 스텔스카드 악세사리 추가
			default:
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnDetachItem DES1(%d) DES2 Error3!!\r\n", i_pItemGeneral->ItemInfo->ArrDestParameter[0], i_pItemGeneral->ItemInfo->ArrDestParameter[1]);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
			}
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			UnsetParamFactor(i_pItemGeneral->ItemInfo->DestParameter1, i_pItemGeneral->ItemInfo->ParameterValue1);
// 			UnsetParamFactor(i_pItemGeneral->ItemInfo->DestParameter2, i_pItemGeneral->ItemInfo->ParameterValue2);
// 			UnsetParamFactor(i_pItemGeneral->ItemInfo->DestParameter3, i_pItemGeneral->ItemInfo->ParameterValue3);
// 			UnsetParamFactor(i_pItemGeneral->ItemInfo->DestParameter4, i_pItemGeneral->ItemInfo->ParameterValue4);
			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
			{
				UnsetParamFactor(i_pItemGeneral->ItemInfo->ArrDestParameter[i], i_pItemGeneral->ItemInfo->ArrParameterValue[i]);
			}

			this->m_ItemManager.Stop8StoreFromUsingTimeLimitedItemList(i_pItemGeneral, i_bDeleteUsingTimeLimitedItem);

			// 2008-01-23 by cmkwon, S_F, S_L: 장착/장착해제 게임 로그에 추가 - 현재는 시간제한악세사리 아이템만 로그에 남긴다
			CAtumLogSender::SendLogMessageITEMDetachItem(this, i_pItemGeneral);

			///////////////////////////////////////////////////////////////////////////////
			// 클라이언트 사용중 아이템에서 삭제
			INIT_MSG_WITH_BUFFER(MSG_FC_STORE_DELETE_USINGITEM, T_FC_STORE_DELETE_USINGITEM, pSDUsingItem, SendBuf);
			pSDUsingItem->ItemNum			= i_pItemGeneral->ItemNum;
			pSDUsingItem->ItemDeletionType	= IUT_GENERAL;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_DELETE_USINGITEM));

			// 2006-03-31 by cmkwon, 아이템 사용된시간 업데이트
			INIT_MSG(MSG_FC_STORE_UPDATE_USINGITEM, T_FC_STORE_UPDATE_USINGITEM, pSMsg, SendBuf);
			pSMsg->ItemUID0			= i_pItemGeneral->UniqueNumber;
			pSMsg->UsingTimeStamp0	= i_pItemGeneral->UsingTimeStamp;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_USINGITEM));
		}
		break;
	// 2010-12-21 by jskim, 마을 이동 속도 증가 아이템 구현
	case POS_PET :
		{
			if(ITEMKIND_PET_ITEM != i_pItemGeneral->Kind)
			{
				char szErrLog[1024];
				wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnDetachItem Kind(%d) Error2!!\r\n", i_pItemGeneral->Kind);
				g_pFieldGlobal->WriteSystemLog(szErrLog);
				DbgOut(szErrLog);
				return;
			}
			
			///////////////////////////////////////////////////////////////////////////////////////
			// start 2011-09-20 by hskim, 파트너 시스템 2차
			// 장착된 소켓 버프 삭제

			mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	
			tPET_CURRENTINFO *pPetInfo = m_ItemManager.GetItemPetByUID(i_pItemGeneral->UniqueNumber);

			if( NULL != pPetInfo )
			{
				for(int a=0; a<pPetInfo->PetEnableSocketCount; a++)
				{
					ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pPetInfo->PetSocketItemUID[a]);
					
					if( NULL != pItemG )
					{
						PetCancelSocketItem(pItemG->ItemInfo);
					}
				}
			}

			igLock.auto_unlock_cancel();

			// end 2011-09-20 by hskim, 파트너 시스템 2차
			///////////////////////////////////////////////////////////////////////////////////////


			switch(i_pItemGeneral->ItemInfo->ArrDestParameter[0])
			{
			case DES_RARE_ITEM_PARTNER_SPEED:	//	마을 이동 속도 증가 아이템 구현
				break;
			default:
				{
					char szErrLog[1024];
					wsprintf(szErrLog, "[Error] CFieldIOCPSocket::OnDetachItem DES1(%d) DES2 Error3!!\r\n", i_pItemGeneral->ItemInfo->ArrDestParameter[0], i_pItemGeneral->ItemInfo->ArrDestParameter[1]);
					g_pFieldGlobal->WriteSystemLog(szErrLog);
					DbgOut(szErrLog);
					return;
				}
			}
			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
			{
				UnsetParamFactor(i_pItemGeneral->ItemInfo->ArrDestParameter[i], i_pItemGeneral->ItemInfo->ArrParameterValue[i]);
			}
			
			this->m_ItemManager.Stop8StoreFromUsingTimeLimitedItemList(i_pItemGeneral, i_bDeleteUsingTimeLimitedItem);
			
			CAtumLogSender::SendLogMessageITEMDetachItem(this, i_pItemGeneral);
			
			///////////////////////////////////////////////////////////////////////////////
			// 클라이언트 사용중 아이템에서 삭제
			INIT_MSG_WITH_BUFFER(MSG_FC_STORE_DELETE_USINGITEM, T_FC_STORE_DELETE_USINGITEM, pSDUsingItem, SendBuf);
			pSDUsingItem->ItemNum			= i_pItemGeneral->ItemNum;
			pSDUsingItem->ItemDeletionType	= IUT_GENERAL;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_DELETE_USINGITEM));
			
			// 2006-03-31 by cmkwon, 아이템 사용된시간 업데이트
			INIT_MSG(MSG_FC_STORE_UPDATE_USINGITEM, T_FC_STORE_UPDATE_USINGITEM, pSMsg, SendBuf);
			pSMsg->ItemUID0			= i_pItemGeneral->UniqueNumber;
			pSMsg->UsingTimeStamp0	= i_pItemGeneral->UsingTimeStamp;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_USINGITEM));
		}
		break;
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ITEM_GENERAL *CFieldIOCPSocket::GetAttachItemGeneralByPosition(int i_position)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-06 ~ 2005-12-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ITEM_GENERAL *CFieldIOCPSocket::GetAttachItemGeneralByPosition(int i_position)
{
	ITEM *pRetItem = NULL;
	switch (i_position)
	{
		case POS_PROW:					pRetItem = &m_ItemProw;				break;
		case POS_PROWIN:				pRetItem = &m_ItemProwIn;			break;
		case POS_PROWOUT:				pRetItem = &m_ItemProwOut;			break;
		case POS_WINGIN:				pRetItem = &m_ItemWingIn;			break;	// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
		case POS_WINGOUT:				pRetItem = &m_ItemWingOut;			break;
		case POS_CENTER:				pRetItem = &m_ItemCenter;			break;
		case POS_REAR:					pRetItem = &m_ItemRear;				break;

		//case POS_ATTACHMENT:			pRetItem = &m_ItemAttachment;		break;	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
		case POS_ACCESSORY_UNLIMITED :	pRetItem = &m_ItemAccessoryUnLimited;	break;	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물

		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		//case POS_PET:			pRetItem = &m_ItemPet;				break;	// 2006-03-30 by cmkwon, 시간제한 악세사리
		case POS_ACCESSORY_TIME_LIMIT :	pRetItem = &m_ItemAccessoryTimeLimit;	break;	// 2006-03-30 by cmkwon, 시간제한 악세사리

		// 2010-06-15 by shcho&hslee 펫시스템 - 팻 슬롯 처리 추가.
		case POS_PET :					pRetItem = &m_ItemPet;				break;

		case POS_HIDDEN_ITEM:		// 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템
		default:
			{
				return NULL;
			}
	}// end_switch (i_position)

	if(0 == pRetItem->ItemNum)
	{
		return NULL;
	}

	return (ITEM_GENERAL*)(pRetItem->ItemNum);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::ProcessItemChangeWindowPosition(MSG_FC_ITEM_CHANGE_WINDOW_POSITION *i_pItemChangeWindowPos, BOOL i_bDeleteUsingTimeLimitedItem/*=TRUE*/)
/// \brief		
///				// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::ProcessItemChangeWindowPosition# 인자추가(i_bNoValidCheck)
/// \author		cmkwon
/// \date		2006-03-31 ~ 2006-03-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::ProcessItemChangeWindowPosition(MSG_FC_ITEM_CHANGE_WINDOW_POSITION *i_pItemChangeWindowPos
																, BOOL i_bDeleteUsingTimeLimitedItem/*=TRUE*/
																, BOOL i_bNoValidCheck/*=TRUE*/)
{
	// lock m_mapItemGeneral, MSG_FC_ITEM_CHANGE_WINDOW_POSITION
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	ITEM_GENERAL *pFromItemGeneral = m_ItemManager.GetItemGeneralByUID(i_pItemChangeWindowPos->FromItemUniqueNumber);
	if (pFromItemGeneral == NULL)
	{
		SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_NO_SUCH_ITEM, i_pItemChangeWindowPos->FromItemUniqueNumber, 0, m_character.CharacterName);
		return RES_BREAK;
	}
	ITEM *pFromItemInfo = pFromItemGeneral->ItemInfo;

	// 2014-02-07 by jhseol, 캐나다 메모리핵 사용 기어타입 변경 후 아이템 장착 시도 보안
	if ( NULL != pFromItemInfo )
	{
		if ( FALSE == IS_SAME_UNITKIND(m_character.UnitKind, pFromItemInfo->ReqUnitKind) )
		{
			if( FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER) )
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED);
				return RES_BREAK;
			}
			else	// 관리자는 에러 스트링만 던진다.
			{
				SendString128(STRING_128_ADMIN_CMD, STRMSG_130531_0010);
			}
		}
	}
	// end 2014-02-07 by jhseol, 캐나다 메모리핵 사용 기어타입 변경 후 아이템 장착 시도 보안

	if(FALSE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pFromItemInfo->ItemAttribute, ITEM_ATTR_ONLY_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵에서만 사용 가능
		SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_INFINITY_ONLY_USE_ITEM);
		return RES_BREAK;
	}

	ITEM_GENERAL *pToItemGeneral = NULL;
	if (i_pItemChangeWindowPos->ToItemUniqueNumber != 0)
	{
		pToItemGeneral = m_ItemManager.GetItemGeneralByUID(i_pItemChangeWindowPos->ToItemUniqueNumber);
		if (pToItemGeneral == NULL)
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_NO_SUCH_ITEM, i_pItemChangeWindowPos->ToItemUniqueNumber, 0, m_character.CharacterName);
			return RES_BREAK;
		}
	}

	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::ProcessItemChangeWindowPosition#, 
	if(i_bNoValidCheck)
	{
	//#ifdef _DEBUG
	//	DBGOUT("ITEM_CHANGE_WIND_POS\r\n");
	//	DBGOUT("Server: %s %s\r\n", GetItemGeneralString(pFromItemGeneral, string()), GetItemGeneralString(pToItemGeneral, string()));
	//	DBGOUT("Client: %d %d %d %d\r\n", i_pItemChangeWindowPos->FromItemUniqueNumber, i_pItemChangeWindowPos->FromItemWindowIndex
	//									, i_pItemChangeWindowPos->ToItemUniqueNumber, i_pItemChangeWindowPos->ToItemWindowIndex);
	//#endif

		if (i_pItemChangeWindowPos->FromItemWindowIndex < POS_ITEMWINDOW_OFFSET
			&& (i_pItemChangeWindowPos->FromItemUniqueNumber != pFromItemGeneral->UniqueNumber
				|| i_pItemChangeWindowPos->FromItemWindowIndex != pFromItemGeneral->ItemWindowIndex)
			)
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION
				, i_pItemChangeWindowPos->FromItemUniqueNumber == pFromItemGeneral->UniqueNumber
				, i_pItemChangeWindowPos->FromItemWindowIndex == pFromItemGeneral->ItemWindowIndex
				, "1");
			return RES_BREAK;
		}

		if (i_pItemChangeWindowPos->ToItemUniqueNumber != 0
			&& i_pItemChangeWindowPos->ToItemWindowIndex < POS_ITEMWINDOW_OFFSET
			&& (i_pItemChangeWindowPos->ToItemUniqueNumber != pToItemGeneral->UniqueNumber
				|| i_pItemChangeWindowPos->ToItemWindowIndex != pToItemGeneral->ItemWindowIndex)
			)
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION
				, i_pItemChangeWindowPos->ToItemUniqueNumber == pToItemGeneral->UniqueNumber
				, i_pItemChangeWindowPos->ToItemWindowIndex == pToItemGeneral->ItemWindowIndex
				, "2");
			return RES_BREAK;
		}

		// 2006-01-24 by cmkwon, 랙으로 인해 유저가 같은 아이템 장착 두번 요청시 처리
		if(pFromItemGeneral->ItemWindowIndex == i_pItemChangeWindowPos->ToItemWindowIndex)
		{
	// 2006-06-21 by cmkwon, 일단 재전송하지 않은것으로 처리, 추후에 정식방식으로 처리 해야함
	// 		// Send MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK
	// 		INIT_MSG_OF_SIZE(MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK, T_FC_ITEM_CHANGE_WINDOW_POSITION_OK, pMsgChangeOK, pMsgChangeOKBuf);
	// 		pMsgChangeOK->UniqueNumber		= pFromItemGeneral->UniqueNumber;
	// 		pMsgChangeOK->ItemWindowIndex	= pFromItemGeneral->ItemWindowIndex;
	// 		pMsgChangeOK->Wear				= pFromItemGeneral->Wear;
	// 		if (pToItemGeneral != NULL)
	// 		{
	// 			pMsgChangeOK->UniqueNumberDest		= pToItemGeneral->UniqueNumber;
	// 			pMsgChangeOK->ItemWindowIndexDest	= pToItemGeneral->ItemWindowIndex;
	// 			pMsgChangeOK->WearDest				= pToItemGeneral->Wear;
	// 		}
	// 		else
	// 		{
	// 			pMsgChangeOK->UniqueNumberDest		= 0;
	// 			pMsgChangeOK->ItemWindowIndexDest	= i_pItemChangeWindowPos->FromItemWindowIndex;
	// 			pMsgChangeOK->WearDest				= 0;
	// 		}
	// 		SendAddData(pMsgChangeOKBuf, MSG_SIZE(MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK));
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2006-09-20 by cmkwon, 아이템 장착 체크
		if(i_pItemChangeWindowPos->FromItemWindowIndex < POS_ITEMWINDOW_OFFSET)
		{
			ITEM_GENERAL *pAttachedItemG = this->GetAttachItemGeneralByPosition(i_pItemChangeWindowPos->FromItemWindowIndex);
			if(NULL == pAttachedItemG
				|| pAttachedItemG->UniqueNumber != i_pItemChangeWindowPos->FromItemUniqueNumber)
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION
					, i_pItemChangeWindowPos->FromItemUniqueNumber == pFromItemGeneral->UniqueNumber
					, i_pItemChangeWindowPos->FromItemWindowIndex == pFromItemGeneral->ItemWindowIndex
					, "3");
				return RES_BREAK;
			}
		}
		if(i_pItemChangeWindowPos->ToItemWindowIndex < POS_ITEMWINDOW_OFFSET)
		{
			ITEM_GENERAL *pAttachedItemG = this->GetAttachItemGeneralByPosition(i_pItemChangeWindowPos->ToItemWindowIndex);
			if( (NULL == pAttachedItemG && 0 != i_pItemChangeWindowPos->ToItemUniqueNumber)
				|| (pAttachedItemG && pAttachedItemG->UniqueNumber != i_pItemChangeWindowPos->ToItemUniqueNumber)
				)
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION
					, i_pItemChangeWindowPos->FromItemUniqueNumber == pFromItemGeneral->UniqueNumber
					, i_pItemChangeWindowPos->FromItemWindowIndex == pFromItemGeneral->ItemWindowIndex
					, "4");
				return RES_BREAK;
			}
		}


		// 잘못된 아이템 위치로의 이동을 확인함
		if (i_pItemChangeWindowPos->ToItemWindowIndex < POS_ITEMWINDOW_OFFSET )
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2008-08-26 by cmkwon, ItemAttribute 추가 - GM용 아이템, 체크
			if(COMPARE_BIT_FLAG(pFromItemInfo->ItemAttribute, ITEM_ATTR_FOR_ONLY_GAME_MASTER)
				&& FALSE == COMPARE_RACE(m_character.Race, RACE_GAMEMASTER))
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_RACE_PERMISSION_DENIED, pFromItemInfo->ItemAttribute);
				return RES_BREAK;
			}

			if (FALSE == CheckItemWindowPosition(i_pItemChangeWindowPos->ToItemWindowIndex, pFromItemInfo))
			{
				// error
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0063, pFromItemInfo->ItemName);
				return RES_BREAK;
			}

			if (!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))	// 관리자는 확인 안 함
			{
				Err_t err = CheckGeneralItemRequirements(pFromItemGeneral);
				if (err != ERR_NO_ERROR)
				{
					SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, err);
					return RES_BREAK;
				}
			}

			Err_t err = CheckAttachableItem(i_pItemChangeWindowPos->ToItemWindowIndex, pFromItemGeneral);
			if(ERR_NO_ERROR != err)
			{// 2006-03-30 by cmkwon, 아이템 장착 가능여부 체크
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, err);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_CHANGE_WINDOW_POSITION
			INT nExcludeItemNum = (NULL == pToItemGeneral) ? 0 : pToItemGeneral->ItemInfo->ItemNum;
			ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pFromItemInfo, nExcludeItemNum);
			if(pUsingItemInfo)
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_ALREADY_USE_ITEMPARAM, pFromItemInfo->ItemNum, pUsingItemInfo->ItemNum);
				return RES_BREAK;
			}
		}

		// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함 - 아이템 장착시만 무게게이지 체크
		if (i_pItemChangeWindowPos->ToItemWindowIndex < POS_ITEMWINDOW_OFFSET
			&& !COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
		{
			float fItemWeight = CAtumSJ::GetItemWeight(pFromItemInfo, 1, pFromItemGeneral->DesWeight);
			if(pToItemGeneral)
			{
				fItemWeight -= CAtumSJ::GetItemWeight(pToItemGeneral->ItemInfo, 1, pToItemGeneral->DesWeight);
			}
			if (GetCurrentLoadagePercentage(fItemWeight) > 1.0f)
			{
				SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_ITEM_OVER_WEIGHT,
									(INT)m_ItemManager.GetCurrentCarryingItemWeight()+fItemWeight,
									(INT)CAtumSJ::GetTransport(&m_character));
				return RES_BREAK;
			}
		}
		
	// 2005-11-15 by cmkwon, 아래 코드로 변경됨
	//	// 격납고가 아니면, 엔진은 내릴 수 없음, 격납고에서 나갈 때 엔진 장착 확인은 클라이언트에서 확인함. 20041124, kelovon w/ dhkwon
	//	if (!IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
	//		&& pFromItemInfo->Kind == ITEMKIND_SUPPORT
	//		&& (i_pItemChangeWindowPos->ToItemWindowIndex >= POS_ITEMWINDOW_OFFSET && i_pItemChangeWindowPos->ToItemUniqueNumber == 0)
	//	)
	//	{
	//		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0064);
	//		return RES_BREAK;
	//	}
		if( pFromItemInfo->Kind == ITEMKIND_SUPPORT
			&& (i_pItemChangeWindowPos->ToItemWindowIndex >= POS_ITEMWINDOW_OFFSET && i_pItemChangeWindowPos->ToItemUniqueNumber == 0)
			&& (FALSE == this->IsCityCurrentFieldMapChannel() || FALSE == m_character.CharacterMode) )
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0064);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-03 by cmkwon, 아머는 작착 해제 할 수 없다. 교체만 가능함. 도시맵에서는 장착 해제 가능함
		if( ITEMKIND_DEFENSE == pFromItemGeneral->Kind
			&& (i_pItemChangeWindowPos->ToItemWindowIndex >= POS_ITEMWINDOW_OFFSET && i_pItemChangeWindowPos->ToItemUniqueNumber == 0)
			&& (FALSE == this->IsCityCurrentFieldMapChannel() || FALSE == m_character.CharacterMode) )
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_CANNOT_UNWEAR_ARMOR);
			return RES_BREAK;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-05-02 by dhjin, 아레나 상태에서는 지도자의 광휘 아이템을 장착 할 수 없다. 해제는 가능
		if(ARENA_STATE_NONE != this->m_ArenaInfo.State
			&& (ITEM_NUM_BRIGHTNESS_OF_BCU_LEADER == pFromItemInfo->ItemNum || ITEM_NUM_BRIGHTNESS_OF_ANI_LEADER == pFromItemInfo->ItemNum)
// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - 
//			&& i_pItemChangeWindowPos->ToItemWindowIndex < POS_INVALID_POSITION)
			&& IS_ATTACHABLE_POSITION(i_pItemChangeWindowPos->ToItemWindowIndex))
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_PROTOCOL_INVALID_ITEM_WINDOW_POSITION);
			return RES_BREAK;
		}
	} // END - if(i_bNoValidCheck)
	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::ProcessItemChangeWindowPosition#,
	


	///////////////////////////////////////////////////////////////////////////
	// 아이템 이동시 적용사항 적용
	///////////////////////////////////////////////////////////////////////////

	// Primary 무기
	if ( i_pItemChangeWindowPos->ToItemWindowIndex == POS_PROWOUT
		|| i_pItemChangeWindowPos->FromItemWindowIndex == POS_PROWOUT)
	{
		///////////////////////////////////////////////////////////////////////////
		// DB에 현재의 Bullet Count를 저장한다.
		SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemProwOut.ItemNum);
	}

	// Secondary 무기
	if ( i_pItemChangeWindowPos->ToItemWindowIndex == POS_WINGOUT
		|| i_pItemChangeWindowPos->FromItemWindowIndex == POS_WINGOUT
	)
	{
		// 쉴드(SHIELD)를 내리면 끄기
		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_SHIELD_MASK)
			&& m_ItemWingOut.Kind == ITEMKIND_SHIELD
		)
		{
			StopItemKindShield( ((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->ItemInfo );
		}

		// Decoy를 내리면 끄기
		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DECOY_MASK)
			&& m_ItemWingOut.Kind == ITEMKIND_DECOY
		)
		{
			StopItemKindDecoy( ((ITEM_GENERAL*)m_ItemWingOut.ItemNum)->ItemInfo );
		}

		///////////////////////////////////////////////////////////////////////////
		// DB에 현재의 Bullet Count를 저장한다.
		SaveCurrentBulletCount((ITEM_GENERAL*)m_ItemWingOut.ItemNum);
	}

	///////////////////////////////////////////////////////////////////////////
	// Item 정보 갱신
	pFromItemGeneral->ItemWindowIndex = i_pItemChangeWindowPos->ToItemWindowIndex;
	SetWear(pFromItemGeneral);

	if (pToItemGeneral != NULL)
	{
		pToItemGeneral->ItemWindowIndex = i_pItemChangeWindowPos->FromItemWindowIndex;
		SetWear(pToItemGeneral);
	}
	// end - Item 정보 갱신
	///////////////////////////////////////////////////////////////////////////

	UpdateWearItemPointer(
		i_pItemChangeWindowPos->FromItemUniqueNumber,
		i_pItemChangeWindowPos->ToItemUniqueNumber,
		i_pItemChangeWindowPos->FromItemWindowIndex,
		i_pItemChangeWindowPos->ToItemWindowIndex
	);

	// Send MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK
	INIT_MSG_OF_SIZE(MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK, T_FC_ITEM_CHANGE_WINDOW_POSITION_OK, pMsgChangeOK, pMsgChangeOKBuf);
	pMsgChangeOK->UniqueNumber		= pFromItemGeneral->UniqueNumber;
	pMsgChangeOK->ItemWindowIndex	= pFromItemGeneral->ItemWindowIndex;
	pMsgChangeOK->Wear				= pFromItemGeneral->Wear;
	if (pToItemGeneral != NULL)
	{
		pMsgChangeOK->UniqueNumberDest		= pToItemGeneral->UniqueNumber;
		pMsgChangeOK->ItemWindowIndexDest	= pToItemGeneral->ItemWindowIndex;
		pMsgChangeOK->WearDest				= pToItemGeneral->Wear;
	}
	else
	{
		pMsgChangeOK->UniqueNumberDest		= 0;
		pMsgChangeOK->ItemWindowIndexDest	= i_pItemChangeWindowPos->FromItemWindowIndex;
		pMsgChangeOK->WearDest				= 0;
	}
	SendAddData(pMsgChangeOKBuf, MSG_SIZE(MSG_FC_ITEM_CHANGE_WINDOW_POSITION_OK));
	
	// 장착 아이템의 위치 변동이 일어났을 때
	if (i_pItemChangeWindowPos->FromItemWindowIndex < MAX_EQUIP_POS)		// 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템
	{
		UpdateItemRenderInfo(i_pItemChangeWindowPos->FromItemWindowIndex, TRUE);
	}
	if (i_pItemChangeWindowPos->ToItemWindowIndex < MAX_EQUIP_POS)			// 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템
	{
		UpdateItemRenderInfo(i_pItemChangeWindowPos->ToItemWindowIndex, TRUE);
	}

// 2006-04-04 by cmkwon, OnAttachItem(),OnDetachItem() 함수 내에서 처리함
// 	// 연료 탱크(ITEMKIND_TANK) 적용
// 	if ( i_pItemChangeWindowPos->ToItemWindowIndex == POS_ATTACHMENT
// 		|| i_pItemChangeWindowPos->FromItemWindowIndex == POS_ATTACHMENT)
// 	{
// 		ITEM_GENERAL *pItemGeneralAttachment = (ITEM_GENERAL*)m_ItemAttachment.ItemNum;
// 		if (NULL == pItemGeneralAttachment)
// 		{// 연료탱크 장착을 해제한다
// 
// 			m_character.EP = CAtumSJ::GetCharacterEP(m_character.TotalGearStat.FuelPart);
// 			int nCountOfTank = m_character.CurrentEP - m_character.EP;
// 			m_character.CurrentEP = min(m_character.CurrentEP, m_character.EP);
// 			m_ItemManager.UpdateItemCountByPointer(pFromItemGeneral, max(0, nCountOfTank), IUT_GENERAL);	// 연료 탱크 채우기
// 		}
// 		else
// 		{// 연료탱크를 장착한다
// 			m_character.EP = CAtumSJ::GetCharacterEP(m_character.TotalGearStat.FuelPart) + (SHORT)m_ItemAttachment.Charging;
// 			ChangeCurrentEP(pItemGeneralAttachment->CurrentCount);
// 			m_ItemManager.UpdateItemCountByPointer(pItemGeneralAttachment, -pItemGeneralAttachment->CurrentCount, IUT_GENERAL);	// 연료 탱크 Count를 0으로 만들기
// 		}
// 		SendCharacterInfo(T_FC_CHARACTER_CHANGE_HPDPSPEP);
// 		SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
// 
// 		// update db
// 		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);
// 
// 		// 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);
// 	}

#ifdef _DEBUG
	SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0065,
						i_pItemChangeWindowPos->FromItemUniqueNumber,
						i_pItemChangeWindowPos->FromItemWindowIndex,
						i_pItemChangeWindowPos->ToItemUniqueNumber,
						i_pItemChangeWindowPos->ToItemWindowIndex);
#endif

	///////////////////////////////////////////////////////////////////////////
	// 앞으로 아이템 장/탈착 관련 처리는 OnAttachItem, OnDetachItem에서 처리
	// 20041206, kelovon
	///////////////////////////////////////////////////////////////////////////
	Err_t errCode	= ERR_NO_ERROR;	// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
	if (i_pItemChangeWindowPos->FromItemWindowIndex < MAX_EQUIP_POS && i_pItemChangeWindowPos->ToItemWindowIndex >= POS_ITEMWINDOW_OFFSET)		// 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템
	{
		// 장착 아이템을 내릴 때
		OnDetachItem(pFromItemGeneral, i_pItemChangeWindowPos->FromItemWindowIndex, TRUE, i_bDeleteUsingTimeLimitedItem);
	}
	else if (i_pItemChangeWindowPos->FromItemWindowIndex >= POS_ITEMWINDOW_OFFSET && i_pItemChangeWindowPos->ToItemUniqueNumber == 0)
	{
		// 아이템을 장착할 때, 대상 위치에 아이템이 없음
		OnAttachItem(pFromItemGeneral, i_pItemChangeWindowPos->ToItemWindowIndex);
	}
	else if (i_pItemChangeWindowPos->FromItemWindowIndex >= POS_ITEMWINDOW_OFFSET && i_pItemChangeWindowPos->ToItemWindowIndex != 0)
	{
		// 아이템을 장착할 때, 대상 위치에 아이템이 있음
		OnDetachItem(pToItemGeneral, i_pItemChangeWindowPos->ToItemWindowIndex, FALSE, i_bDeleteUsingTimeLimitedItem);
		OnAttachItem(pFromItemGeneral, i_pItemChangeWindowPos->ToItemWindowIndex);
	}
	else
	{
		SendString128(STRING_128_ADMIN_CMD, STRMSG_S_F2NOTIFY_0066,
							i_pItemChangeWindowPos->FromItemUniqueNumber,
							i_pItemChangeWindowPos->FromItemWindowIndex,
							i_pItemChangeWindowPos->ToItemUniqueNumber,
							i_pItemChangeWindowPos->ToItemWindowIndex);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
	this->OnUpdateWearItem(i_pItemChangeWindowPos->FromItemUniqueNumber, i_pItemChangeWindowPos->ToItemUniqueNumber, i_pItemChangeWindowPos->FromItemWindowIndex, i_pItemChangeWindowPos->ToItemWindowIndex);

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Main서버와 아이템 동기화를 위한 처리
	this->m_ItemManager.ItemUpdateByInfinityPlaying(pFromItemGeneral);
	this->m_ItemManager.ItemUpdateByInfinityPlaying(pToItemGeneral);


	///////////////////////////////////////////////////////////////////////////
	// Update DB
	QPARAM_CHANGE_ITEM_WINDOW_POSITION *pQParamChangeWindowPosition
				= new QPARAM_CHANGE_ITEM_WINDOW_POSITION;
	pQParamChangeWindowPosition->AccountUID			= m_character.AccountUniqueNumber;
	pQParamChangeWindowPosition->CharacterUID		= m_character.CharacterUniqueNumber;
	pQParamChangeWindowPosition->ItemUID1			= pFromItemGeneral->UniqueNumber;
	pQParamChangeWindowPosition->ItemWindowIndex1	= pFromItemGeneral->ItemWindowIndex;
	pQParamChangeWindowPosition->ItemWear1			= pFromItemGeneral->Wear;
	if (pToItemGeneral != NULL)
	{
		pQParamChangeWindowPosition->ItemUID2			= pToItemGeneral->UniqueNumber;
		pQParamChangeWindowPosition->ItemWindowIndex2	= pToItemGeneral->ItemWindowIndex;
		pQParamChangeWindowPosition->ItemWear2			= pToItemGeneral->Wear;
	}
	else
	{
		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);

	return RES_RETURN_TRUE;
}


// 2007-08-09 by cmkwon, 모든 세력에 채팅 전송하기 - 인자추가(, char *i_szChatMsg=NULL)
Err_t CFieldIOCPSocket::ApplyCardItem(ITEM *i_pItemInfo, BOOL i_bUseFlag/*=FALSE*/, char *i_szChatMsg/*=NULL*/)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-05 by cmkwon, 몬스터변신관련 해제 카드 구현 - 
	if(i_pItemInfo->IsExistDesParam(DES_TRANSFORM_TO_GEAR))
	{
		// 2010-04-05 by cmkwon, 몬스터변신관련 해제 카드 구현 - 2010-04-16 by cmkwon, 빠진사항 추가 수정
		if(NULL == m_ItemManager.FindUsingItemByDestParameterNoLock(DES_TRANSFORM_TO_MONSTER))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyCardItem# %s can't use DES_TRANSFORM_TO_GEAR 01000 ItemInfo(%8d:%s) CurMon(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), i_pItemInfo->ItemNum, i_pItemInfo->ItemName, m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer);
			return ERR_PROTOCOL_CANNOT_USE_ITEM;
		}
		else
		{
			m_ItemManager.DeleteUsingTimeLimitedItemListByDestParameter(DES_TRANSFORM_TO_MONSTER);
		}		
		return ERR_NO_ERROR;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - CFieldIOCPSocket::ApplyCardItem#, 적용처리
	if(i_pItemInfo->IsExistDesParam(DES_TRANSFORM_TO_MONSTER))
	{
		INT monUnitKind = (INT)(i_pItemInfo->GetParameterValue(DES_TRANSFORM_TO_MONSTER));
		if(NULL == ms_pFieldIOCP->GetMonsterInfo(monUnitKind))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyCardItem# %s 10000 ItemInfo(%8d:%s) MonsterUnitKind(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), i_pItemInfo->ItemNum, i_pItemInfo->ItemName, monUnitKind);
			return ERR_PROTOCOL_NO_SUCH_MONSTER_INFO;
		}
		if(FALSE == this->UpdateItemRenderInfoForTransformer(monUnitKind, TRUE))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ApplyCardItem# %s 20000 ItemInfo(%8d:%s) CurMon(%d) NewMon(%d) \r\n"
				, GetCharacterString(GetCharacter(), string()), i_pItemInfo->ItemNum, i_pItemInfo->ItemName, m_UnitRenderInfo.RI_MonsterUnitKind_ForTransformer, monUnitKind);
			return ERR_PROTOCOL_ALREADY_USE_ITEM;
		}
	}

	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
	//switch(i_pItemInfo->DestParameter1)
	switch(i_pItemInfo->ArrDestParameter[0])
	{
	case DES_CASH_STEALTH:			// 스텔스 카드 - 7010260
		{
			this->m_bStealthState	= 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();		// 2013-05-09 by hskim, 세력 포인트 개선
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
		}
		break;
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 	case DES_CASH_HP_AND_DP_UP:		// 고급/중급/초급 에너지/쉴드 키트 - 7010350/7010360/7010370
// 		{
// 			m_nPlusHP		= 0;
// 			m_nPlusDP		= 0;
// // 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// // 			if(DES_HP == i_pItemInfo->DestParameter2)
// // 			{
// // 				m_nPlusHP	= i_pItemInfo->ParameterValue2;
// // 			}
// // 			if(DES_DP == i_pItemInfo->DestParameter3)
// // 			{
// // 				m_nPlusDP	= i_pItemInfo->ParameterValue3;
// // 			}
// 			if(DES_HP == i_pItemInfo->ArrDestParameter[1])
// 			{
//  				m_nPlusHP	= i_pItemInfo->ArrParameterValue[1];
// 			}
// 			if(DES_DP == i_pItemInfo->ArrDestParameter[2])
// 			{
//  				m_nPlusDP	= i_pItemInfo->ArrParameterValue[2];
// 			}
// 
// 			ChangeHP(GetCharacterTotalHP());
// 			ChangeDP(GetCharacterTotalDP());
// 
// 			if(i_bUseFlag
// 				&& IsValidCharacter())
// 			{
// 				m_character.CurrentHP	= m_character.HP;		// 만피 시켜주기
// 				SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHP);
// 				
// 				m_character.CurrentDP	= m_character.DP;
// 				SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTDP);
// 			}
// 		}
// 		break;
 	case DES_CASH_HP_AND_DP_UP:		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, // 고급/중급/초급 에너지/쉴드 키트 - 7010350/7010360/7010370
	case DES_MINATTACK_01:
	case DES_MAXATTACK_01:
	case DES_MINATTACK_02:
	case DES_MAXATTACK_02:
	case DES_ATTACKPROBABILITY_01:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 아드레날린캡슐
	case DES_ATTACKPROBABILITY_02:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 아드레날린캡술
	case DES_DEFENSE_01:					// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSE_02:					// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSEPROBABILITY_01:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSEPROBABILITY_02:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_HP_REPAIR_RATE_FLIGHTING:		// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 160, // 2006-09-29 by cmkwon, 보조스킬아이템 - 에너지캡슐
	case DES_DP_REPAIR_RATE:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 161, // 2006-09-29 by cmkwon, 보조스킬아이템 - 쉴드캡슐
	case DES_SP_REPAIR_RATE:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 162, // 2006-09-29 by cmkwon, 보조스킬아이템 - SP캡슐
	case DES_DROP_EXP:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 157
	case DES_DROP_SPI:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 158
	case DES_DROP_ITEM:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 159
	case DES_RARE_ITEM_DROP_RATE:			// 2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
	case DES_PIERCE_UP_01:					// 2009-12-21 by cmkwon, 일본 Arario 기능 추가 구현 아이템 - 
	case DES_PIERCE_UP_02:					// 2009-12-21 by cmkwon, 일본 Arario 기능 추가 구현 아이템 - 
	case DES_ITEM_RESISTANCE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 저항 아이템 사용 체크 
	case DES_ITEM_ADDATTACK:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 사용 체크 
	case DES_ITEM_IGNOREDEFENCE:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 방어력 무시 아이템 사용 체크
	case DES_ITEM_IGNOREAVOID:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 회피력 무시 아이템 사용 체크
	case DES_ITEM_REDUCEDAMAGE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 절대값 감소 아이템 사용 체크
	case DES_ITEM_ADDATTACK_SEC:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류)
	case DES_ITEM_ONCE_RESISTANCE:			// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가 
	case DES_ENGINE_MAX_SPEED_UP:			// 2010-02-26 by cmkwon, 일본 Arario 기능 추가 구현 요청(엔진관련) - 
	case DES_MAX_SP_UP:						// 2010-08-26 by shcho&jsKim, 밤 아이템 구현
		{
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			this->SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter1, i_pItemInfo->ParameterValue1);
// 			this->SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter2, i_pItemInfo->ParameterValue2);
// 			this->SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter3, i_pItemInfo->ParameterValue3);
// 			this->SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter4, i_pItemInfo->ParameterValue4);
			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
			{
				this->SetParamFactor(&m_ParamFactor, i_pItemInfo->ArrDestParameter[i], i_pItemInfo->ArrParameterValue[i]);
			}
		}
		break;
// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 위로 같이 추가 함.
// 	case DES_HP_REPAIR_RATE_FLIGHTING:		// 2006-09-29 by cmkwon, 보조스킬아이템 - 에너지캡슐
// 	case DES_DP_REPAIR_RATE:				// 2006-09-29 by cmkwon, 보조스킬아이템 - 쉴드캡슐
// 	case DES_SP_REPAIR_RATE:				// 2006-09-29 by cmkwon, 보조스킬아이템 - SP캡슐
// 		{
// 			this->SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter1, i_pItemInfo->ParameterValue1);
// 		}
		break;
	case DES_HYPER_BOOSTER:					// 2006-10-11 by cmkwon, 보조스킬아이템 - 하이퍼부스터 
		{// 2006-10-11 by cmkwon, 서버에서는 처리 할것이 없음 , 부스터 관련은 클라이언트에서 처리
		}
		break;
	case DES_SKILL_SCANNING:				// 2007-04-17 by cmkwon, 144		// Invisible 상태의 유저를 볼 수 있도록 한다
		// 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
#ifdef SC_SEARCHEYE_SHUTTLE_POSITION_JHSEOL_MSPARK
		if( 15000 > i_pItemInfo->Time )		// 지속시간이 15초보다 작으면 일반 서치아이
		{
			m_structUsingItemBitFlag.bSearchEye_1	= TRUE;		// 서치아이 아이템 사용중인 상태 FLAG (FALSE : 미사용, TRUE : 사용)
		}
		else
		{   
			m_structUsingItemBitFlag.bSearchEye_2	= TRUE;		// 서치아이 아이템 사용중인 상태 FLAG (FALSE : 미사용, TRUE : 사용)
		}
#endif
		// end 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
	case DES_ATTACK_RANGE_01:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 서버는 처리 필요 없음
	case DES_ATTACK_RANGE_02:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 서버는 처리 필요 없음
		{// 2007-04-17 by cmkwon, 서버에서는 처리 할것이 없음, 기능은 클라이언트에서 처리
		}
		break;
	case DES_CHAT_ALL_INFLUENCE:			// 177		// 2007-08-09 by cmkwon, 모든 세력에 채팅 전송하기 - desparam 추가, 유료아이템
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2007-08-24 by cmkwon, 스피커아이템 사용 가능/금지 설정 기능 추가 - 플래그 체크
			if(ms_pFieldIOCP->GetUnusableSpeakerItem())
			{
				return ERR_CANNOT_USE_SPEAKER_ITEM;
			}

			if(NULL == i_szChatMsg
				|| 0 >= strlen(i_szChatMsg))
			{
				return ERR_CHAT_CHAT_NOT_TRANSFERED;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-08-09 by cmkwon, 모든 세력에 채팅 전송하기 - 모든 세력 유저에게 메시지 전송함
			INIT_MSG_WITH_BUFFER(MSG_FC_CHAT_ALL_INFLUENCE, T_FC_CHAT_ALL_INFLUENCE, pChatAll, SendBuf);

			// 2010. 09. 28. by hsLee. 아레나 서버명 생략 처리. 
			char szCharacterName[SIZE_MAX_CHARACTER_NAME] = {0, };

			char szGetCharacterName[SIZE_MAX_CHARACTER_NAME] = {0, };
				strcpy ( szGetCharacterName , GetCharacter()->CharacterName );

			char *pszCharacterName = NULL;

			if ( g_pFieldGlobal->IsArenaServer() )
			{
				ms_pFieldIOCP->ConvertArenaRenderUserName ( szGetCharacterName , szCharacterName );
				pszCharacterName = szCharacterName;
			}
			else
			{
				pszCharacterName = szGetCharacterName;
			}
			
			STRNCPY_MEMSET ( pChatAll->FromCharacterName , pszCharacterName , SIZE_MAX_CHARACTER_NAME );
			STRNCPY_MEMSET ( pChatAll->str256ChatMsg , i_szChatMsg , SIZE_MAX_STRING_256 );
			ms_pFieldIOCP->SendMessageToAllClients ( SendBuf , MSG_SIZE ( MSG_FC_CHAT_ALL_INFLUENCE ) , INFLUENCE_TYPE_ALL_MASK );
		}
		break;
	case DES_CHAT_BLOCK:	// 2008-12-30 by cmkwon, 지도자 채팅 제한 카드 구현 - CFieldIOCPSocket::ApplyCardItem(), 기능 적용
		{
			if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
			{// 2008-12-30 by cmkwon, 지도자만 사용 가능한 아이템
				return ERR_PERMISSION_DENIED;
			}

			if(SIZE_MAX_CHARACTER_NAME <= strlen(i_szChatMsg))
			{// 2008-12-30 by cmkwon, 캐릭터명이 너무 길다.
				return ERR_DB_INVALID_PARAMETER;
			}

			CFieldIOCPSocket *pFISocTarget = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(i_szChatMsg);
			if(NULL == pFISocTarget 
				|| FALSE == pFISocTarget->IsValidCharacter(FALSE)
				|| this->GetCharacter()->InfluenceType != pFISocTarget->GetCharacter()->InfluenceType)
			{
				return ERR_INVALID_PEER_CHARACTER;
			}

			// 2008-12-30 by cmkwon, IMServer로 지도자 채금 정보 전송
			INIT_MSG_WITH_BUFFER(MSG_FI_EVENT_CHAT_BLOCK, T_FI_EVENT_CHAT_BLOCK, pChatBlock, SendBuf);
			STRNCPY_MEMSET(pChatBlock->szBlockedCharacterName, i_szChatMsg, SIZE_MAX_CHARACTER_NAME);
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			pChatBlock->nBlockedMinutes		= i_pItemInfo->ParameterValue1/60;		// 2008-12-30 by cmkwon, 초단위를 분으로 변경
			pChatBlock->nBlockedMinutes		= i_pItemInfo->ArrParameterValue[0]/60;		// 2008-12-30 by cmkwon, 초단위를 분으로 변경

			ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_EVENT_CHAT_BLOCK));

			// 2008-12-30 by cmkwon, 지도자에게 사용된 정보 전송
			this->SendString128(STRING_128_USER_NOTICE, STRMSG_081230_0001, pChatBlock->szBlockedCharacterName, pChatBlock->nBlockedMinutes);

			// 2008-12-30 by cmkwon, 채금 받은이에게 정보 전송
			pFISocTarget->SendString128(STRING_128_USER_NOTICE, STRMSG_081230_0002, pChatBlock->nBlockedMinutes);
		}
		break;

		// 2013-08-30 by bckim, 필드이동금지아이템
	case DES_MOVEMENT_RESTRICTION_GIVE:
		{
			// 지도자 OR 관리자만 가능  
			if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_OPERATION|RACE_INFLUENCE_SUBLEADER_1|RACE_INFLUENCE_SUBLEADER_2))	// 2013-12-13 by jhseol, 필드이동금지아이템 부지도자 권한 추가
			{
				return ERR_PERMISSION_DENIED;
			}	

			if(SIZE_MAX_CHARACTER_NAME <= strlen(i_szChatMsg))	// 캐릭터명이 너무 길다.
			{
				return ERR_DB_INVALID_PARAMETER;
			}
			
			CFieldIOCPSocket *pFISocTarget = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(i_szChatMsg);
			if(NULL == pFISocTarget 
				|| FALSE == pFISocTarget->IsValidCharacter(FALSE)
				|| this->GetCharacter()->InfluenceType != pFISocTarget->GetCharacter()->InfluenceType)
			{
				return ERR_INVALID_PEER_CHARACTER;
			}
					
			ITEM * ptmpRestrictItemInfo = ms_pFieldIOCP->GetItemInfo(DES_MOVEMENT_RESTRICTION_TAKE_ITEMNUM);	// 7044190	
			if( NULL != ptmpRestrictItemInfo )	
			{
				pFISocTarget->InsertTimeLimiteItem(ptmpRestrictItemInfo);				
							
				char tmpStr[128];
				sprintf(tmpStr,STRMSG_130830_0001,pFISocTarget->m_character.CharacterName);							   
				ms_pFieldIOCP->SendString128ToAllClients(STRING_128_USER_NOTICE, tmpStr, TRUE, this->GetCharacter()->InfluenceType); 				
			}			
		}
		break;
		// End. 2013-08-30 by bckim, 필드이동금지아이템

	case DES_INCREASE_INVENTORY_SPACE:		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - CFieldIOCPSocket::ApplyCardItem#, 
		{
			BYTE byAddCnt	= i_pItemInfo->ArrParameterValue[0];
			int nCurCnt		= m_character.GetAddedPermanentInventoryCount();
			if(SIZE_MAX_ADDABLE_INVENTORY_COUNT <= nCurCnt
				|| 255 < nCurCnt + byAddCnt)
			{
				return ERR_PROTOCOL_CANNOT_USE_ITEM;
			}
			m_character.SetAddedPermanentInventoryCount(nCurCnt+byAddCnt);
			this->SetAddedPermanentInventoryCountOfOthersCharacter(m_character.CharacterUniqueNumber, m_character.RacingPoint);  // 인벤은 꼭 필요하지 않지만 적용해 준다
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeAddedInventoryCount, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber, m_character.RacingPoint);
			g_pFieldGlobal->WriteSystemLogEX(FALSE, "    [GameLog]: CFieldIOCPSocket::ApplyCardItem# %s DES_INCREASE_INVENTORY_SPACE (%d) => (%d) \r\n", GetCharacterString(GetCharacter(), string()), nCurCnt, nCurCnt+byAddCnt);
		}
		break;
	case DES_INCREASE_STORE_SPACE:			// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - CFieldIOCPSocket::ApplyCardItem#, 
		{
			BYTE byAddCnt	= i_pItemInfo->ArrParameterValue[0];
			int nCurCnt		= m_character.GetAddedPermanentInventoryCount(ITEM_IN_STORE);
			if(SIZE_MAX_ADDABLE_STORE_COUNT <= nCurCnt
				|| 255 < nCurCnt + byAddCnt)
			{
				return ERR_PROTOCOL_CANNOT_USE_ITEM;				
			}
			m_character.SetAddedPermanentInventoryCount(nCurCnt+byAddCnt, ITEM_IN_STORE);
			this->SetAddedPermanentInventoryCountOfOthersCharacter(m_character.CharacterUniqueNumber, m_character.RacingPoint);
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeAddedInventoryCount, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber, m_character.RacingPoint);
			g_pFieldGlobal->WriteSystemLogEX(FALSE, "    [GameLog]: CFieldIOCPSocket::ApplyCardItem# %s DES_INCREASE_STORE_SPACE (%d) => (%d) \r\n", GetCharacterString(GetCharacter(), string()), nCurCnt, nCurCnt+byAddCnt);
		}
		break;

	case DES_WAR_POINT_UP: // 워포인트 캡슐아이템
		{ // 2010-08-27 by shcho&&jskim, WARPOINT 증가 아이템 구현
			BOOL ret = 0;
			INT tmpWarpoint = i_pItemInfo->ArrParameterValue[0]; // 추가될 워포인트 정보
			ret = this->SetWarPoint(tmpWarpoint);
			
			if(FALSE == ret)
			{
				g_pFieldGlobal->WriteSystemLogEX(FALSE, "    [GameLog]: CFieldIOCPSocket::SetWarPoint# %s DES_WAR_POINT_UP WarPoint = (%d) Failed!! \r\n", GetCharacterString(GetCharacter(), string()), tmpWarpoint);
			}
		}
		break;

		// 2013-08-07 by bckim, 미션프리패스 아이템
	case DES_QUEST_MISSION_FREE_PASS:
		{	
			#ifdef S_QUEST_MISSION_FREE_PASS_BCKIM			// case DES_QUEST_MISSION_FREE_PASS:
			return this->QuestMisstionFreePass(i_pItemInfo);		
			#endif
		}
		break;
		// End. 2013-08-07 by bckim, 미션프리패스 아이템

#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN				// 2013-02-28 by bckim, 복귀유져 버프추가
	case DES_BUFF_TO_RETURN_USER:
		{
			m_ItemManager.SetReturnItemDesParamInParty(this, i_pItemInfo);		// 복귀유져!! 아이템 적용시점
			}
		break;
#endif

	// 2013-08-30 by bckim, 필드이동금지아이템
	case DES_MOVEMENT_RESTRICTION_TAKE:		// 421
		{		
			if( FALSE == IS_CITY_MAP_INDEX(this->m_character.MapChannelIndex.MapIndex) )
			{
				WarpToCityMap();
			}
			this->SendString128(STRING_128_USER_NOTICE,STRMSG_130830_0002,this->m_character.CharacterName);			// 필드이동제한을 당하는 유져에게 보내는 메세지 
		}
		break;
	// End. 2013-08-30 by bckim, 필드이동금지아이템

	default:
		{
// 2010-03-18 by cmkwon, 몬스터변신 구현 - 아래와 같이 수정
//			return ERR_PROTOCOL_NO_SUCH_DES_PARAM;
			///////////////////////////////////////////////////////////////////////////////
			// 2010-03-18 by cmkwon, 몬스터변신 구현 - 모든 파라미터를 적용한다.
			this->ApplyItemDesParam(i_pItemInfo);
		}
	}

	return ERR_NO_ERROR;
}

void CFieldIOCPSocket::ReleaseCardItem(ITEM *i_pItemInfo)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - CFieldIOCPSocket::ApplyCardItem#, 적용처리
	if(i_pItemInfo->IsExistDesParam(DES_TRANSFORM_TO_MONSTER))
	{
		this->UpdateItemRenderInfoForTransformer(0, FALSE);
	}

	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
	//switch(i_pItemInfo->DestParameter1)
	switch(i_pItemInfo->ArrDestParameter[0])
	{
	case DES_CASH_STEALTH:			// 스텔스 카드 - 7010260
		{
			this->m_bStealthState	= 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();		// 2013-05-09 by hskim, 세력 포인트 개선
			m_pCurrentFieldMapChannel->Send2NPCServerW(BufSend, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_STEALTHSTATE));
		}
		break;
// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
// 	case DES_CASH_HP_AND_DP_UP:		// 고급/중급/초급 에너지/쉴드 키트 - 7010350/7010360/7010370
// 		{
// 			m_nPlusHP	= 0;
// 			m_nPlusDP	= 0;
// 			ChangeHP(GetCharacterTotalHP());
// 			ChangeDP(GetCharacterTotalDP());
// 		}
// 		break;
 	case DES_CASH_HP_AND_DP_UP:		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, // 고급/중급/초급 에너지/쉴드 키트 - 7010350/7010360/7010370
	case DES_MINATTACK_01:
	case DES_MAXATTACK_01:
	case DES_MINATTACK_02:
	case DES_MAXATTACK_02:
	case DES_ATTACKPROBABILITY_01:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 아드레날린캡슐
	case DES_ATTACKPROBABILITY_02:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 아드레날린캡술
	case DES_DEFENSE_01:					// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSE_02:					// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSEPROBABILITY_01:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_DEFENSEPROBABILITY_02:			// 2006-09-29 by cmkwon, 보조스킬아이템 - 브레이브캡슐
	case DES_HP_REPAIR_RATE_FLIGHTING:		// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 160, // 2006-09-29 by cmkwon, 보조스킬아이템 - HP 회복율
	case DES_DP_REPAIR_RATE:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 161, // 2006-09-29 by cmkwon, 보조스킬아이템 - DP 회복율
	case DES_SP_REPAIR_RATE:				// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 162, // 2006-09-29 by cmkwon, 보조스킬아이템 - SP 회복율
	case DES_DROP_EXP:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 157
	case DES_DROP_SPI:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 158
	case DES_DROP_ITEM:						// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 159
	case DES_RARE_ITEM_DROP_RATE:			// 2010-11-30 by shcho, 레어아이템 드랍 확률 증가 아이템 구현
	case DES_PIERCE_UP_01:					// 2009-12-21 by cmkwon, 일본 Arario 기능 추가 구현 아이템 - 
	case DES_PIERCE_UP_02:					// 2009-12-21 by cmkwon, 일본 Arario 기능 추가 구현 아이템 - 
	case DES_ITEM_RESISTANCE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 저항 아이템 사용 체크 
	case DES_ITEM_ADDATTACK:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 사용 체크 
	case DES_ITEM_IGNOREDEFENCE:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 방어력 무시 아이템 사용 체크
	case DES_ITEM_IGNOREAVOID:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 회피력 무시 아이템 사용 체크
	case DES_ITEM_REDUCEDAMAGE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 절대값 감소 아이템 사용 체크
	case DES_ITEM_ADDATTACK_SEC:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류)
	case DES_ITEM_ONCE_RESISTANCE:			// 2009-09-09 ~ 2010-01-19 by dhjin, 인피니티 - 한 번만 저항하고 없어지는 저항 아이템 추가 
	case DES_ENGINE_MAX_SPEED_UP:			// 2010-02-26 by cmkwon, 일본 Arario 기능 추가 구현 요청(엔진관련) - 
		{
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter1, i_pItemInfo->ParameterValue1);
// 			this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter2, i_pItemInfo->ParameterValue2);
// 			this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter3, i_pItemInfo->ParameterValue3);
// 			this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter4, i_pItemInfo->ParameterValue4);
			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
			{
				this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->ArrDestParameter[i], i_pItemInfo->ArrParameterValue[i]);
			}
		}
		break;
	// 2010-08-26 by shcho&jsKim, 밤 아이템 구현
	case DES_MAX_SP_UP:
		{
			for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
			{
				this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->ArrDestParameter[i], i_pItemInfo->ArrParameterValue[i]);
			}
			this->ChangeSP(this->GetCharacterTotalSP());		// 2010-08-26 by shcho&jsKim, 밤 아이템 구현
		}
		break;
	// 2010-08-26 by shcho&jsKim, 밤 아이템 구현
// 2008-12-29 by cmkwon, 일본 Arario 사용 후 시간 제한 아이템 DesParam 추가 구현 - 위로 이동 함
// 	case DES_HP_REPAIR_RATE_FLIGHTING:		// 2006-09-29 by cmkwon, 보조스킬아이템 - HP 회복율
// 	case DES_DP_REPAIR_RATE:				// 2006-09-29 by cmkwon, 보조스킬아이템 - DP 회복율
// 	case DES_SP_REPAIR_RATE:				// 2006-09-29 by cmkwon, 보조스킬아이템 - SP 회복율
// 		{
// 			this->UnsetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter1, i_pItemInfo->ParameterValue1);
// 		}
// 		break;
	case DES_SKILL_SCANNING:		// 2007-04-17 by cmkwon, 144		// Invisible 상태의 유저를 볼 수 있도록 한다// 2007-04-17 by cmkwon, 서버에서는 처리 할것이 없음, 기능은 클라이언트에서 처리
		// 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
#ifdef SC_SEARCHEYE_SHUTTLE_POSITION_JHSEOL_MSPARK
		if( 15000 > i_pItemInfo->Time )		// 지속시간이 15초보다 작으면 일반 서치아이
		{
			m_structUsingItemBitFlag.bSearchEye_1	= FALSE;		// 서치아이 아이템 사용중인 상태 FLAG (FALSE : 미사용, TRUE : 사용)
		}
		else
		{
			m_structUsingItemBitFlag.bSearchEye_2	= FALSE;		// 서치아이 아이템 사용중인 상태 FLAG (FALSE : 미사용, TRUE : 사용)
		}
#endif
		// end 2012-12-06 by jhseol, 서치아이 범위 캐릭터 중심으로 변경
	case DES_HYPER_BOOSTER:			// 2006-10-11 by cmkwon, 보조스킬아이템 - 하이퍼부스터 // 2006-10-11 by cmkwon, 서버에서는 처리 할것이 없음 , 부스터 관련은 클라이언트에서 처리
	case DES_CHAT_ALL_INFLUENCE:	// 177		// 2007-08-09 by cmkwon, 모든 세력에 채팅 전송하기 - 처리 필요 없음
		{
		}
		break;

#ifdef SC_ITEM_EVENT_RETURN_USER_BCKIM_BHSOHN				// 2013-02-28 by bckim, 복귀유져 버프추가
	case DES_BUFF_TO_RETURN_USER:
		{
			this->ReleaseItemDesParam(i_pItemInfo);
			this->m_character.bUsingReturnItem = RETURN_USER_NOT_USING_ITEM;		// 아이템 해제
			this->SendCharacterOtherInfo( this->m_character.ClientIndex, TRUE );  // 변경된 복귀유져정보 전송 
		}	
		break;
#endif

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - 모든 파라미터를 적용한다.
	default:
		{
			this->ReleaseItemDesParam(i_pItemInfo);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::InsertTimeLimiteItem(ITEM *i_pTimeLimiteItemInfo, BOOL i_bCheckAlreadyUsing8Apply/*=TRUE*/)
/// \brief		// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 수정
/// \author		cmkwon
/// \date		2006-04-21 ~ 2006-04-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::InsertTimeLimiteItem(ITEM *i_pTimeLimiteItemInfo, BOOL i_bCheckAlreadyUsing8Apply/*=TRUE*/)
{
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	
	// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 수정
	//				CFieldIOCPSocket::Process_FC_ITEM_USE_ITEM(), CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM() 에서 이 함수를 같이 사용하도록 하기 위해 인자 추가해서 처리
	if(i_bCheckAlreadyUsing8Apply)
	{
		if(m_ItemManager.IsExistInsertingItemNumList2DB(i_pTimeLimiteItemInfo->ItemNum))
		{// 2008-01-31 by cmkwon, 이미 추가 중인 리스트에 있다면 바로 리턴
			return FALSE;
		}

		if(m_ItemManager.IsExistAlreadyUsingItemByItemNum(i_pTimeLimiteItemInfo->ItemNum))
		{
			m_ItemManager.DeleteUsingTimeLimitedItemList(i_pTimeLimiteItemInfo->ItemNum);
		}

		Err_t errCode = ApplyCardItem(i_pTimeLimiteItemInfo, TRUE);			// 사용된 아이템 기능 적용 하기
		if(ERR_NO_ERROR != errCode)
		{		
			return FALSE;
		}
	}

	ITEM_GENERAL *pUsingItemG		= (ITEM_GENERAL*)m_ItemManager.MakeNewItem(i_pTimeLimiteItemInfo->ItemNum, ITEM_IN_CHARACTER, i_pTimeLimiteItemInfo);
	pUsingItemG->UsingTimeStamp		= ITEM_NOT_USING + 1;				// ITEM_NOT_USING이 아니므로 사용이 시작된것
	pUsingItemG->UsingStartTime.SetCurrentDateTime();	// 사용 시작 시간 설정
	if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pUsingItemG, IUT_USE_ITEM))
	{
		SAFE_DELETE(pUsingItemG);
		return FALSE;
	}

	// 2008-01-31 by cmkwon, 시간제한 아이템 DB 에 추가 중 체크 - 추가 중 ItemNum 리스트에 추가한다.
	m_ItemManager.InsertInsertingItemNumList2DB(i_pTimeLimiteItemInfo->ItemNum);

	return TRUE;
}

// 2013-05-09 by hskim, 세력 포인트 개선
BOOL CFieldIOCPSocket::ApplyBuffSkill(INT nItemNum)
{
	// 2013-07-06 by hskim, 서버 코드 강화
	if( FALSE == IsValidCharacter(FALSE) )
	{
		return FALSE;
	}
	// end 2013-07-06 by hskim, 서버 코드 강화

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(nItemNum);
	if ( NULL == pItemInfo )
	{
		return FALSE;
	}

	ITEM_SKILL ItemSkill			= ITEM_SKILL(pItemInfo);
	ItemSkill.UniqueNumber			= 0;
	ItemSkill.AccountUniqueNumber	= m_character.AccountUniqueNumber;
	ItemSkill.Possess				= m_character.CharacterUniqueNumber;
	ItemSkill.ItemWindowIndex		= POS_INVALID_POSITION;

	MSG_FC_SKILL_USE_SKILL MsgSUS;
	MEMSET_ZERO(&MsgSUS, sizeof(MsgSUS));

	MsgSUS.SkillItemID.ItemNum = nItemNum;
	MsgSUS.TargetIndex = m_character.ClientIndex;

	return this->m_SkillManager.UseSkill(&ItemSkill, &MsgSUS);
}

BOOL CFieldIOCPSocket::ReleaseBuffSkill(INT nItemNum)
{
	// 2013-07-06 by hskim, 서버 코드 강화
	if( FALSE == IsValidCharacter(FALSE) )
	{
		return FALSE;
	}
	// end 2013-07-06 by hskim, 서버 코드 강화

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(nItemNum);
	if ( NULL == pItemInfo )
	{
		return FALSE;
	}

	MSG_FC_SKILL_CANCEL_SKILL MsgSCS;
	MEMSET_ZERO(&MsgSCS, sizeof(MsgSCS));

	MsgSCS.SkillItemID.ItemNum = nItemNum;

	if( ERR_NO_ERROR != this->m_SkillManager.CancelSkill(pItemInfo, &MsgSCS) )
	{
		return FALSE;
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::ReleaseBuffSkillByDesParam(DestParam_t desSame)
{
	// 2013-07-06 by hskim, 서버 코드 강화
	if( FALSE == IsValidCharacter(FALSE) )
	{
		return FALSE;
	}
	// end 2013-07-06 by hskim, 서버 코드 강화

	mtvectorItemID vecItemID;
	vecItemID.reserve(20);
	
	if( DES_NULL == desSame )
	{
		return FALSE;
	}

	this->m_SkillManager.GetActiveatedSkillByDesParam(&vecItemID, desSame);

	mtvectorItemID::iterator itr = vecItemID.begin();
	while (itr != vecItemID.end())
	{
		ReleaseBuffSkill(itr->ItemNum);

		itr++;
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::ApplyBuffSkillByTurnAround()
{
	if( TRUE != g_pFieldGlobal->IsArenaServer() )
	{
		// 2014-03-25 by jekim, 승리의 환호
		float PVPBuffPercent;
		INT SkillNum;
		if((SkillNum=ms_pFieldIOCP->m_InflWarManager.GetPVPBuffPercent(m_character.InfluenceType,&PVPBuffPercent)))
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_POINT, T_FC_WAR_INFLUENCE_CONSECUTIVE_POINT, pInflPoint, pInflPointSendBuf);
			pInflPoint->PVPBuffPercent = PVPBuffPercent;
			SendAddData(pInflPointSendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_POINT));
			ApplyBuffSkill(SkillNum);
			return TRUE;
		}
		// end 2014-03-25 by jekim, 승리의 환호
		// 2014-03-25 by jekim, 승리의 환호 - 기존 코드 주석처리
// 		int CurrentDiffContributionPoint = ms_pFieldIOCP->m_InflWarManager.GetTurnAroundPoint();
// 		int nAbsDiff = abs(CurrentDiffContributionPoint);
// 
// 		if( (CurrentDiffContributionPoint < 0 && TRUE == COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_ANI)) ||
// 			(CurrentDiffContributionPoint > 0 && TRUE == COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN)) )
// 		{
// 			// 2013-08-01 by jhseol, 역전의 버프 리뉴얼
// 			if( nAbsDiff > TURN_AROUND_BUFF_SKILL_NEW_THRESHOLD )
// 			{
// 				// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 버프적용시 세력포인트를 미리 보내주기
// 				INIT_MSG_WITH_BUFFER(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_POINT, T_FC_WAR_INFLUENCE_CONSECUTIVE_POINT, pInflPoint, pInflPointSendBuf);
// 				pInflPoint->PVPBuffPercent = ms_pFieldIOCP->m_InflWarManager.GetPVPBuffPercent(CurrentDiffContributionPoint);
// 				SendAddData(pInflPointSendBuf, MSG_SIZE(MSG_FC_WAR_INFLUENCE_CONSECUTIVE_POINT));
// 				// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 버프적용시 세력포인트를 미리 보내주기
// 				ApplyBuffSkill(TURN_AROUND_BUFF_SKILL_1ST);
// 				return TRUE;
// 			}
// 			// 기존코드 주석차리
// 			if( nAbsDiff >= TURN_AROUND_BUFF_SKILL_1ST_THRESHOLD )
// 			{
// 				if( nAbsDiff >= TURN_AROUND_BUFF_SKILL_2ND_THRESHOLD )
// 				{
// 					ApplyBuffSkill(TURN_AROUND_BUFF_SKILL_2ND);
// 				}
// 				else
// 				{
// 					ApplyBuffSkill(TURN_AROUND_BUFF_SKILL_1ST);
// 				}
// 
// 				return TRUE;
// 			}
			// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼

//		}
	}

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


// 2014-06-17 by bckim, 세력 불균형 ( 세력정보 및 우세세력 표시 )
BOOL CFieldIOCPSocket::InfluenceShowInfo()
{
	if( TRUE != g_pFieldGlobal->IsArenaServer() )
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_INFLUENCE_SHOW_INFO, T_FC_INFLUENCE_SHOW_INFO, pShowInfo, pShowInfoSendBuf);
		pShowInfo->InfluenceType	= this->m_character.InfluenceType;
		pShowInfo->TurnAroundPoint	= ms_pFieldIOCP->m_InflWarManager.GetTurnAroundPoint();
		SendAddData(pShowInfoSendBuf, MSG_SIZE(MSG_FC_INFLUENCE_SHOW_INFO));
		return TRUE;
	}
	return FALSE;
}
// End. 2014-06-17 by bckim, 세력 불균형 ( 세력정보 및 우세세력 표시 )

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsTransferItem(ITEM_GENERAL *i_pItemG, BOOL i_bBazaar/*=FALSE*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-26 ~ 2006-07-26
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsTransferItem(ITEM_GENERAL *i_pItemG, BOOL i_bBazaar/*=FALSE*/)
{
	if (COMPARE_BIT_FLAG(i_pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_QUEST_ITEM))
	{
		return FALSE;
	}

	if(ITEMKIND_ACCESSORY_TIMELIMIT == i_pItemG->Kind
		&& i_pItemG->UsingTimeStamp != ITEM_NOT_USING)
	{// 2006-07-26 by cmkwon, 이미 사용 시작된 아이템은 상점에 판매/거래/창고로 이동 불가
		
		return FALSE;
	}

	if(WEAR_NOT_ATTACHED != i_pItemG->Wear)
	{// 2006-08-02 by cmkwon, 장착 아이템을 이동 불가
		return FALSE;
	}

	if(i_bBazaar
		&& FALSE == COMPARE_BIT_FLAG(i_pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_BAZAAR_ITEM))
	{
		return FALSE;
	}

	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsTransferItem(ITEM *i_pItemInfo, BOOL i_bBazaar/*=FALSE*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-27 ~ 2006-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsTransferItem(ITEM *i_pItemInfo, BOOL i_bBazaar/*=FALSE*/)
{
	if (COMPARE_BIT_FLAG(i_pItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_QUEST_ITEM))
	{
		return FALSE;
	}

	if(i_bBazaar
		&& FALSE == COMPARE_BIT_FLAG(i_pItemInfo->ItemAttribute, ITEM_ATTR_BAZAAR_ITEM))
	{
		return FALSE;
	}

	return TRUE;
}

float CFieldIOCPSocket::GetCurrentLoadagePercentage(float i_fWeightPlus)
{
	// lock m_mapItemGeneral, @GetCurrentLoadagePercentage
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	return (m_ItemManager.GetCurrentCarryingItemWeight()+i_fWeightPlus) / CAtumSJ::GetTransport(&m_character);
}

float CFieldIOCPSocket::GetTradeItemWeight()
{
	float fTotalWeight = 0.0f;

	m_mapTradeItem.lock();

	mtmapUID2TradeItem::iterator itrTrd = m_mapTradeItem.begin();
	while (itrTrd != m_mapTradeItem.end())
	{
		TradeItem *pTradeItem = &(itrTrd->second);
		fTotalWeight += CAtumSJ::GetItemWeight(pTradeItem->pStoreItem->ItemInfo, pTradeItem->Count, pTradeItem->pStoreItem->DesWeight);

		itrTrd++;
	}

	m_mapTradeItem.unlock();

	return fTotalWeight;
}

BOOL CFieldIOCPSocket::AttachItem(int position, ITEM_GENERAL *pItem, BOOL bCheckWear)
{
// check: 확인하기!!!
#ifdef _DEBUG
	if (pItem->Kind == ITEMKIND_INGOT || pItem->Kind == ITEMKIND_ENERGY
		|| pItem->Kind == ITEMKIND_BULLET || pItem->Kind == ITEMKIND_CARD || pItem->Kind == ITEMKIND_ENCHANT)
	{
		// 장전, 장착할 수 없는 아이템은 FALSE를 리턴함
		return FALSE;
	}
#endif
	
	switch(position)
	{
	case POS_PROW:
		if (bCheckWear && m_ItemProw.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemProw, pItem->ItemInfo, sizeof(ITEM));
		m_ItemProw.ItemNum = (int)pItem;
		break;
	case POS_PROWIN:
		if (bCheckWear && m_ItemProwIn.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemProwIn, pItem->ItemInfo, sizeof(ITEM));
		m_ItemProwIn.ItemNum = (int)pItem;
// 2005-03-04 by cmkwon, CFieldIOCPSocket::AttachItem()함수를 호출한 곳에서 처리
//		if (!bCheckWear)	// 처음 로딩할 때는 무시
//		{
//			ResetAllSkillAndEnchant();	// skill and enchant 적용
//		}
		break;
	case POS_PROWOUT:
		if (bCheckWear && m_ItemProwOut.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemProwOut, pItem->ItemInfo, sizeof(ITEM));
		m_ItemProwOut.ItemNum = (int)pItem;
// 2005-03-04 by cmkwon, CFieldIOCPSocket::AttachItem()함수를 호출한 곳에서 처리
//		if (!bCheckWear)	// 처음 로딩할 때는 무시
//		{
//			ResetAllSkillAndEnchant();	// skill and enchant 적용
//		}
		break;
	case POS_WINGIN:			// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
		if (bCheckWear && m_ItemWingIn.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemWingIn, pItem->ItemInfo, sizeof(ITEM));
		m_ItemWingIn.ItemNum = (int)pItem;
		break;
	case POS_WINGOUT:
		if (bCheckWear && m_ItemWingOut.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemWingOut, pItem->ItemInfo, sizeof(ITEM));
		m_ItemWingOut.ItemNum = (int)pItem;
// 2005-03-04 by cmkwon, CFieldIOCPSocket::AttachItem()함수를 호출한 곳에서 처리
//		if (!bCheckWear)	// 처음 로딩할 때는 무시
//		{
//			ResetAllSkillAndEnchant();	// skill and enchant 적용
//		}
		break;
	case POS_CENTER:
		if (bCheckWear && m_ItemCenter.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemCenter, pItem->ItemInfo, sizeof(ITEM));
		m_ItemCenter.ItemNum = (int)pItem;
// 2005-03-04 by cmkwon, CFieldIOCPSocket::AttachItem()함수를 호출한 곳에서 처리
//		if (!bCheckWear)	// 처음 로딩할 때는 무시
//		{
//			ResetAllSkillAndEnchant();	// skill and enchant 적용
//		}
		break;
	case POS_REAR:
		if (bCheckWear && m_ItemRear.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemRear, pItem->ItemInfo, sizeof(ITEM));
		m_ItemRear.ItemNum = (int)pItem;
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
	case POS_ACCESSORY_UNLIMITED :
		if (bCheckWear && m_ItemAccessoryUnLimited.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemAccessoryUnLimited, pItem->ItemInfo, sizeof(ITEM));
		m_ItemAccessoryUnLimited.ItemNum = (int)pItem;
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리
	case POS_ACCESSORY_TIME_LIMIT :
		if (bCheckWear && m_ItemAccessoryTimeLimit.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemAccessoryTimeLimit, pItem->ItemInfo, sizeof(ITEM));
		m_ItemAccessoryTimeLimit.ItemNum = (int)pItem;
		break;

	case POS_PET: // 2010-06-15 by shcho&hslee 펫시스템 - 
		if(bCheckWear && m_ItemPet.ItemNum != NULL)
		{
			return FALSE;
		}
		memcpy(&m_ItemPet,pItem->ItemInfo, sizeof(ITEM));
		m_ItemPet.ItemNum = (int)pItem;
		break;
	}
	return TRUE;
}

// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
//void CFieldIOCPSocket::DettachItem(int position, ITEM *pItem, ITEM_GENERAL *pItemGeneral)
void CFieldIOCPSocket::DetachItem(int position)
{
	// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
	//ResetAllSkillAndEnchant();		// called CFieldIOCPSocket::DettachItem#
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
	switch (position)
	{
	case POS_PROW:					memset(&m_ItemProw, 0x00, sizeof(ITEM));			break;
	case POS_PROWIN:				memset(&m_ItemProwIn, 0x00, sizeof(ITEM));			break;
	case POS_PROWOUT:				memset(&m_ItemProwOut, 0x00, sizeof(ITEM));			break;
	case POS_WINGIN:				memset(&m_ItemWingIn, 0x00, sizeof(ITEM));			break;	// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
	case POS_WINGOUT:				memset(&m_ItemWingOut, 0x00, sizeof(ITEM));			break;
	case POS_CENTER:				memset(&m_ItemCenter, 0x00, sizeof(ITEM));			break;
	case POS_REAR:					memset(&m_ItemRear, 0x00, sizeof(ITEM));			break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_ATTACHMENT:			memset(&m_ItemAttachment, 0x00, sizeof(ITEM));		break;	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
	case POS_ACCESSORY_UNLIMITED :	memset(&m_ItemAccessoryUnLimited, 0x00, sizeof(ITEM));		break;	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			memset(&m_ItemPet, 0x00, sizeof(ITEM));				break;	// 2006-03-30 by cmkwon, 시간제한 악세사리
	case POS_ACCESSORY_TIME_LIMIT :	memset(&m_ItemAccessoryTimeLimit, 0x00, sizeof(ITEM));				break;	// 2006-03-30 by cmkwon, 시간제한 악세사리

	// 2010-06-15 by shcho&hslee 펫시스템 - 팻 처리 추가.
	case POS_PET :					memset ( &m_ItemPet , 0x00 , sizeof( ITEM ) );		break;
	}// end_switch (position)
}

ITEM *CFieldIOCPSocket::GetAttachedItem(BYTE i_nPosition)
{
	switch(i_nPosition) {
		case POS_PROW:
			return &m_ItemProw;
			break;
		case POS_PROWIN:
			return &m_ItemProwIn;
			break;
		case POS_PROWOUT:
			return &m_ItemProwOut;
			break;
		case POS_WINGIN:		// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
			return &m_ItemWingIn;
			break;
		case POS_WINGOUT:
			return &m_ItemWingOut;
			break;
		case POS_CENTER:
			return &m_ItemCenter;
			break;
		case POS_REAR:
			return &m_ItemRear;
			break;

		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
		case POS_ACCESSORY_UNLIMITED :
			return &m_ItemAccessoryUnLimited;
			//return &m_ItemAttachment;
			break;

		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리
		case POS_ACCESSORY_TIME_LIMIT :
			return NULL;
			break;

		// 2010-06-15 by shcho&hslee 펫시스템
		case POS_PET :
			return &m_ItemPet;
			break;

	}

	return NULL;
}

void CFieldIOCPSocket::SwapItem(ITEM *pa, ITEM *pb)
{
	ITEM tmp;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;

	if (IS_PRIMARY_WEAPON(pa->Kind))
	{
// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//		m_PrimaryTimeStamp = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();
//		m_PrimaryShotNumCount = CAtumSJ::GetTotalPrimaryShotCountPerReattackTime(&m_ItemProwOut, &m_ParamFactor);
//		m_PrimaryMultiNumCount = m_ItemProwOut.MultiNum;
	}
	else if (IS_SECONDARY_WEAPON(pa->Kind))
	{
// check: 그냥 쏘게 하기, 20041030, kelovon with ClientTeam
//		m_SecondaryTimeStamp = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds();
//		m_SecondaryShotNumCount = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);
//		m_SecondaryMultiNumCount = CAtumSJ::GetSecondaryMultiNumCount(&m_ItemWingOut, &m_ParamFactor);
	}
	else
	{
		// check: not reachable
		assert(0);
	}
}

void CFieldIOCPSocket::UpdateWearItemPointer(UID64_t MoveItemUniqueNumber, UID64_t DestItemUniqueNumber, int MovePos, int DestPos)
{
#ifdef _DEBUG
	assert (MovePos >= 0 && DestPos >= 0);
#endif

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

	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - 
	//if ( DestPos < POS_INVALID_POSITION )
	if ( IS_ATTACHABLE_POSITION(DestPos))
	{
		switch(DestPos)
		{
		case POS_PROW:
		case POS_PROWIN:
		case POS_PROWOUT:
		case POS_WINGIN:		// 2006-07-20 by cmkwon, 이펙트 아이템 (중앙 위쪽)
		case POS_WINGOUT:
		case POS_CENTER:
		case POS_REAR:
		case POS_PET: 	// 2010-06-15 by shcho&hslee 펫시스템 - 
		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
		case POS_ACCESSORY_UNLIMITED :

		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리
		case POS_ACCESSORY_TIME_LIMIT :
		
			if(AttachItem(DestPos, m_ItemManager.GetItemGeneralByUID(MoveItemUniqueNumber)))
			{
			}
			break;
		}// end_switch(DestPos)
	}
	else if ( DestPos >= POS_ITEMWINDOW_OFFSET )
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
		if(IS_ATTACHABLE_POSITION(MovePos))
		{
			DetachItem(MovePos);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 
/// \author		cmkwon
/// \date		2010-03-11 ~ 2010-03-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnUpdateWearItem(UID64_t MoveItemUniqueNumber, UID64_t DestItemUniqueNumber, int MovePos, int DestPos)
{
	this->ResetAllSkillAndEnchant();		// called CFieldIOCPSocket::OnUpdateWearItem#
}

// 주의: 반드시 ItemWindowIndex가 설정된 후에 함수를 호출해야 함
void CFieldIOCPSocket::SetWear(ITEM_GENERAL* pItem)
{
	int idx = pItem->ItemWindowIndex;

	// start 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템
	if( idx == POS_HIDDEN_ITEM )
	{
		pItem->Wear = WEAR_NOT_ATTACHED;

		return ;		
	}
	// end 2011-09-20 by hskim, 파트너 시스템 2차 - 숨겨진 아이템

	if ( idx < POS_ITEMWINDOW_OFFSET)
	{
		pItem->Wear = WEAR_ATTACHED;
	}
	else if ( idx >= POS_ITEMWINDOW_OFFSET )
	{
		pItem->Wear = WEAR_NOT_ATTACHED;
	}
	else if (idx == POS_INVALID_POSITION)
	{
		// error: not reachable
#ifdef _DEBUG
		assert(0);
#endif
		return;
	}
	else
	{
		// error: not reachable
#ifdef _DEBUG
		assert(0);
#endif
		return;
	}

	return;
}

BOOL CFieldIOCPSocket::ResGetCharacterInfoByName(CHARACTER *pCharacter, int nErr)
{
	BYTE	buffer[SIZE_MAX_PACKET];
	int		nUsedBytes	= 0;

	if(IsUsing() == FALSE)
	{
		return FALSE;
	}

	if(0 == nErr)
	{
		if(strnicmp(m_character.AccountName, pCharacter->AccountName, SIZE_MAX_ACCOUNT_NAME) != 0)
		{
			// Protocol Error 처리
			// - 요청한 처리결과의 AccountName이 접속한 AccountName과 다르다
			// 2010-02-04 by cmkwon, 오류 시스템 로그 추가 - 
			g_pGlobalGameServer->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ResGetCharacterInfoByName# not match AccountName !! %s (%s != %s) Err(%d) \r\n"
				, GetCharacterString(pCharacter, string()), m_character.AccountName, pCharacter->AccountName, nErr);
		}
		else
		{
			// 2008-01-08 by cmkwon, 버그 수정 - 위치를 이쪽으로 이동함
			ms_pFieldIOCP->m_InflWarManager.SetLeader8SubLeaderRACE(pCharacter);	// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -

			this->SetClientState(CS_GOTCHARACTER);
			memcpy(&m_character, pCharacter, sizeof(CHARACTER));		// 게임에서 사용할 Character
			m_character.ClientIndex = this->GetClientArrayIndex();				// ClientIndex를 다시 설정한다.

			///////////////////////////////////////////////////////////////////
			// DB Data의 error check
			///////////////////////////////////////////////////////////////////
			if (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level) > m_character.Experience)
			{
				m_character.Experience = CAtumSJ::GetInitialExperienceOfLevel(m_character.Level);
			}

			if (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1) < m_character.Experience)
			{
				m_character.Experience = CAtumSJ::GetInitialExperienceOfLevel(m_character.Level)
					+ (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1) - CAtumSJ::GetInitialExperienceOfLevel(m_character.Level))*0.98f;
			}
			this->m_GameStartEXP = m_character.Experience; // 2010-06-01 by shcho, GLogDB 관련 -

			// HP 오류 수정
			if (m_character.CurrentHP >= m_character.HP)
			{
				m_character.CurrentHP = m_character.HP;
			}
			if (m_character.CurrentHP < 0)
			{
				m_character.CurrentHP = 0;
			}
			// SP 오류 수정
			if (m_character.CurrentSP >= m_character.SP)
			{
				m_character.CurrentSP = m_character.SP;
			}
			if (m_character.CurrentSP < 0)
			{
				m_character.CurrentSP = 0;
			}
			// EP 오류 수정
			if (m_character.CurrentEP >= m_character.EP)
			{
				m_character.CurrentEP = m_character.EP;
			}
			if (m_character.CurrentEP < 0)
			{
				m_character.CurrentEP = 0;
			}
			// DP 오류 수정
			if (m_character.CurrentDP >= m_character.DP)
			{
				m_character.CurrentDP = m_character.DP;
			}
			if (m_character.CurrentDP < 0)
			{
				m_character.CurrentDP = 0;
			}

			// 신분 확인
			CheckAndUpdateStatus();

			mt_auto_lock ccLock(&m_mtvectCharacterCache);
			if(FALSE == this->UpdateCharacterCacheLock(m_character.CharacterUniqueNumber, &m_character))
			{
				m_mtvectCharacterCache.pushBackLock(m_character);
			}
			ccLock.auto_unlock_cancel();


			// set header
			memset(buffer, 0x00, SIZE_MAX_PACKET);
			*(MessageType_t*)buffer = T_FC_CHARACTER_GET_CHARACTER_OK;
			nUsedBytes += SIZE_FIELD_TYPE_HEADER;

			// set body
			MSG_FC_CHARACTER_GET_CHARACTER_OK *pMsgGetCharacter
				= (MSG_FC_CHARACTER_GET_CHARACTER_OK*)(buffer + nUsedBytes);
			memcpy(pMsgGetCharacter, &m_character, sizeof(CHARACTER));	// set character

			nUsedBytes += sizeof(MSG_FC_CHARACTER_GET_CHARACTER_OK);
			SendAddData(buffer, nUsedBytes);
		}
	}
	else
	// Error
	{
		this->SetClientState(CS_LOGINED);						// Client의 GetCharacter 실패
		memset(&m_character, 0x00, sizeof(CHARACTER));			// Character 구초체를 초기화한다.
		m_character.ClientIndex = this->GetClientArrayIndex();	// Character 구초체의 배열 인덱스를 설정한다.
		switch(nErr)
		{
		case ERR_COMMON_NO_SUCH_CHARACTER:
			{
				SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_COMMON_NO_SUCH_CHARACTER);
			}
			break;
		default:
			{
				SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_COMMON_UNKNOWN_ERROR, nErr);
			}
		}
	}

	return FALSE;
}


BOOL CFieldIOCPSocket::ResGetAllCharacterInfoByID(MSG_FC_CONNECT_LOGIN_OK *pMsgConnectIDOK
												  , SCASH_PREMEIUM_CARD_INFO *i_pCashCardInfo
												  , BYTE i_bySelectableInfluenceMask
												  , int nErr)
{
	if(IsUsing() == FALSE)
	{
		return FALSE;
	}

	if(0 == nErr)
	{
		this->SetClientState(CS_LOGINED);											// Client의 Login 성공
		this->SetSelectableInfluenceMask(i_bySelectableInfluenceMask);				// 2005-12-07 by cmkwon, 
		m_nNumCharacters				= pMsgConnectIDOK->NumCharacters;			// AccountName이 가지고 있는 Character수를 설정
		m_character.AccountUniqueNumber	= pMsgConnectIDOK->AccountUniqueNumber;		// AccountName의 AccountUinqueNumber를 설정
		
		mt_auto_lock mtallcharacter(&m_mtvectAllCharacterInfo);
		m_mtvectAllCharacterInfo.clear();
		for (int i=0; i < m_nNumCharacters; i++)
		{
			m_mtvectAllCharacterInfo.push_back(pMsgConnectIDOK->Characters[i]);
		}
		mtallcharacter.auto_unlock_cancel();
				
		m_ItemManager.CashInitPremiumCardInfo(i_pCashCardInfo);

		///////////////////////////////////////////////////////////////////////////////
		// 로그인 OK 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_LOGIN_OK, T_FC_CONNECT_LOGIN_OK, pSOK, SendBuf);
		*pSOK		= *pMsgConnectIDOK;
		
		// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - MSG_FC_CONNECT_LOGIN_OK 에 값 할당
		pSOK->bIsUseSecondaryPasswordSystem		= g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag();
		pSOK->bIsSetSecondaryPassword			= this->IsSettingSecondaryPassword();

		SendAddData(SendBuf, MSG_SIZE(MSG_FC_CONNECT_LOGIN_OK));

		//////////////////////////////////////////////////////////////////////////
		// 2007-12-28 by dhjin, 아레나 통합 - 아레나 서버가 아니면 아레나 서버 정보를 클라이언트에 전송한다.
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_ARENASERVER_INFO, T_FC_CONNECT_ARENASERVER_INFO, pASInfo, ASInfoSendBuf);
			pASInfo->MainServer_ID			= g_pFieldGlobal->GetMGameServerID();
			pASInfo->ArenaServer_ID			= g_pFieldGlobal->m_sArenaServerInfo.ArenaServerID;
			pASInfo->AFS_Port				= g_pFieldGlobal->m_sArenaServerInfo.ArenaFieldServerPort;
			pASInfo->AIS_Port				= g_pFieldGlobal->m_sArenaServerInfo.ArenaIMServerPort;
			STRNCPY_MEMSET(pASInfo->AFS_IP, g_pFieldGlobal->m_sArenaServerInfo.ArenaFieldServerIP, SIZE_MAX_IPADDRESS);
			STRNCPY_MEMSET(pASInfo->AIS_IP, g_pFieldGlobal->m_sArenaServerInfo.ArenaIMServerIP, SIZE_MAX_IPADDRESS);
			SendAddData(ASInfoSendBuf, MSG_SIZE(MSG_FC_CONNECT_ARENASERVER_INFO));
		}

		
		// 2014-01-27 by bckim, 버그 트랩
#ifdef SC_BUGTRAP_BCKIM_SSJUNG		
		if(FALSE == g_pFieldGlobal->IsArenaServer())
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_BUGTRAP_SERVER_INFO, T_FC_CONNECT_BUGTRAPSERVER_INFO, pBSInfo, BSInfoSendBuf);
			pBSInfo->BugTrapServerFlag	= g_pFieldGlobal->m_sBugTrapServerInfo.BugTrapServerFlag;		
			pBSInfo->BugTrapServerType	=g_pFieldGlobal->m_sBugTrapServerInfo.BugTrapServerType;
			STRNCPY_MEMSET(pBSInfo->BugTrapServerIP, g_pFieldGlobal->m_sBugTrapServerInfo.BugTrapServerIP, SIZE_MAX_IPADDRESS);
			STRNCPY_MEMSET(pBSInfo->LoginID, g_pFieldGlobal->m_sBugTrapServerInfo.LoginID, SIZE_MAX_ACCOUNT_NAME);
			STRNCPY_MEMSET(pBSInfo->LoginPW, g_pFieldGlobal->m_sBugTrapServerInfo.LoginPW, SIZE_MAX_PASSWORD);
			STRNCPY_MEMSET(pBSInfo->ServerNationInfo, g_pFieldGlobal->m_sBugTrapServerInfo.ServerNationInfo, SIZE_MAX_PASSWORD);

			STRNCPY_MEMSET(pBSInfo->ServerGroupName0, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);		
			STRNCPY_MEMSET(pBSInfo->GamePublisher, g_pFieldGlobal->GetGamePublisherName(), SIZE_MAX_GAME_PUBLISHER_NAME);
			pBSInfo->nLanguageType = g_pFieldGlobal->GetLanguageType();
			SendAddData(BSInfoSendBuf, MSG_SIZE(MSG_FC_CONNECT_BUGTRAP_SERVER_INFO));
		}
#endif
		// End. 2014-01-27 by bckim, 버그 트랩
		
		
		if(m_ItemManager.IsExistPremiumCard())
		{
			INIT_MSG(MSG_FC_CHARACTER_CASH_PREMIUM_CARD_INFO, T_FC_CHARACTER_CASH_PREMIUM_CARD_INFO, pSCardInfo, SendBuf);
			m_ItemManager.Make_MSG_FC_CHARACTER_CASH_PREMIUM_CARD_INFO(pSCardInfo);
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CASH_PREMIUM_CARD_INFO));
		}
	}
	else
	{
		// Protocol Error 처리
		// - AccountName이 존재하지 않는다
		// - AccountName의 Character가 하나두 없다

		this->SetClientState(CS_CONNECTED);												// Client의 Login 실패
		memset(&m_character, 0x00, sizeof(CHARACTER));								// Character 구초체를 초기화한다.
		m_character.ClientIndex = this->GetClientArrayIndex();								// Character 구초체의 배열 인덱스를 설정한다.
		switch(nErr)
		{
		case ERR_COMMON_LOGIN_FAILED:
			{
				SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_COMMON_LOGIN_FAILED);
			}
			break;
		default:
			{
				SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_COMMON_UNKNOWN_ERROR, nErr);
			}
		}
	}

	return TRUE;
}

// 2015-07-07 by bckim, 게임포지 해킹보완 소켓타입확인	
BOOL CFieldIOCPSocket::CheckAntiHackingFieldSever(MessageType_t	i_nRecvType)
{
	switch(i_nRecvType)
	{
	case T_FC_CONNECT_LOGIN:
	case T_FI_GUILD_BONUS_EXP_RATE:
		{		
			return TRUE;
		}
		// From Field Client
		
	case T_FC_CONNECT_NETWORK_CHECK:	// 2008-02-15 by cmkwon, Client<->FieldServer 간 네트워크 상태 체크 - 	
	case T_FC_CHARACTER_GET_CHARACTER:
	case T_FC_CHARACTER_CREATE:
	case T_FC_CHARACTER_DELETE:
	case T_FC_CHARACTER_GET_OTHER_INFO:
	case T_FC_CHARACTER_GET_OTHER_MOVE:
	case T_FC_CHARACTER_GET_OTHER_RENDER_INFO:
	case T_FC_CHARACTER_GET_ACCOUNTUNIQUENUMBER:
	case T_FC_CHARACTER_APPLY_COLLISION_DAMAGE:
	case T_FC_CHARACTER_GAMESTART:
	case T_FC_CHARACTER_CONNECT_GAMESTART:
	case T_FC_CHARACTER_DEAD_GAMESTART:
	case T_FC_CHARACTER_GAMEEND:
	case T_FC_CHARACTER_REPAIR:
	case T_FC_CHARACTER_DOCKING:
	case T_FC_CHARACTER_UNDOCKING:
	case T_FC_CHARACTER_CHANGE_BODYCONDITION:
	case T_FC_CHARACTER_CHANGE_BODYCONDITION_ALL:
	case T_FC_CHARACTER_SHOW_EFFECT:
	case T_FC_CHARACTER_GET_OTHER_PARAMFACTOR:
	case T_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE:
	case T_FC_CHARACTER_SPEED_HACK_USER:
	case T_FC_CHARACTER_GET_CASH_MONEY_COUNT:
	case T_FC_CHARACTER_TUTORIAL_SKIP:
	case T_FC_CHARACTER_CHANGE_CHARACTER_MODE:
	case T_FC_CHARACTER_FALLING_BY_FUEL_ALLIN:
	case T_FC_CHARACTER_WARP_BY_AGEAR_LANDING_FUEL_ALLIN:
	case T_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK:
	case T_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK:
	case T_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK:
	case T_FC_CHARACTER_MEMORY_HACK_USER:
	case T_FC_CHARACTER_UPDATE_SUBLEADER:			// 2007-02-14 by dhjin
	case T_FC_CHARACTER_OBSERVER_START:			// 2007-03-27 by dhjin
	case T_FC_CHARACTER_OBSERVER_END:			// 2007-03-27 by dhjin
	case T_FC_CHARACTER_SHOW_MAP_EFFECT:		// 2007-04-20 by cmkwon
		// 2008-01-10 by dhjin,  아레나 통합 - 
	case T_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER:
	case T_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER:
	case T_FC_CHARACTER_GET_USER_INFO:		// 2008-06-23 by dhjin, EP3 유저정보옵션 -
	case T_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET:			// 2008-06-23 by dhjin, EP3 유저정보옵션 -
	case T_FC_CHARACTER_CHANGE_NICKNAME:			// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	case T_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX:		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
	case T_FC_CHARACTER_DEBUFF_DOT_INFO:	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - F -> C
	case T_FC_CHARACTER_GET_USER_ITEM_INFO:		// 2012-06-05 by jhseol, 아템미리보기 - 살펴볼 케릭터 UID
	case T_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET:		// 2012-07-12 by jhseol, 아템미리보기 On / Off 기능 - 공개 여부
		///////////////////////////////////////////////////////////////////////
		// MOVE
	case T_FC_MOVE:
	case T_FC_MOVE_LOCKON:
	case T_FC_MOVE_UNLOCKON:
	case T_FC_MOVE_LANDING:
	case T_FC_MOVE_LANDING_DONE:
	case T_FC_MOVE_TAKEOFF:
	case T_FC_MOVE_TARGET:
	case T_FC_MOVE_WEAPON_VEL:
	case T_FC_MOVE_ROLLING:
	case T_FC_MOVE_HACKSHIELD_GuidAckMsg:
	case T_FC_MOVE_HACKSHIELD_CRCAckMsg:
	case T_FC_MOVE_HACKSHIELD_HACKING_CLIENT:
	case T_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK:	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK:	// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
	case T_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK:	// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 
	case T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK:	// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
	case T_FC_MOVE_XTRAP_REQ_STEP_OK:	// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 - 
	case T_FC_MOVE_APEX_REQ_APEXDATA_OK:	// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
		
		///////////////////////////////////////////////////////////////////////
		// BATTLE
	case T_FC_BATTLE_ATTACK:
	case T_FC_BATTLE_ATTACK_FIND:
	case T_FC_BATTLE_DROP_MINE:
	case T_FC_BATTLE_MINE_ATTACK:
	case T_FC_BATTLE_MINE_ATTACK_FIND:
	case T_FC_BATTLE_DROP_DUMMY:
	case T_FC_BATTLE_DROP_FIXER:
	case T_FC_BATTLE_TOGGLE_SHIELD:
	case T_FC_BATTLE_TOGGLE_DECOY:
	case T_FC_BATTLE_ATTACK_EVASION:
	case T_FC_BATTLE_REQUEST_P2P_PK:
	case T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK:
	case T_FC_BATTLE_REJECT_REQUEST_P2P_PK:
	case T_FC_BATTLE_SURRENDER_P2P_PK:
	case T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK:
	case T_FC_BATTLE_REJECT_SURRENDER_P2P_PK:
		
	case T_FC_EVENT_WARP_SAME_MAP_DONE:
	case T_FC_EVENT_WARP_SAME_FIELD_SERVER_DONE:
	case T_FC_EVENT_ENTER_BUILDING_OK:
	case T_FC_EVENT_LEAVE_BUILDING:
	case T_FC_EVENT_REQUEST_WARP:
	case T_FC_EVENT_REQUEST_OBJECT_EVENT:
	case T_FC_EVENT_SELECT_CHANNEL:
	case T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY:
	case T_FC_EVENT_REQUEST_RACING_WARP:
	case T_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST:
	case T_FC_EVENT_REQUEST_SHOP_WARP:
	case T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING:
	case T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK:		// 2006-07-21 by cmkwon
	case T_FC_EVENT_CLICK_TELEPORT:			// 2007-09-06 by dhjin
	case T_FC_EVENT_NOTIFY_MSG_GET:			// 2007-11-28 by cmkwon, 통지시스템 구현 -
	case T_FC_EVENT_NOTIFY_MSG_DELETE:			// 2007-11-28 by cmkwon, 통지시스템 구현 -
	case T_FC_EVENT_COUPON_EVENT_USE_COUPON:	// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - 
		
		///////////////////////////////////////////////////////////////////////
		// SHOP
	case T_FC_SHOP_GET_ITEMINFO:
	case T_FC_SHOP_BUY_ITEM:
	case T_FC_SHOP_SELL_ITEM:
	case T_FC_SHOP_GET_USED_ITEM_PRICE:
	case T_FC_SHOP_GET_SHOP_ITEM_LIST:
	case T_FC_SHOP_REQUEST_REPAIR:
	case T_FC_SHOP_BUY_CASH_ITEM:
	case T_FC_SHOP_BUY_COLOR_ITEM:
	case T_FC_SHOP_BUY_WARPOINT_ITEM:
	case T_FC_SHOP_CHECK_GIVE_TARGET:	// 2007-11-13 by cmkwon, 선물하기 기능 추가 - 
	case T_FC_SHOP_INFLUENCE_BUFF:		// 2013-05-09 by hskim, 세력 포인트 개선
		
		///////////////////////////////////////////////////////////////////////
		// ITEM
	case T_FC_STORE_GET_ITEM:
	case T_FC_STORE_MOVE_ITEM:
	case T_FC_STORE_EXPIRE_USINGITEM:		// 2006-10-11 by cmkwon
	case T_FC_STORE_REQUEST_QUICKSLOT:
	case T_FC_STORE_SAVE_QUICKSLOT:
	case T_FC_STORE_LOG_GUILD_ITEM:
	case T_FC_ITEM_GET_ITEM:
	case T_FC_ITEM_DELETE_ITEM_ADMIN:
	case T_FC_ITEM_DELETE_DROP_ITEM:
	case T_FC_CHARACTER_USE_BONUSSTAT:
	case T_FC_ITEM_CHANGE_WINDOW_POSITION:
	case T_FC_ITEM_UPDATE_WINDOW_ITEM_LIST:
	case T_FC_ITEM_THROW_AWAY_ITEM:
	case T_FC_ITEM_USE_ENERGY:
	case T_FC_ITEM_USE_ITEM:
	case T_FC_ITEM_USE_ENCHANT:
	case T_FC_ITEM_MIX_ITEMS:
	case T_FC_ITEM_USE_CARDITEM_GUILDSUMMON:
	case T_FC_ITEM_USE_CARDITEM_RESTORE:
	case T_FC_ITEM_USE_CARDITEM_GUILD:
	case T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON:
	case T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME:
	case T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE:
	case T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE:
	case T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE:
	case T_FC_ITEM_USE_INFLUENCE_BUFF:
	case T_FC_ITEM_USE_INFLUENCE_GAMEEVENT:
	case T_FC_ITEM_USE_RANDOMBOX:
	case T_FC_ITEM_USE_SKILL_SUPPORT_ITEM:		// 2006-09-29 by cmkwon
	case T_FC_ITEM_USE_LUCKY_ITEM:				// 2008-11-04 by dhjin, 럭키머신
		
		///////////////////////////////////////////////////////////////////////////////////////
		// 2011-09-20 by hskim, 파트너 시스템 2차
	case T_FC_ITEM_USE_PET_SOCKET_ITEM:	
	case T_FC_ITEM_CANCEL_PET_SOCKET_ITEM:
		///////////////////////////////////////////////////////////////////////
		// INFO 요청
	case T_FC_INFO_GET_MONSTER_INFO:
	case T_FC_INFO_GET_MAPOBJECT_INFO:
	case T_FC_INFO_GET_ITEM_INFO:
	case T_FC_INFO_GET_SIMPLE_ITEM_INFO:
	case T_FC_INFO_GET_RARE_ITEM_INFO:
	case T_FC_INFO_GET_BUILDINGNPC_INFO:
	case T_FC_INFO_GET_ENCHANT_COST:
	case T_FC_INFO_GET_CURRENT_MAP_INFO:
	case T_FC_INFO_GET_SERVER_DATE_TIME:
	case T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO:	// 2007-10-30 by cmkwon, 세력별 해피아워 이벤트 구현 - C->F
	case T_FC_INFO_CHECK_RESOBJ_CHECKSUM:		// 2007-05-28 by cmkwon
		
		///////////////////////////////////////////////////////////////////////
		// Request
	case T_FC_REQUEST_REQUEST:
	case T_FC_REQUEST_ACCEPT_REQUEST:
	case T_FC_REQUEST_REJECT_REQUEST:
		///////////////////////////////////////////////////////////////////////
		// FC_CITY - 도시용 프로토콜
	case T_FC_CITY_GET_BUILDING_LIST:
	case T_FC_CITY_REQUEST_ENTER_BUILDING:
		// 2004-11-10 by cmkwon, Process_FC_EVENT_REQUEST_SHOP_WARP, Process_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST로 대체함
		//		case T_FC_CITY_GET_WARP_TARGET_MAP_LIST:
		//		case T_FC_CITY_REQUEST_WARP:
	case T_FC_CITY_CHECK_WARP_STATE:
	case T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST:
	case T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO:
	case T_FC_CITY_POLL_REG_LEADER_CANDIDATE:
	case T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE:
	case T_FC_CITY_POLL_VOTE:
	case T_FC_CITY_POLL_REQUEST_POLL_DATE:
	case T_FC_CITY_WARINFO_INFLUENCE:
	case T_FC_CITY_WARINFO_OUTPOST:
		///////////////////////////////////////////////////////////////////////
		// Quest
	case T_FC_QUEST_REQUEST_START:
	case T_FC_QUEST_ACCEPT_QUEST:
	case T_FC_QUEST_CANCEL_QUEST:
	case T_FC_QUEST_REQUEST_SUCCESS:
	case T_FC_QUEST_DISCARD_QUEST:
	case T_FC_QUEST_MOVE_QUEST_MAP:
	case T_FC_QUEST_REQUEST_SUCCESS_CHECK:
	case T_FC_QUEST_REQUEST_PARTY_WARP_ACK:		// 2006-10-16 by cmkwon
		
		///////////////////////////////////////////////////////////////////////
		// Party & Guild
	case T_FC_PARTY_REQUEST_INVITE:
	case T_FC_PARTY_ACCEPT_INVITE:
	case T_FC_PARTY_REJECT_INVITE:
	case T_FC_PARTY_GET_MEMBER:
	case T_FC_PARTY_GET_ALL_MEMBER:
	case T_FC_PARTY_REQUEST_PARTY_WARP:
	case T_FC_PARTY_REQUEST_PARTY_WARP_WITH_MAP_NAME:
	case T_FC_PARTY_REQUEST_PARTY_OBJECT_EVENT:
	case T_FC_PARTY_GET_OTHER_MOVE:
		///////////////////////////////////////////////////////////////////////
		// Guild
	case T_FC_GUILD_GET_MAP_OWNER_INFO:
	case T_FC_GUILD_REQUEST_GUILD_WAR:
	case T_FC_GUILD_GET_WAR_INFO:
	case T_FC_GUILD_SUMMON_MEMBER_OK:
	case T_FC_GUILD_DISMEMBER:
		
		///////////////////////////////////////////////////////////////////////
		// Trade
	case T_FC_TRADE_REQUEST_TRADE:
	case T_FC_TRADE_CANCEL_REQUEST:
	case T_FC_TRADE_ACCEPT_TRADE:
	case T_FC_TRADE_REJECT_TRADE:
	case T_FC_TRADE_TRANS_ITEM:
	case T_FC_TRADE_SEE_ITEM:
	case T_FC_TRADE_OK_TRADE:
	case T_FC_TRADE_CANCEL_TRADE:
	case T_FC_COUNTDOWN_DONE:
	case T_FC_OBJECT_CHANGE_BODYCONDITION:
	case T_FC_AUCTION_REGISTER_ITEM:
	case T_FC_AUCTION_CANCEL_REGISTER:
	case T_FC_AUCTION_BUY_ITEM:
	case T_FC_AUCTION_GET_ITEM_LIST:
	case T_FC_SKILL_USE_SKILLPOINT:
	case T_FC_SKILL_SETUP_SKILL:
	case T_FC_SKILL_USE_SKILL:
	case T_FC_SKILL_CANCEL_SKILL:
	case T_FC_SKILL_PREPARE_USE:
	case T_FC_SKILL_CANCEL_PREPARE:
	case T_FC_SKILL_CONFIRM_USE:
	case T_FC_SKILL_CONFIRM_USE_ACK:
		///////////////////////////////////////////////////////////////////////
		// FC_TIMER
	case T_FC_TIMER_TIMEOUT:
		///////////////////////////////////////////////////////////////////////
		// FC_CLIENT_REPORT
	case T_FC_CLIENT_REPORT:
		///////////////////////////////////////////////////////////////////////
		// FC_ADMIN
	case T_FC_ADMIN_GET_SERVER_STAT:
		///////////////////////////////////////////////////////////////////////
		// FC_MONSTER
	case T_FC_MONSTER_SKILL_END_SKILL:
	case T_FC_MONSTER_SUMMON_MONSTER:
	case T_FC_MONSTER_TUTORIAL_MONSTER_DELETE:
		///////////////////////////////////////////////////////////////////////
		// T0_FC_RACING
	case T_FC_RACING_RACINGLIST_REQUEST:
	case T_FC_RACING_RACINGINFO_REQUEST:
	case T_FC_RACING_JOIN_REQUEST:
	case T_FC_RACING_CHECKPOINT_CHECK:
		///////////////////////////////////////////////////////////////////////
		// T0_FC_CITYWAR
	case T_FC_CITYWAR_GET_OCCUPYINFO:
	case T_FC_CITYWAR_SET_SETTINGTIME:
	case T_FC_CITYWAR_SET_TEX:
	case T_FC_CITYWAR_SET_BRIEFING:
	case T_FC_CITYWAR_BRING_SUMOFTEX:
	case T_FC_WAR_REQ_SIGN_BOARD_STRING_LIST:
		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-26 by cmkwon, 개인 상점 관련
	case T_FC_BAZAAR_SELL_PUT_ITEM:
	case T_FC_BAZAAR_SELL_CANCEL_ITEM:
	case T_FC_BAZAAR_SELL_START:
	case T_FC_BAZAAR_SELL_REQUEST_ITEMLIST:
	case T_FC_BAZAAR_SELL_BUY_ITEM:
	case T_FC_BAZAAR_BUY_PUT_ITEM:
	case T_FC_BAZAAR_BUY_CANCEL_ITEM:
	case T_FC_BAZAAR_BUY_START:
	case T_FC_BAZAAR_BUY_REQUEST_ITEMLIST:
	case T_FC_BAZAAR_BUY_SELL_ITEM:
		
	//////////////////////////////////////////////////////////////////////////
		// 2007-07-06 by dhjin, Tutorial
	case T_FC_TUTORIAL_START:
	case T_FC_TUTORIAL_COMPLETE:
	case T_FC_TUTORIAL_END:
	case T_FC_TUTORIAL_WARP:
		// case T_FC_OUTPOST_RESET_CHECK_START:
	case T_FC_OUTPOST_RESET_START:
	case T_FC_OUTPOST_NEXTWAR_INFO_REQUEST:
	case T_FC_OUTPOST_NEXTWAR_SET_TIME:
	case T_FC_INFO_NOTICE_REQUEST:
	case T_FC_INFO_NOTICE_REG:
	case T_FC_INFO_NOTICE_MODIFY:
	case T_FC_INFO_EXPEDIENCYFUND_REQUEST:
	case T_FC_INFO_EXPEDIENCYFUND_PAYBACK:
	case T_FC_INFO_SECONDARYPASSWORD_UPDATE_PASSWORD:	// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
	case T_FC_INFO_SECONDARYPASSWORD_CHECK_PASSWORD:			// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
	case T_FC_INFO_SECONDARYPASSWORD_LOCK:				// 2007-09-12 by cmkwon, 베트남 2차패스워드 구현 -
	case T_FC_INFO_GET_GUILDMARK:
		
	case T_FC_INFO_MSWARINFO_DISPLAY_OPTION:			// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 -
	case T_FC_INFO_MSWARINFO_RESULT:			// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 
	case T_FC_INFO_SPWARINFO_RESULT:			// 2008-04-02 by dhjin, 모선전, 거점전 정보창 기획안 - 
		//////////////////////////////////////////////////////////////////////////
		// 2008-04-29 by dhjin, EP3 편지 시스템 -
	case T_FC_CHAT_LETTER_REQUEST_TITLE:
	case T_FC_CHAT_LETTER_READ:
	case T_FC_CHAT_LETTER_DELETE:
	case T_FC_CHAT_LETTER_SEND:
	case T_FC_CHAT_ALLLETTER_REQUEST_TITLE:
	case T_FC_CHAT_ALLLETTER_READ:
	case T_FC_CHAT_ALLLETTER_DELETE:
	case T_FC_CHAT_ALLLETTER_SEND:
		//////////////////////////////////////////////////////////////////////////
		// 2008-12-08 by dhjin, 미션마스터
	case T_FC_QUEST_REQUEST_MISSIONMASTER_HELP:
	case T_FC_QUEST_MISSIONMASTER_HELP_INVITE:
	case T_FC_QUEST_MISSIONMASTER_HELP_REJECT:
		//////////////////////////////////////////////////////////////////////////
		// 2009-01-12 by dhjin, 선전 포고 -	
	case T_FC_INFO_DECLARATION_MSWAR_INFO:
	case T_FC_INFO_DECLARATION_MSWAR_SET:
	case T_FC_INFO_WRK_GET_SERVICE_INFO:	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	case T_FC_INFO_WRK_GET_RANKER_LIST:		// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	case T_FC_INFO_WRK_GET_SELF_RANKING:	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
	case T_FC_INFINITY_MODE_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 리스트 요청, C -> F
	case T_FC_INFINITY_READY_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 리스트 요청, C -> F
	case T_FC_INFINITY_CREATE:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 생성 요청, C -> F
	case T_FC_INFINITY_JOIN:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 가입 요청, C -> F
	case T_FC_INFINITY_JOIN_REQUEST_MASTERUSER_OK:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 방장에거 가입자 승인 여부 요청, C -> F
	case T_FC_INFINITY_MEMBER_INFO_LIST:				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맴버 정보, C -> F
	case T_FC_INFINITY_CHANGE_MASTER:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 마스터 변경, C -> F
	case T_FC_INFINITY_LEAVE:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 탈퇴, C -> F
	case T_FC_INFINITY_BAN:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 추방, C -> F		
	case T_FC_INFINITY_READY:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 준비 버튼 누름, C -> F
	case T_FC_INFINITY_READY_CANCEL:						// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 준비취소 버튼 누름, C -> F
	case T_FC_INFINITY_START:								// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 시작 버튼 누름(인피 시작), C -> F		
	case T_FC_INFINITY_MAP_LOADED:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵 로딩 종료, C -> F
	case T_FC_INFINITY_FIN_OK:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 종료 확인 후 마을(Main서버로 돌아감), C -> F
	case T_FC_INFINITY_TENDER_PUT_IN_TENDER:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 유저 Tender 버튼 누름
	case T_FC_SHOP_INFINITY_BUY_ITEM:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 상점
	case T_FC_INFINITY_JOIN_CANCEL:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 입장 취소
	case T_FC_INFINITY_RESTART_BY_DISCONNECT:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
	case T_FC_INFINITY_MAP_LOADED_RESTART_BY_DISCONNECT:					// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리	
	case T_FC_ITEM_USE_INVOKING_WEAR_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템 사용
	case T_FC_ITEM_EXPIRE_TIME_INVOKING_WEAR_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템 지속 시간 완료
	case T_FC_ITEM_END_COOLINGTIME_ITEM:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 쿨타임 종료
	case T_FC_ITEM_GET_COOLINGTIME_INFO:					// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 쿨타임 정보 요청 C->F
	case T_FC_INFINITY_CHANGE_DIFFICULTY_LEVEL :			// 2010. 05. 19 by hsLee 인피니티 필드 2차 난이도 조절. (신호처리 + 몬스터 처리(서버) )
	case T_FC_INFINITY_SKIP_ENDING_CINEMA :
	case T_FC_DISSOLVED_ITEM :
		/////////////////////////////////////////////////////////////
	case T_FC_ITEM_PET_SET_NAME :
	case T_FC_ITEM_PET_SET_EXP_RATIO :
	case T_FC_ITEM_PET_SET_SOCKET :
	case T_FC_ITEM_PET_SET_KIT_SLOT :
	case T_FC_ITEM_PET_SET_AUTOSKILL_SLOT :
		//////////////////////////////////////////////////////////		
		
	case T_FC_CHARACTER_XIGNCODE_C_ACK_PACKET:
	case T_FC_CHARACTER_XIGNCODE_C_ACK_CODE:
	case T_FC_COLLECTION_SHAPE_CHANGE:
	case T_FC_BUGTRAP_ACCEPT:
	case T_FC_MARKET_BASE_INFO_REQUEST:
	case T_FC_MARKET_SEARCH_REQUEST:
	case T_FC_MARKET_PAGING_REQUEST:
	case T_FC_MARKET_SORT_REQUEST:
	case T_FC_MARKET_BUY_REQUEST:
	case T_FC_MARKET_SELL_REQUEST:
	case T_FC_MARKET_GET_REQUEST:
	case T_FC_MARKET_MY_LIST_REQUEST:
	case T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST:
	case T_FC_DESTROY_AUCTION_TENDER_REQUEST:
	case T_FC_DESTROY_AUCTION_GET_REQUEST:
	case T_FC_DESTROY_AUCTION_MY_LIST_REQUEST:
		{			
			if( ST_INVALID_TYPE == m_PeerSocketType )
			{				
				return FALSE;
			}	
		}				
		// 아레나 관련 패킷 
	case T_FtoA_MFSINFO:
	case T_FtoA_AUTH_CHARACTER_OK:
	case T_FtoA_ARENA_TEAM_MATCHING_OK:
	case T_FtoA_ARENA_CHARACTER_RESET_RELOAD:
	case T_FtoA_INFINITY_IMPUTE_LIST:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 귀속 정보.
	case T_FtoA_INFINITY_START_OK:							// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 시작 MainFieldSever준비 완료 전송, MFS -> AFS
	case T_FtoA_INFINITY_READY_FINISH_MAINSVR_START:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Main서버로 돌아갈 준비가 완료 됨, MFS -> AFS
	case T_FtoA_INFINITY_START_CHECK_ACK:					// 2010-03-23 by cmkwon, 인피니티 입장 캐쉬 아이템 구현 - 
	case T_FtoA_UPDATE_ITEM_NOTI:							// 2010-03-31 by dhjin, 인피니티 입장 캐쉬 아이템 구현 - 
	case T_FC_CONNECT_ARENASERVER_LOGIN:			// 2007-12-28 by dhjin,  아레나 통합 -
	case T_FC_CONNECT_ARENASERVER_TO_IMSERVER:			// 2008-03-03 by dhjin,  아레나 통합 -
		
		//////////////////////////////////////////////////////////////////////////
		// 2007-04-17 by dhjin, ARENA 관련 	
	case T_FC_ARENA_PLAY_CHARACTER_TYPE:		// 2012-06-08 by jhseol, 아레나 추가개발part2 - 케릭터 : 타입 복사
	case T_FC_ARENA_REQUEST_TEAM:
	case T_FC_ARENA_CREATE_TEAM:
	case T_FC_ARENA_ENTER_TEAM:
	case T_FC_ARENA_REAVE_TEAM:
	case T_FC_ARENA_TEAM_READY_FINISH:
	case T_FC_ARENA_TEAM_READY_FINISH_CANCEL:
	case T_FC_ARENA_ENTER_ROOM_WARP:
	case T_FC_ARENA_FINISH_WARP:
	case T_FC_ARENA_REQUEST_CREATE_TEAMINFO:
	case T_FC_ARENA_REQUEST_OTHER_TEAM_INFO:
	case T_FC_ARENA_QUICK_ENTER_TEAM:
		// 2008-01-08 by dhjin, 아레나 통합 - 
	case T_FC_ARENA_CHARACTER_GAMESTART:
		
		{
			return TRUE;
		}
		
	}
	return TRUE;
}
// End. 2015-07-07 by bckim, 게임포지 해킹보완 소켓타입확인

EventResult_t CFieldIOCPSocket::WarpToMap(const MAP_CHANNEL_INDEX &MapChannel)
{
	EVENTINFO *pEventInfo = new EVENTINFO;
	memset(pEventInfo, 0x00, sizeof(EVENTINFO));
	//pEventInfo->m_EventReceiver;
	//pEventInfo->m_vPosition;
	pEventInfo->m_bEventType = EVENT_TYPE_WARP;
	pEventInfo->m_EventwParam1 = ~0;		// 0xFFFF, 나중에 T_FP_EVENT_NOTIFY_WARP_OK 에서 m_EventwParam1을 확인해서 ~0이면 SAFE_DELETE()한다.
	pEventInfo->m_EventwParam2 = ~0;
	pEventInfo->m_EventwParam3 = MapChannel.MapIndex;

	return HandleEvent(pEventInfo, MapChannel.ChannelIndex);
}

EventResult_t CFieldIOCPSocket::WarpToMap(const MAP_CHANNEL_INDEX &MapChannel, D3DXVECTOR3 *pPosition, BYTE i_byCharacterMode/*=FALSE*/)
{
	EVENTINFO *pEventInfo = new EVENTINFO;
	memset(pEventInfo, 0x00, sizeof(EVENTINFO));
	//pEventInfo->m_EventReceiver;
	pEventInfo->m_vPosition = *pPosition;
	pEventInfo->m_bEventType = EVENT_TYPE_WARP;
	pEventInfo->m_EventwParam1 = ~0;		// 0xFFFF, 나중에 T_FP_EVENT_NOTIFY_WARP_OK 에서 m_EventwParam1을 확인해서 ~0이면 SAFE_DELETE()한다.
	pEventInfo->m_EventwParam2 = ~0;
	pEventInfo->m_EventwParam3 = MapChannel.MapIndex;

	return HandleEvent(pEventInfo, MapChannel.ChannelIndex, i_byCharacterMode);
}

EventResult_t CFieldIOCPSocket::WarpToMap(const MAP_CHANNEL_INDEX &MapChannel, int TargetIndex)
{
	EVENTINFO *pEventInfo = new EVENTINFO;
	memset(pEventInfo, 0x00, sizeof(EVENTINFO));
	//pEventInfo->m_EventReceiver;
	//pEventInfo->m_vPosition;
	pEventInfo->m_bEventType = EVENT_TYPE_WARP;
	pEventInfo->m_EventwParam1 = ~0;		// 0xFFFF, 나중에 T_FP_EVENT_NOTIFY_WARP_OK 에서 m_EventwParam1을 확인해서 ~0이면 SAFE_DELETE()한다.
	pEventInfo->m_EventwParam2 = TargetIndex;
	pEventInfo->m_EventwParam3 = MapChannel.MapIndex;

	return HandleEvent(pEventInfo, MapChannel.ChannelIndex);
}

EventResult_t CFieldIOCPSocket::WarpToMap(const MapIndex_t MapIndex, const ChannelIndex_t ChannelIndex)
{
	MAP_CHANNEL_INDEX tmpMapChannel;
	tmpMapChannel.MapIndex = MapIndex;
	tmpMapChannel.ChannelIndex = ChannelIndex;

	return WarpToMap(tmpMapChannel);
}

EventResult_t CFieldIOCPSocket::WarpToMap(const MapIndex_t MapIndex, const ChannelIndex_t ChannelIndex, D3DXVECTOR3 *pPosition)
{
	MAP_CHANNEL_INDEX tmpMapChannel;
	tmpMapChannel.MapIndex = MapIndex;
	tmpMapChannel.ChannelIndex = ChannelIndex;

	return WarpToMap(tmpMapChannel, pPosition);
}

EventResult_t CFieldIOCPSocket::WarpToMap(const MapIndex_t MapIndex, const ChannelIndex_t ChannelIndex, int TargetIndex)
{
	MAP_CHANNEL_INDEX tmpMapChannel;
	tmpMapChannel.MapIndex = MapIndex;
	tmpMapChannel.ChannelIndex = ChannelIndex;

	return WarpToMap(tmpMapChannel, TargetIndex);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			EventResult_t CFieldIOCPSocket::WarpToCityMap(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-07-27 ~ 2005-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
EventResult_t CFieldIOCPSocket::WarpToCityMap(void)
{
	CFieldMapChannel *pFMChann = this->GetCityFieldMapChannelPtr();

	// 2007-09-11 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(200) : %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);

	return WarpToMap(pFMChann->m_MapChannelIndex, &pFMChann->m_pMapProject->GetRandomXZCityWarpTargetPosition(), TRUE);
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			EventResult_t CFieldIOCPSocket::WarpToQuestMap(MapIndex_t i_targetMapIndex)
/// \brief		
/// \author		cmkwon
/// \date		2005-08-02 ~ 2005-08-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
EventResult_t CFieldIOCPSocket::WarpToQuestMap(MapIndex_t i_targetMapIndex)
{
	if(0 == i_targetMapIndex){					return EVENT_RESULT_BREAK;}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-15 by dhjin, 아레나 맵이면 워프 불가
	if(IS_MAP_INFLUENCE_ARENA(this->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		return EVENT_RESULT_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-28 by dhjin, 상점 이용 중에는 워프 불가
	if(BAZAAR_STATE_NONE != this->m_bazaarManager.GetBazaarState())
	{
		return EVENT_RESULT_BREAK;
	}

	if(INFLUENCE_CITY_MAP_INDEX == i_targetMapIndex
		|| i_targetMapIndex == CAtumSJ::GetCityMapIndexByInfluence(m_character.InfluenceType, m_character.GetStartCityMapIndex()))	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::WarpToQuestMap#
	{
		return WarpToCityMap();
	}
	
	CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(i_targetMapIndex);

	// start 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
	if( INFLUENCE_GARDEN_MAP_INDEX == i_targetMapIndex )
	{
		pMapProject = this->GetGardenFieldMapProjectPtr();
	}
	// end 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정

	if (NULL == pMapProject)
	{
		return EVENT_RESULT_BREAK;
	}

	if(pMapProject->IsMultiMapChannel(m_character.InfluenceType))
	{
		SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK|BODYCON_EVENT_SELECTCHANNEL_MASK);
		SendAllChannelState(pMapProject, pMapProject->m_DefaltWarpTargetIndex);
		return EVENT_RESULT_CONTINUE;		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 정상적으로 처리하는 것이므로 리턴값 수정
	}
	return WarpToMap(pMapProject->GetRandomFieldMapChannel(TRUE)->GetMapChannelIndex());
}

BOOL CFieldIOCPSocket::SendAllChannelState(MapIndex_t i_nMapIndex, INT i_nWarpTargetIndex)
{
	CFieldMapProject *pProj = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(i_nMapIndex);
	if (pProj == NULL)
	{
		return FALSE;
	}

	return SendAllChannelState(pProj, i_nWarpTargetIndex);
}

BOOL CFieldIOCPSocket::SendAllChannelState(CFieldMapProject *i_pFieldMapProject, INT i_nWarpTargetIndex)
{
	int offset = 0;
	int nTmpChannelCount = i_pFieldMapProject->GetNumberOfMapChannels();

	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_SUGGEST_CHANNELS, T_FC_EVENT_SUGGEST_CHANNELS,
							pMsgSuggestChannels, pMsgSuggestChannelsBuf);

	pMsgSuggestChannels->MapIndex = i_pFieldMapProject->m_nMapIndex;
	pMsgSuggestChannels->WarpTargetIndex = i_nWarpTargetIndex;
	pMsgSuggestChannels->NumOfChannels = 0;

	offset += MSG_SIZE(MSG_FC_EVENT_SUGGEST_CHANNELS);
	for (int i = 0; i < nTmpChannelCount; i++)
	{
		CFieldMapChannel *pChannel
			= i_pFieldMapProject->GetFieldMapChannelByIndex(i, TRUE);

		if (pChannel == NULL)
		{
			continue;
		}

		MEX_CHANNEL_INFO *pTmpChannelInfo = (MEX_CHANNEL_INFO*)(pMsgSuggestChannelsBuf + offset);
		pTmpChannelInfo->ChannelIndex = pChannel->GetMapChannelIndex().ChannelIndex;
		pTmpChannelInfo->Crowdedness = pChannel->GetCrowdedness();

		offset += sizeof(MEX_CHANNEL_INFO);
		pMsgSuggestChannels->NumOfChannels++;
	}

	SendAddData(pMsgSuggestChannelsBuf, offset);

	return TRUE;
}

BOOL CFieldIOCPSocket::SendAllChannelState(MapIndex_t i_nMapIndex, EVENTINFO *i_pEventInfo)
{
	CFieldMapProject *pProj = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(i_nMapIndex);
	if (pProj == NULL)
	{
		return FALSE;
	}

	return SendAllChannelState(pProj, i_pEventInfo->m_EventwParam2);
}

BOOL CFieldIOCPSocket::SendAllChannelState(CFieldMapProject *i_pFieldMapProject, EVENTINFO *i_pEventInfo)
{
	return SendAllChannelState(i_pFieldMapProject, i_pEventInfo->m_EventwParam2);
}


EventResult_t CFieldIOCPSocket::HandleEvent(EVENTINFO *pEventInfo, const ChannelIndex_t ChannelIndex, BYTE i_byCharacterMode/*=FALSE*/)
{
	// 이미 EVENT_HANDLE중이면 불가
	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK)
		&& FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_SELECTCHANNEL_MASK))
	{// 2006-06-15 by cmkwon, 채널 선택 상태 일경우는 예외 처리한다.
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0021);
		return EVENT_RESULT_BREAK;
	}

	// 죽었을 때는 워프 불가!
	if ( pEventInfo->m_bEventType == EVENT_TYPE_WARP
		&& COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK)
	)
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0022);
		return EVENT_RESULT_BREAK;
	}

	if (this->IsPartyBattleState())
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0023);
		return EVENT_RESULT_BREAK;
	}

	// event type에 따른 작업
	if (pEventInfo->m_bEventType == EVENT_TYPE_ENTER_BUILDING)
	{
		// Process_FC_MOVE_LANDING_DONE()에서 처리한다.
		return EVENT_RESULT_CONTINUE;
	}
	
	if (pEventInfo->m_bEventType == EVENT_TYPE_WARP)
	{

		///////////////////////////////////////////////////////////////////////////////
		// 자신이 공격 하던 몬스터의 AttackedInfoList 에서 자신의 정보를 삭제한다,
		this->DeleteMeFromMonsterAttackedList();

		///////////////////////////////////////////////////////////////////////////
		// 2004-11-17 by cmkwon, 워프시에 Drop Mine 리스트 초기화
		this->ClearAllCharacterMines();
// 2005-11-01 by cmkwon, 맵이 다를 경우만 처리하도록 수정
//		///////////////////////////////////////////////////////////////////////////
//		// 2004-11-17 by cmkwon, 워프시에 PK중이었다면, PK Reset 처리
//		if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
//		{
//			CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
//			OnP2PPKEnd(pPeerPKSocket, this);
//		}
//
		// warp log를 위해
		MapIndex_t logCurrentMapIndex = m_character.MapChannelIndex.MapIndex;
		ChannelIndex_t logCurrentChannIdx	= m_character.MapChannelIndex.ChannelIndex;		// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 -
		AVECTOR3 logCurrentPosition; logCurrentPosition = m_character.PositionVector;

		CFieldMapProject *pMapProj = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pEventInfo->m_EventwParam3);
		if (pMapProj == NULL)
		{
			DBGOUT("[%d] No Such MapProject: [%d]\n", m_character.ClientIndex, pEventInfo->m_EventwParam3);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::HandleEvent# No such MapProject !! %s MapIndex(%d) \r\n", GetCharacterString(GetCharacter(), string()), pEventInfo->m_EventwParam3);
			return EVENT_RESULT_CLOSE_CONNECTION;
		}
		
		if (pMapProj->GetFieldMapChannelByIndex(ChannelIndex) == NULL)
		{
			DBGOUT("[%d] No Such MapChannel: %d at %d\n", (INT)m_character.ClientIndex, (INT)ChannelIndex, (INT)pEventInfo->m_EventwParam3);
			return EVENT_RESULT_BREAK;
		}

		// 2013-08-30 by bckim, 필드이동금지아이템
		if( FALSE == IS_CITY_MAP_INDEX(pMapProj->m_nMapIndex) 
			&& this->m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(DES_MOVEMENT_RESTRICTION_TAKE) )
		{
			this->SendString128(STRING_128_USER_NOTICE,STRMSG_130830_0002);	
			return EVENT_RESULT_BREAK;
		}
		// End. 2013-08-30 by bckim, 필드이동금지아이템

		///////////////////////////////////////////////////////////////////////////////
		// 2006-07-19 by cmkwon, 바자맵은 항상 캐릭터모드
		if(~0 != pEventInfo->m_EventwParam2
			&& (IS_BAZAAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex) || IS_BAZAAR_MAP_INDEX(pMapProj->m_nMapIndex)))
		{// 2006-07-19 by cmkwon, 소스맵 혹은 타겟캡이 바자맵이면 항상 캐릭터모드
			i_byCharacterMode	= TRUE;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2007-08-24 by dhjin, 전진기지 도시맵으로의 워프는 항상 케릭터 모드, 포지션은 설정됨
		if(IS_OUTPOST_CITY_MAP_INDEX(pMapProj->m_nMapIndex))
		{
			i_byCharacterMode			= TRUE;
			pEventInfo->m_vPosition		= pMapProj->GetRandomXZCityWarpTargetPosition();
		}

		// send MSG_FC_EVENT_OTHER_WARP
		INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_OTHER_WARPED, T_FC_EVENT_OTHER_WARPED, pMsgOtherWarped, pMsgOtherWarpedBuf);
		pMsgOtherWarped->ClientIndex	= m_character.ClientIndex;
		pMsgOtherWarped->WarpMapIndex	= pEventInfo->m_EventwParam3;		// 2005-11-01 by cmkwon
		SendInRangeMessageAroundMe(pMsgOtherWarpedBuf, MSG_SIZE(MSG_FC_EVENT_OTHER_WARPED), FALSE);


		CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if (pFParty != NULL)
		{
			pFParty->SendMsgToMembersMap(pMsgOtherWarpedBuf, MSG_SIZE(MSG_FC_EVENT_OTHER_WARPED), m_pCurrentFieldMapChannel, m_character.CharacterUniqueNumber);
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 -
			this->m_SkillManager.ResetDebuffSkill();
			this->m_SkillManager.ResetDotSkill();
		}

		/*
			- 이후의 데이터들을 무시하기 위해 client의 body condition을 WARPING으로 설정
			- client에게 FC_EVENT_WARP 보내기
			- 주위의 client들에게 FC_EVENT_OTHER_WARPED 보내기

			* client에서 FC_EVENT_WARP를 받으면 client가 직접 접속을 끊는다.
			* 접속이 끊어지면 map block에서도 제거함
			* body condition은 FC_EVENT_WARP_CONNECT이후에 warp area를 최초로 벗어날 때 reset됨
		*/

// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 상태버그 수정, 아래쪽으로 이동
// 		// change body condition
// 		SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK);
// 		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_LANDED_MASK))
// 		{
// 			SetBodyConditionBit(m_character.BodyCondition, BODYCON_FLY_MASK);
// 		}

		// 거래중에 워프하면  취소한다
		if (IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
		{
// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 아래와 같이 수정함.
// 			// 해당 캐릭터가 없음
// 			CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
// 			if (NULL == pTargetSocket)
// 			{
// 				SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_TOO_FAR_TO_TRADE, m_peerTraderCharacterUniqueNumber);
// 				SendTradeCanceledAndReset(NULL, FALSE);
// 				return EVENT_RESULT_BREAK;		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 
// 			}
// 
// 			if (D3DXVec3Length(&(m_character.PositionVector-pTargetSocket->m_character.PositionVector)) > REQUERED_TRADE_DISTANCE)
// 			{
// 				SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_TOO_FAR_TO_TRADE);
// 				SendTradeCanceledAndReset(pTargetSocket, TRUE);
// 				return EVENT_RESULT_BREAK;		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 
// 			}
			///////////////////////////////////////////////////////////////////////////////
			// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 거래 취소 처리만 진행, 에러 전송 필요 없음
			SendTradeCanceledAndReset(NULL, TRUE);
		}

		///////////////////////////////////////////////////////////////////////////////		
		// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 상태버그 수정, 거래체크 후로 이동
 		// change body condition
 		SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK);
 		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_LANDED_MASK))
 		{
 			SetBodyConditionBit(m_character.BodyCondition, BODYCON_FLY_MASK);
 		}

// 2005-11-15 by cmkwon, 아래코드로 변경됨
//		if(IS_CITY_MAP_INDEX(pEventInfo->m_EventwParam3))
//		{// 도시맵으로 워프시 차징스킬 초기화
//
//			m_SkillManager.ClearChargingSkill();
//		}
		if(FALSE != i_byCharacterMode)
		{// 캐릭터모드일 때에는 차징스킬 초기화
			m_SkillManager.ClearChargingSkill();
		}

		///////////////////////////////////////////////////////////////////////////////
		// 도시점령전시 공격측, 방어측, 관람측 구별 설정함
		this->m_byCityWarTeamType	= pMapProj->GetCityWarTeamTypeByGuildUID(this->GetCharacter()->GuildUniqueNumber);

		///////////////////////////////////////////////////////////////////////////////
		// 2006-01-23 by cmkwon, 캐릭터 모드 변환 처리
		// 1. 다른맵으로 워프시 아래에서 처리됨
		// 2. 같은맵의 좌표 이동 워프시는 T_FC_CHARACTER_CHANGE_CHARACTER_MODE 프로토코에서 처리됨

		///////////////////////////////////////////////
		// ip, port 가 같고 map 이름이 같을 때 ==> FC_EVENT_WARP_SAME_MAP
		if (pEventInfo->m_EventwParam3 == m_character.MapChannelIndex.MapIndex
			&& ChannelIndex == m_character.MapChannelIndex.ChannelIndex)		// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 - 채널까지 같은 경우 처리
		{
			// send MSG_FC_EVENT_WARP_SAME_MAP
			if(IsUsing() == FALSE || CS_PLAYING != GetClientState())
			{
				return EVENT_RESULT_CLOSE_CONNECTION;
			}

			///////////////////////////////////////////////////////////////////////////
			// 2010-03-30 by cmkwon, 동일맵에서의 워프도 PvP 패배 처리 - 
			if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
			{
				CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
				OnP2PPKEnd(pPeerPKSocket, this);
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2005-07-27 by cmkwon, 동일맵 워프시에는 i_byCharacterMode를 m_character에 적용하지 않고 클라이언트로 전송만 한다. T_FC_CHARACTER_CHANGE_CHARACTER_MODE에서 처리한다.
			// send MSG_FC_EVENT_WARP_SAME_MAP
			INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_WARP_SAME_MAP, T_FC_EVENT_WARP_SAME_MAP, pWarpSameMap, pWarpSameMapBuf);
			pWarpSameMap->PositionVector	= GetWarpTargetPosition(pMapProj, pEventInfo);			// Warp 지점 결정
			pWarpSameMap->CharacterMode0	= i_byCharacterMode;
			SendAddData(pWarpSameMapBuf, MSG_SIZE(MSG_FC_EVENT_WARP_SAME_MAP));

			// send log
			// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 - SendLogMessageWARP() 인자 수정
			CAtumLogSender::SendLogMessageWARP(this, logCurrentMapIndex, logCurrentChannIdx, logCurrentPosition, m_character.MapChannelIndex.MapIndex, m_character.MapChannelIndex.ChannelIndex, pWarpSameMap->PositionVector);

			// HandleEvent()를 강제로 부른 경우에는 삭제해야 함
			if (pEventInfo->m_EventwParam1 == ~0)
			{
				SAFE_DELETE(pEventInfo);
			}
		}
		///////////////////////////////////////////////
		// ip, port 가 같고 map 이름이 다를 때 ==> FC_EVENT_WARP_SAME_FIELD_SERVER
// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 - 아래와 같이 else 로 처리
//		else if (pEventInfo->m_EventwParam3 != m_character.MapChannelIndex.MapIndex
//			&& TRUE == ms_pFieldIOCP->m_FieldServerID.CompareValue(pMapProj->m_strFieldIP, pMapProj->m_sFieldListenPort) )
		else
		{
			///////////////////////////////////////////////////////////////////////////
			// 2005-11-01 by cmkwon, 다른맵으로 워프시에 PK중이었다면, PK Reset 처리
			if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
			{
				CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
				OnP2PPKEnd(pPeerPKSocket, this);
			}

			///////////////////////////////////////////////////////////////////////////
			// NPC Server에 GameEndOK 메세지를 전송한다.
			INIT_MSG_WITH_BUFFER(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, pSendClientGameEndOKBuf);
			pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
			m_pCurrentFieldMapChannel->Send2NPCServerW(pSendClientGameEndOKBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));

			// 남은 시간만큼의 타이머를 잠시 멈추고 저장함
			m_TimerManager.PauseAllTimerEvents();

			/*
				1. map block에서 삭제
				2. DB update: map name, target vector, position vector
			*/
			if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
			{
				char szTemp[256];
				sprintf(szTemp, "[Error] DeleteBlockPosition_1 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);

			// send MSG_FC_EVENT_WARP_SAME_FIELD_SERVER
			// 2007-10-02 by cmkwon, 아래와 같이 수정함 
			//if(IsUsing() == FALSE || CS_PLAYING != GetClientState())
			if(FALSE == IsValidCharacter(FALSE))
			{
				return EVENT_RESULT_CLOSE_CONNECTION;
			}
// 2005-11-08 by cmkwon, 보급상점 추가 중
//			///////////////////////////////////////////////////////////////////////////////
//			// 2005-08-03 by cmkwon, 캐릭터모드일 경우 HP, DP, SP 회복 체크, 총알 충전, 연료를 가득 채우기
//			if(i_byCharacterMode)
//			{
//				m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
//				m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
//				m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
//
//
//				///////////////////////////////////////////////////////////////////////////////
//				// 1형, 2형 총알을 가득 채워 준다.
//				// 2005-06-29 by cmkwon,
//				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);}
//
//				///////////////////////////////////////////////////////////////////////////////
//				// 연료를 가득 채워 준다.
//				if(m_character.CurrentEP < m_character.EP)
//				{
//					m_character.CurrentEP	= m_character.EP;
//					SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
//				}
//			}

			///////////////////////////////////////////////////////////////////////////////
			// 2005-07-27 by cmkwon, i_byCharacterMode를 m_character에 적용하고 클라이언트로 전송한다.
			INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_WARP_SAME_FIELD_SERVER, T_FC_EVENT_WARP_SAME_FIELD_SERVER, pWarpSameField, pWarpSameFieldBuf);
			pWarpSameField->PositionVector	= GetWarpTargetPosition(pMapProj, pEventInfo);			// Warp 지점 결정
			pWarpSameField->CharacterMode0	= i_byCharacterMode;
			
			///////////////////////////////////////////////////////////////////////////////
			// 2010-06-01 by shcho, GLogDB 관련 -
			ATUM_DATE_TIME CurTime;
			CurTime.SetCurrentDateTime(); // 현재 시간을 가져온다.
			MOSTSTAYED_MAP_INFO	* pMostStayedMap;
			pMostStayedMap = NULL;
			// 2010-06-01 by shcho, GLogDB 관련 -
			if(m_StartStayedMapTime.IsValidATUM_DATE_TIME()) 
			{// 최초가 아니면
				pMostStayedMap = this->FindStayedMapInfo(m_character.MapChannelIndex.MapIndex);
				if(NULL != pMostStayedMap) // 맵 인덱스가 있다면 넣는다.
				{
					pMostStayedMap->StayedTime += CurTime.GetTimeDiffTimeInSeconds(m_StartStayedMapTime); // 시간만 넣는다.
				}
				else // 맵 인덱스가 없다면
				{
					MOSTSTAYED_MAP_INFO tempMapInfo; // 벡터에 추가할 맵인덱스와 시간정보
					tempMapInfo.MapIndex	=  m_character.MapChannelIndex.MapIndex; // 현재 맵 인덱스
					tempMapInfo.StayedTime	=  CurTime.GetTimeDiffTimeInSeconds(m_StartStayedMapTime); // 현재 시간에서 시작 시간을 뺀 시간.
					m_vectStayedMapInfo.push_back(tempMapInfo);// 없으면 추가한다.
				}
				m_StartStayedMapTime = CurTime; // 현재 시간을 넣는다.
			}

			///////////////////////////////////////////////////////////////////////////////

			// character 정보 업데이트
			m_character.MapChannelIndex.MapIndex		= pEventInfo->m_EventwParam3;
			m_character.MapChannelIndex.ChannelIndex	= ChannelIndex; // check: MapChannel 도입중, 20040322, kelovon
			m_character.CharacterMode					= i_byCharacterMode;

#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); // 워프 핸들 이벤트  함수 
			}
#endif

			// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
			ApplyMapEntranceCondition(&pMapProj->m_EntranceCondition);
			// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

			// 2006-01-23 by cmkwon
			ClearBodyConditionBit(m_character.BodyCondition, BODYCON_CHARACTER_MODE_MASK);
			if(m_character.CharacterMode)
			{
				SetBodyConditionBit(m_character.BodyCondition,	BODYCON_CHARACTER_MODE_STOP);
			}

			// MSG 채우기
			pWarpSameField->MapWeather			= pMapProj->m_Weather;
			pWarpSameField->MapChannelIndex		= m_character.MapChannelIndex;

			// map name update
			QPARAM_CHARACTER_CHANGE_MAPCHANNEL *pQChangeMap = new QPARAM_CHARACTER_CHANGE_MAPCHANNEL;
			pQChangeMap->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQChangeMap->MapChannelIndex		= m_character.MapChannelIndex;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeMapChannel, this, m_character.AccountUniqueNumber, pQChangeMap);

			// IM Server에도 알림
			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));

			// 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));

			// vector들 update
			m_character.PositionVector  = A2DX(pWarpSameField->PositionVector);
			QPARAM_CHARACTER_CHANGE_POSITION *pQChangePos = new QPARAM_CHARACTER_CHANGE_POSITION;
			pQChangePos->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQChangePos->PositionVector			= m_character.PositionVector;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePosition, this, m_character.AccountUniqueNumber, pQChangePos);

			//send MSG_FC_EVENT_WARP_SAME_FIELD_SERVER
			SendAddData(pWarpSameFieldBuf, MSG_SIZE(MSG_FC_EVENT_WARP_SAME_FIELD_SERVER));






			// 2013-05-09 by hskim, 세력 포인트 개선
#ifdef SC_UPGRADE_INFLUENCE_POINT_HSKIM_BHSOHN
			if( TRUE == IS_INFLUENCE_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex) )
			{
				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));
			}
#endif
			// end 2013-05-09 by hskim, 세력 포인트 개선

			// send log
			// 2007-11-30 by cmkwon, 같은맵에 채널이 다를 경우도 워프 처리 - SendLogMessageWARP() 인자 수정
			CAtumLogSender::SendLogMessageWARP(this, logCurrentMapIndex, logCurrentChannIdx, logCurrentPosition, pWarpSameField->MapChannelIndex.MapIndex, pWarpSameField->MapChannelIndex.ChannelIndex, pWarpSameField->PositionVector);

			// HandleEvent()를 강제로 부른 경우에는 삭제해야 함
			if (pEventInfo->m_EventwParam1 == ~0)
			{
				SAFE_DELETE(pEventInfo);
			}
		}
// 2005-07-27 by cmkwon, 다른 필드서버로의 워프는 지원하지 않으므로 주석처리함
//		///////////////////////////////////////////////
//		// ip, port 가 다르고 map 이름이 다를 때 ==> FC_EVENT_WARP
//		// NOTIFY_WARP 처리해야 함
//		else if (  pEventInfo->m_EventwParam3 != m_character.MapChannelIndex.MapIndex
//				  && FALSE == ms_pFieldIOCP->m_FieldServerID.CompareValue(pMapProj->m_strFieldIP, pMapProj->m_sFieldListenPort) )
//		{
//			// 필드 서버 변경을 위한 close가 발생한다.
//			m_bFieldServerChangeFlag = TRUE;
//
//			///////////////////////////////////////////////////////////////////////////
//			// NPC Server에 GameEndOK 메세지를 전송한다.
//			INIT_MSG_WITH_BUFFER(MSG_FN_CLIENT_GAMEEND_OK, T_FN_CLIENT_GAMEEND_OK, pSendClientGameEndOK, pSendClientGameEndOKBuf);
//			pSendClientGameEndOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
//			pSendClientGameEndOK->ClientIndex	= m_character.ClientIndex;
//			m_pCurrentFieldMapChannel->Send2NPCServerW(pSendClientGameEndOKBuf, MSG_SIZE(MSG_FN_CLIENT_GAMEEND_OK));
//
//			// CPreWinSocket::OnRecvdPacket()의 "case T_FP_EVENT_NOTIFY_WARP_OK:"에서 사용
//			m_pCurrentEventInfo = pEventInfo;
//
//			// IM Server에 알림
//			INIT_MSG_WITH_BUFFER(MSG_FI_EVENT_NOTIFY_WARP, T_FI_EVENT_NOTIFY_WARP, pNotifyWarp, pNotifyWarpBuf);
//			pNotifyWarp->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
//			pNotifyWarp->MapChannelIndex.MapIndex = pEventInfo->m_EventwParam3;
//			pNotifyWarp->MapChannelIndex.ChannelIndex = 0;	// check: MapChannel 도입중, 20040322, kelovon
//			pNotifyWarp->nNumOfTimer = 0; // check: 타이머를 클라이언트에서 관리하므로 다시 구현하기, 20041021, kelovon
//
//			ms_pFieldIOCP->m_pIMWinSocket->Write((char*)pNotifyWarpBuf, MSG_SIZE(MSG_FI_EVENT_NOTIFY_WARP)+sizeof(TIMER_EVENT_4_EXCHANGE)*pNotifyWarp->nNumOfTimer);
//
//			// 이후의 부분은 PreServer로부터 MSG_FP_EVENT_NOTIFY_WARP_OK 를 받고 난 후 처리
//			// 이후의 부분: 각종 설정 및 client에게 EVENT_WARP 보내기
//		}
					
		return EVENT_RESULT_CONTINUE;
	}
	else if ( pEventInfo->m_bEventType == EVENT_TYPE_WARP_TARGET)
	{
/*
#ifdef _DEBUG
		if (pEventInfo->m_bEventType != EVENT_TYPE_NOEVENT)
		{
			DBGOUT("Event[%d] at [%d] (%d, %d) ====> EVENT_TYPE_WARP_TARGET\n",
				pEventInfo->m_bEventType,
				m_pCurrentFieldMapChannel->GetTileInfoIndex(m_character.PositionVector.x, m_character.PositionVector.z),
				(int)m_character.PositionVector.x,
				(int)m_character.PositionVector.z
				);
		}
#endif
*/
		return EVENT_RESULT_CONTINUE;
	}

	// NOT Reachable
	return EVENT_RESULT_CLOSE_CONNECTION;
}

EventResult_t CFieldIOCPSocket::SetWarpTargetPosition(CFieldMapProject *i_pMapProject, EVENTINFO *i_pEventInfo, AVECTOR3 *o_pWarpTargetPosition)
{
	if (i_pEventInfo->m_EventReceiver == EVENT_RECEIVER_OBJECT
			 || ((i_pEventInfo->m_EventReceiver == EVENT_RECEIVER_NONE || i_pEventInfo->m_EventReceiver == EVENT_RECEIVER_TILE) && D3DXVec3Length(&i_pEventInfo->m_vPosition) == 0)
			)
	{
		// Warp 지점이 지정되지 않은 경우
		CFieldMapProject *pNewMapProject
			= (CFieldMapProject *)ms_pFieldIOCP->GetMapWorkspace()->GetMapProjectByMapIndex(i_pEventInfo->m_EventwParam3);
		if (pNewMapProject == NULL)
		{
			//DBGOUT("[%d] No Such MapProject: [%d]\n", m_character.ClientIndex, i_pEventInfo->m_EventwParam3);
			return EVENT_RESULT_CLOSE_CONNECTION;
		}

		if (i_pEventInfo->m_EventwParam2 == ~0)
		{
			// Warp Index가 지정되지 않은 경우
			*o_pWarpTargetPosition = pNewMapProject->GetDefaultPoint();
		}
		else
		{
			// Warp Index가 지정된 경우
			D3DXVECTOR3 v3 = pNewMapProject->GetRandomWarpPoint(i_pEventInfo->m_EventwParam2);
			if (v3.x == -1 && v3.y == -1 && v3.z == -1)
			{
#ifdef _DEBUG
				// check: 맵 오류
				SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0024);
				DBGOUT(STRMSG_S_F2NOTIFY_0025, i_pEventInfo->m_EventwParam3, i_pEventInfo->m_EventwParam2);
				v3 = pNewMapProject->GetDefaultPoint();
#else
				return EVENT_RESULT_CLOSE_CONNECTION;
#endif
			}
			*o_pWarpTargetPosition = v3;
		}
	}
	else if ((i_pEventInfo->m_EventReceiver == EVENT_RECEIVER_TILE || i_pEventInfo->m_EventReceiver == EVENT_RECEIVER_NONE)
		&& D3DXVec3Length(&i_pEventInfo->m_vPosition) != 0)
	{
		// Warp 지점이 지정된 경우
		*o_pWarpTargetPosition = i_pEventInfo->m_vPosition;
	}
	else
	{
		// not reachable
		ASSERT_NEVER_GET_HERE();
	}
	return EVENT_RESULT_CONTINUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			D3DXVECTOR3 CFieldIOCPSocket::GetWarpTargetPosition(CFieldMapProject *i_pMapProject, EVENTINFO *i_pEventInfo)
/// \brief		
/// \author		cmkwon
/// \date		2005-07-27 ~ 2005-07-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 CFieldIOCPSocket::GetWarpTargetPosition(CFieldMapProject *i_pMapProject, EVENTINFO *i_pEventInfo)
{
// 2006-07-03 by cmkwon, 주석 처리
// 	if (IS_CITY_MAP_INDEX(i_pEventInfo->m_EventwParam3))
// 	{
// 		return i_pMapProject->GetRandomCityWarpTargetPosition();
// 	}
	
	if (D3DXVec3Length(&i_pEventInfo->m_vPosition) > 0.0f)
	{// Warp TargetPosition이 지정된 경우
		return i_pEventInfo->m_vPosition;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// Warp TargetPosition이 지정되지 않은 경우
	CFieldMapProject *pNewMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(i_pEventInfo->m_EventwParam3);
	if (pNewMapProject == NULL)
	{
		return i_pEventInfo->m_vPosition;
	}

	if (i_pEventInfo->m_EventwParam2 == ~0)
	{// Warp Index가 지정되지 않은 경우
		return pNewMapProject->GetDefaultPoint();
	}
	
	// Warp Index가 지정된 경우
	return pNewMapProject->GetRandomWarpPoint(i_pEventInfo->m_EventwParam2);	
}

// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
void CFieldIOCPSocket::ApplyMapEntranceCondition(vectorMapEntranceCondition *pEntranceCondition)
{
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	vectorMapEntranceCondition::iterator itr(pEntranceCondition->begin());

	for(; itr != pEntranceCondition->end(); itr++)
	{
		SMAP_ENTRANCE_CONDITION *pEnterCondition = itr;
		ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pEnterCondition->ItemNum);

		if (NULL == pItemG || NULL == pItemG->ItemInfo)
		{
			continue;
		}

		if( MAP_ENTRANCE_CONDITION_OPTION_DELETE == pEnterCondition->Option )
		{
			if( 0 == pEnterCondition->RequireCount )
			{
				continue;
			}

			if (IS_COUNTABLE_ITEM(pItemG->Kind))
			{
				// 카운터블 아이템

				int iRequireCount = (pEnterCondition->RequireCount <= 0 ? pEnterCondition->RequireCount : pEnterCondition->RequireCount * -1);

				ITEM_GENERAL tmpItemForLog = *pItemG;
				tmpItemForLog.CurrentCount += iRequireCount;
				CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);

				m_ItemManager.UpdateItemCountByPointer(pItemG, iRequireCount, IUT_WARP);
			}
			else
			{
				// 일반 아이템

				vectENCHANT tmvectEnchant;

				CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);

				this->PopAllEnchantByItemUID(&tmvectEnchant, pItemG->UniqueNumber);
				m_ItemManager.DeleteItemFromCharacterByUID(pItemG->UniqueNumber, IUT_WARP);
			}
		}
	}
}
// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템


ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_LOGIN(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize	= 0;
	CFieldIOCPSocket			*pFieldIOCPSocket	= NULL;
	const CHARACTER				*pCharacter			= NULL;
	BYTE						SendBuf[SIZE_MAX_PACKET];
	MSG_FP_CONNECT_AUTH_USER	*pSendFPConnectAuthUser = NULL;
	MSG_FC_CONNECT_LOGIN		*pRecvFCConnectLogin = NULL;


	// Client로 부터 계정으로 접속을 받는다
	// 응답으로 T_FC_CONNECT_ID_OK 메세지를 보낸다.

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

	///////////////////////////////////////////////////////////////////////////////
	// 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 에 설정하기 - 
		{// 2007-08-27 by cmkwon, 서버다운준비 상태에서 접속가능 IP 체크
			SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_DOING_SERVER_SHUTDOWN);
			return RES_BREAK;
		}
	}

	if(strnicmp(pRecvFCConnectLogin->AccountName, "", SIZE_MAX_ACCOUNT_NAME) == 0)
	{
		// Protocol Error 처리
		// - AccountName이 비어 있음
		// Error Code : ERR_PROTOCOL_EMPTY_ACCOUNTNAME
		SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_PROTOCOL_EMPTY_ACCOUNTNAME);
		return RES_BREAK;
	}

	// 2014-02-10 by jhseol&bckim, 체널링 - 체널링 번호 확인
#ifdef SC_CHANNELING_JHSEOL_BCKIM_SSJUNG	// - 체널링 번호 확인
	m_nChannelingNum = ms_pFieldIOCP->GetChannellingServerUIDbyToken(pRecvFCConnectLogin->AccountName[0]);
	//m_nChannelingNum = GetChannelingNumByAccountName(pRecvFCConnectLogin->AccountName);
#endif
	// end 2014-02-10 by jhseol&bckim, 체널링 - 체널링 번호 확인
	
	if(CS_RECVLOGIN <= GetClientState())
	{
		// Protocol Error 처리
		// - client state 오류
		// Error Code : ERR_PROTOCOL_INVALID_FIELDSERVER_CLIENT_STATE
		SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_PROTOCOL_INVALID_FIELDSERVER_CLIENT_STATE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// Client가 이중 접속 체크
	mt_auto_lock mtA(&ms_pFieldIOCP->m_mtsetAccountName);
	if(ms_pFieldIOCP->m_mtsetAccountName.end() != ms_pFieldIOCP->m_mtsetAccountName.find(pRecvFCConnectLogin->AccountName))
	{
		SendErrorMessage(T_FC_CONNECT_LOGIN, ERR_PROTOCOL_NOT_LOGINED);
		return RES_BREAK;
	}

	this->SetClientState(CS_RECVLOGIN);			// Client의 Login 상태를 설정한다.
	// 접속자의 AccountName을 설정한다.
	STRNCPY_MEMSET(m_character.AccountName, pRecvFCConnectLogin->AccountName, SIZE_MAX_ACCOUNT_NAME);
	ms_pFieldIOCP->m_mtsetAccountName.insert(pRecvFCConnectLogin->AccountName);
	mtA.auto_unlock_cancel();

#ifdef _ATUM_LOAD_TEST
	if(0 == strnicmp(pRecvFCConnectLogin->AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
	{
		DbgOut("yd-Login-check PRESERVER_AUTH_TYPE_LOGIN\r\n"); // START 2011-11-03 by shcho, yedang 셧다운제 구현 - 임시
		MSG_FP_CONNECT_AUTH_USER_OK *pRMsg = (MSG_FP_CONNECT_AUTH_USER_OK*)(new char[sizeof(MSG_FP_CONNECT_AUTH_USER_OK)]);
		STRNCPY_MEMSET(pRMsg->AccountName, pRecvFCConnectLogin->AccountName, SIZE_MAX_ACCOUNT_NAME);
		pRMsg->UserType = 0;									// 2013-01-22 by khkim GLog 권한변수 0초기화 
		pRMsg->AccountUniqueNumber = 0;
		pRMsg->ClientIndex = this->GetClientArrayIndex();
		pRMsg->AuthType = PRESERVER_AUTH_TYPE_LOGIN;
		DbgOut("Process_FC_CONNECT_LOGIN Running QT_GetAllCharacterInfoByID Birth:[%d]\r\n", pRMsg->Birthday); // START 2011-11-03 by shcho, yedang 셧다운제 구현 - 임시
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetAllCharacterInfoByID, this
			, m_character.AccountUniqueNumber, (MSG_FP_CONNECT_AUTH_USER_OK*)pRMsg);
	}
	else
	{
		// 처리: Pre Server AUTH_USER를 요청한다.
		// set header
		*(MessageType_t*)SendBuf = T_FP_CONNECT_AUTH_USER;
		pSendFPConnectAuthUser = (MSG_FP_CONNECT_AUTH_USER*)(SendBuf + SIZE_FIELD_TYPE_HEADER);

		// set body
		STRNCPY_MEMSET(pSendFPConnectAuthUser->AccountName, pRecvFCConnectLogin->AccountName, SIZE_MAX_ACCOUNT_NAME);
// 2006-05-23 by cmkwon
//		pSendFPConnectAuthUser->FieldServerID = ms_pFieldIOCP->m_FieldServerID;
		pSendFPConnectAuthUser->FieldServerID.SetValue(g_pFieldGlobal->GetPublicIPLocal(), g_pFieldGlobal->GetPortListening());
		STRNCPY_MEMSET(pSendFPConnectAuthUser->PrivateIP, pRecvFCConnectLogin->PrivateIP, SIZE_MAX_IPADDRESS);
		pSendFPConnectAuthUser->ClientIndex = this->GetClientArrayIndex();
		pSendFPConnectAuthUser->AuthType = PRESERVER_AUTH_TYPE_LOGIN;

		// send message to PreServer
		ms_pFieldIOCP->m_pPreWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FP_CONNECT_AUTH_USER));
	}
#else
	// 처리: Pre Server AUTH_USER를 요청한다.
	// set header
	*(MessageType_t*)SendBuf = T_FP_CONNECT_AUTH_USER;
	pSendFPConnectAuthUser = (MSG_FP_CONNECT_AUTH_USER*)(SendBuf + SIZE_FIELD_TYPE_HEADER);

	// set body
	STRNCPY_MEMSET(pSendFPConnectAuthUser->AccountName, pRecvFCConnectLogin->AccountName, SIZE_MAX_ACCOUNT_NAME);
// 2006-05-23 by cmkwon
//	pSendFPConnectAuthUser->FieldServerID = ms_pFieldIOCP->m_FieldServerID;
	pSendFPConnectAuthUser->FieldServerID.SetValue(g_pFieldGlobal->GetPublicIPLocal(), g_pFieldGlobal->GetPortListening());
	STRNCPY_MEMSET(pSendFPConnectAuthUser->PrivateIP, pRecvFCConnectLogin->PrivateIP, SIZE_MAX_IPADDRESS);
	pSendFPConnectAuthUser->ClientIndex = this->GetClientArrayIndex();
	pSendFPConnectAuthUser->AuthType = PRESERVER_AUTH_TYPE_LOGIN;

	// send message to PreServer
	ms_pFieldIOCP->m_pPreWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FP_CONNECT_AUTH_USER));

#endif // END - _ATUM_LOAD_TEST

	///////////////////////////////////////////////////////////////////////////////
	// 2012-10-05 by jhseol, NPlay pc방 모듈 - AccountName으로 소켓 등록
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
	mt_auto_lock mtB(&ms_pFieldIOCP->m_mapAccountName);
	char tmAccountName[SIZE_MAX_ACCOUNT_NAME];
	BOOL rec = ms_pFieldIOCP->m_mapAccountName.insertLock(GGetLowerCase(tmAccountName, pRecvFCConnectLogin->AccountName, SIZE_MAX_ACCOUNT_NAME), this);
	mtB.auto_unlock_cancel();
#endif
	// end 2012-10-05 by jhseol, NPlay pc방 모듈 - AccountName으로 소켓 등록

	m_PeerSocketType = ST_CLIENT_TYPE;

	ms_pFieldIOCP->m_uiAccumulatedUserCounts++;
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_NETWORK_CHECK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-02-15 by cmkwon, Client<->FieldServer 간 네트워크 상태 체크 - CFieldIOCPSocket::Process_FC_CONNECT_NETWORK_CHECK() 추가
/// \author		cmkwon
/// \date		2008-02-15 ~ 2008-02-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_NETWORK_CHECK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CONNECT_NETWORK_CHECK,
									MSG_FC_CONNECT_NETWORK_CHECK, pRMsg);

	if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
	{// 2008-02-15 by cmkwon, 관리자/운영자만 체크 가능하다.
		return RES_BREAK;
	}

	if(100 < pRMsg->nCheckCount)
	{// 2008-02-15 by cmkwon, 한번에 최대 100개로 제한 한다.
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_CONNECT_NETWORK_CHECK_OK, T_FC_CONNECT_NETWORK_CHECK_OK, pSMsg, SendBuf);
	pSMsg->nCheckCount	= pRMsg->nCheckCount;
	pSMsg->dwClientTick	= pRMsg->dwClientTick;
	pSMsg->nWriteBufferSize		= m_mtlistWriteBuf.size();		// 2008-10-31 by cmkwon, 네트워크 상태 체크 관련 수정(버퍼개수도 전송) - 아주 정확한 데이트가 필요한것이 아니므로 lock은 필요 없을것 같음
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CONNECT_NETWORK_CHECK_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_ARENASERVER_LOGIN(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 통합 - 아레나 서버로 클라이언트가 접속 처리
/// \author		dhjin 
/// \date		2007-12-28 ~ 2007-12-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_ARENASERVER_LOGIN(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CONNECT_ARENASERVER_LOGIN,
									MSG_FC_CONNECT_ARENASERVER_LOGIN, pMsg);
	
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-28 by dhjin, 아레나 서버가 아니므로 오류
		// 2009-12-09 by cmkwon, 로그 정보 추가 - 
		SendErrorMessage(T_FC_CONNECT_ARENASERVER_LOGIN, ERR_INVALID_ARENASERVER, 10000, g_pFieldGlobal->IsArenaServer());
		return RES_BREAK;
	}

	CIOCPSocket	*	MFSSock;
	MFSSock = ms_pFieldIOCP->GetMFSSockForArenaServer(pMsg->MFS_ID);
	if(NULL == MFSSock
		|| FALSE == MFSSock->IsUsing())
	{// 2007-12-28 by dhjin, 필드 서버에 대한 정보가 없으면 오류
		// 2009-12-09 by cmkwon, 로그 정보 추가 - 
		SendErrorMessage(T_FC_CONNECT_ARENASERVER_LOGIN, ERR_NO_SUCH_FIELDSERVER, 11000, pMsg->MFS_ID);
		return RES_BREAK;
	}
	
	m_AfsNeedMfsInfo.MFSClientIdx		= pMsg->MFSClientIdx;
	m_AfsNeedMfsInfo.MFSCharacterUID	= pMsg->MFSCharacterUID;
	m_AfsNeedMfsInfo.MFSServerID		= pMsg->MFS_ID;

	INIT_MSG_WITH_BUFFER(MSG_FtoA_AUTH_CHARACTER, T_FtoA_AUTH_CHARACTER, pSendMsg, SendBuf);
	pSendMsg->AccountUID		= pMsg->AccountUID;
	pSendMsg->MFSCharacterUID	= pMsg->MFSCharacterUID;
	pSendMsg->MFSClientIndex	= pMsg->MFSClientIdx;
	pSendMsg->AFSClientIndex	= this->GetClientArrayIndex();
	MFSSock->SendAddData(SendBuf, MSG_SIZE(MSG_FtoA_AUTH_CHARACTER));

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENACHECK] T_FC_CONNECT_ARENASERVER_LOGIN ArenaCUID = %d, CUID = %d, AUID = %d\r\n"
//		, this->m_character.CharacterUniqueNumber, pMsg->MFSCharacterUID, pMsg->AccountUID);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		
/// \author		dhjin
/// \date		2008-03-03 ~ 2008-03-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CONNECT_ARENASERVER_TO_IMSERVER(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(FALSE == g_pFieldGlobal->IsArenaServer())
	{// 2007-12-28 by dhjin, 아레나 서버가 아니므로 오류
		SendErrorMessage(T_FC_CONNECT_ARENASERVER_TO_IMSERVER, ERR_INVALID_ARENASERVER);
		return RES_BREAK;
	}
	
	// IM Server에 등록
	INIT_MSG_WITH_BUFFER(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP, T_FI_CONNECT_NOTIFY_FIELDSERVER_IP, msgNotiryFieldIP, NotiryFieldIPSendBuf);
	msgNotiryFieldIP->CharacterUniqueNumber = this->m_character.CharacterUniqueNumber;
	msgNotiryFieldIP->FieldServerID = ms_pFieldIOCP->m_FieldServerID;

	ms_pFieldIOCP->m_pIMWinSocket->Write(NotiryFieldIPSendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_FIELDSERVER_IP));

	// IM Server에 게임 시작을 알림
	INIT_MSG_WITH_BUFFER(MSG_FI_CONNECT_NOTIFY_GAMESTART, T_FI_CONNECT_NOTIFY_GAMESTART, msgNotifyGameStart, NotifyGameStartSendBuf);
	msgNotifyGameStart->CharacterUniqueNumber = this->m_character.CharacterUniqueNumber;
	msgNotifyGameStart->FieldGameStartType = GST_GAMESTART;
	msgNotifyGameStart->MapChannelIndex = this->m_character.MapChannelIndex;

	ms_pFieldIOCP->m_pIMWinSocket->Write(NotifyGameStartSendBuf, MSG_SIZE(MSG_FI_CONNECT_NOTIFY_GAMESTART));

	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_CHARACTER(const char* pPacket, int nLength, int &nBytesUsed)
{
	char					*pRecvMsg = NULL;
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_GET_CHARACTER);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1400A);
		return RES_RETURN_FALSE;
	}
	pRecvMsg = new char[sizeof(MSG_FC_CHARACTER_GET_CHARACTER)];
	memcpy(pRecvMsg, pPacket+nBytesUsed, nRecvTypeSize);
	nBytesUsed += nRecvTypeSize;

	///////////////////////////////////////////////////////////////////////////////
	// 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 에 설정하기 - 
		{// 2007-08-27 by cmkwon, 서버다운준비 상태에서 접속가능 IP 체크
			SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_DOING_SERVER_SHUTDOWN);
			return RES_BREAK;
		}
	}

	if(m_character.AccountUniqueNumber != ((MSG_FC_CHARACTER_GET_CHARACTER*)pRecvMsg)->AccountUniqueNumber)
	{
		// Protocol Error 처리
		// - 접속한 AccountUniqueNumber와 요청한 AccountUniqueNumber이 다르다
		// Error Code : ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER
		SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER);
		SAFE_DELETE(pRecvMsg);
		return RES_BREAK;
	}
	else if(((MSG_FC_CHARACTER_GET_CHARACTER*)pRecvMsg)->CharacterUniqueNumber == 0)
	{
		// Protocol Error 처리
		// - 요청한 CharacterUniqueNumber가 유효하지 않음
		// Error Code : ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER
		SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		SAFE_DELETE(pRecvMsg);
		return RES_BREAK;
	}

	if(CS_LOGINED > GetClientState())
	{
		// Protocol Error 처리
		// - 유효하지 않은 GetCharacter 메세지
		// Error Code : ERR_PROTOCOL_INVALID_GETCHARACTER
		SendErrorMessage(T_FC_CHARACTER_GET_CHARACTER, ERR_PROTOCOL_INVALID_GETCHARACTER);
		//DbgOut("		GetCharacter Error ClientState[%d]\n", GetClientState());
		SAFE_DELETE(pRecvMsg);
		return RES_BREAK;
	}
	else if(CS_PLAYING <= GetClientState())
	{
		SAFE_DELETE(pRecvMsg);
		return RES_BREAK;
	}

	this->SetClientState(CS_RECVGETCHARACTER);								// Client의 GotCharacter 상태를 설정한다.
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetCharacterInfoByName, this
		, ((MSG_FC_CHARACTER_GET_CHARACTER*)pRecvMsg)->AccountUniqueNumber, (MSG_FC_CHARACTER_GET_CHARACTER*)pRecvMsg);	//  처리
	pRecvMsg = NULL;

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CREATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	CHARACTER				*pCharacter			= NULL;

	// Client로 부터 Character를 만드는 요청을 받는다
	// 응답으로 T_FC_CHARACTER_CREATE_OK 메세지를 보낸다.

	MSG_FC_CHARACTER_CREATE *pRecvCharacterCreate;

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

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - 캐릭터 생성시 캐릭터명 처리
	LowercaseOnly_i_forTurkish(pRecvCharacterCreate->CharacterName, SIZE_MAX_CHARACTER_NAME);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-04 by cmkwon, 서버 다운 진행상태
	if(ms_pFieldIOCP->m_bPrepareShutDown)
	{
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_DOING_SERVER_SHUTDOWN);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-04-09 by cmkwon, 대회 서버 처리
	if(g_pFieldGlobal->GetIsJamboreeServer())
	{
		if (FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER|RACE_DEMO) )
		{// 2007-04-09 by cmkwon, 관리자/운영자/DEMO만 캐릭터 생성 가능
			SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_JAMBOREE_FAIL_CREATE_CHARACTER);
			return RES_BREAK;
		}
	}

	if(m_nNumCharacters >= SIZE_MAX_NUM_CHARACTER)
	{
		// Protocol Error 처리
		// - 더이상 Character를 만들수 없음, 최대 3(SIZE_MAX_NUM_CHARACTER)
		// Error Code : ERR_PROTOCOL_ALREADY_MAX_CHARACTER
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_ALREADY_MAX_CHARACTER, m_nNumCharacters, 0, pRecvCharacterCreate->CharacterName);
		return RES_BREAK;
	}
	else if(pRecvCharacterCreate->AccountUniqueNumber == 0 || m_character.AccountUniqueNumber != pRecvCharacterCreate->AccountUniqueNumber)
	{
		// Protocol Error 처리
		// - 접속한 AccountUniqueNumber와 요청한 AccountUniqueNumber이 다르다
		// Error Code : ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER);
		return RES_BREAK;
	}
	else if(FALSE == CAtumSJ::IsValidCharacterName(pRecvCharacterCreate->CharacterName, g_pFieldGlobal->GetLanguageType()))
	{
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_CHARACTERNAME);
		return RES_BREAK;
	}
	else if(pRecvCharacterCreate->GearStat1.AttackPart < 1 || pRecvCharacterCreate->GearStat1.DefensePart < 1 || pRecvCharacterCreate->GearStat1.FuelPart < 1 ||
		pRecvCharacterCreate->GearStat1.SoulPart < 1 || pRecvCharacterCreate->GearStat1.ShieldPart < 1 || pRecvCharacterCreate->GearStat1.DodgePart < 1)
	{
		// Protocol Error 처리
		// - 받은 State 값중에 마이너스 값이 있음
		// Error Code : ERR_PROTOCOL_STATE_MINUSVALUE
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_STATE_MINUSVALUE);
		return RES_BREAK;
	}
	// 2015-07-29 by bckim, 베트남 메모리 변조 대응 기어타입 축소
	/*
	else if(pRecvCharacterCreate->UnitKind < UNITKIND_BT01 || pRecvCharacterCreate->UnitKind > UNITKIND_ST04)
	{
		// Protocol Error 처리
		// - Unit Kind가 유효하지 않음
		// Error Code : ERR_PROTOCOL_INVALID_UNITKIND
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_UNITKIND);
		return RES_BREAK;
	}
	*/
	else if(pRecvCharacterCreate->UnitKind != UNITKIND_BT01 && pRecvCharacterCreate->UnitKind != UNITKIND_OT01
		&& pRecvCharacterCreate->UnitKind != UNITKIND_DT01	&& pRecvCharacterCreate->UnitKind != UNITKIND_ST01)
	{
		// Protocol Error 처리
		// - Unit Kind가 유효하지 않음
		// Error Code : ERR_PROTOCOL_INVALID_UNITKIND
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_UNITKIND);
		return RES_BREAK;
	}
	// End. 2015-07-29 by bckim, 베트남 메모리 변조 대응 기어타입 축소
	else if (!g_pFieldGlobal->CheckProhibitedName(pRecvCharacterCreate->CharacterName))
	{
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_CHARACTER_NAME, 0, 0, pRecvCharacterCreate->CharacterName);
		return RES_BREAK;
	}
	else if(pRecvCharacterCreate->AutoStatType1 > AUTOSTAT_TYPE_MGEAR_SUPPORT)
	{
		SendErrorMessage(T_FC_CHARACTER_CREATE, ERR_PROTOCOL_INVALID_AUTOSTAT_TYPE, pRecvCharacterCreate->AutoStatType1);
		return RES_BREAK;
	}

	pCharacter = new CHARACTER;
	memset(pCharacter, 0x00, sizeof(CHARACTER));	// 캐릭터 구조체 초기화

	// Client로 부터 받은 값
	pCharacter->ClientIndex = m_character.ClientIndex;
	STRNCPY_MEMSET(pCharacter->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	pCharacter->AccountUniqueNumber = m_character.AccountUniqueNumber;
	STRNCPY_MEMSET(pCharacter->CharacterName, pRecvCharacterCreate->CharacterName, SIZE_MAX_CHARACTER_NAME);
	pCharacter->CharacterUniqueNumber = 0;		// 나중에 DB 생성이 성공하면 할당해줌! QP_CreateCharacter()를 참조
	pCharacter->CharacterName[SIZE_MAX_CHARACTER_NAME-1] = '\0';
	pCharacter->UnitKind		= pRecvCharacterCreate->UnitKind;
	pCharacter->Race			= pRecvCharacterCreate->Race & RACE_ALL;	// 2007-03-07 by cmkwon, 캐릭생성시 메모리해킹이 발생 할 수 있으므로 권한관련 비트는 초기화 한다.
	pCharacter->AutoStatType	= AUTOSTAT_TYPE_FREESTYLE;
// 2005-06-30 by cmkwon, 강제로 AUTOSTAT_TYPE_FREESTYLE로 설정
//	pCharacter->AutoStatType	= pRecvCharacterCreate->AutoStatType1;
	pCharacter->GearStat		= CAtumSJ::GetGearStatChangeValueStruct(pRecvCharacterCreate->UnitKind)->GearStat1;
	pCharacter->Gender			= pRecvCharacterCreate->Gender;
	pCharacter->PilotFace		= pRecvCharacterCreate->PilotFace;
	pCharacter->InfluenceType	= INFLUENCE_TYPE_NORMAL;				// 일반세력 기본 할당
//	pCharacter->InfluenceType	= pRecvCharacterCreate->InfluenceType0;

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-07 by cmkwon, 선택 가능한 세력Mask를 설정
	pCharacter->SelectableInfluenceMask	= this->GetSelectableInfluenceMask();

	// Client Default 값
	memset(pCharacter->GuildName, 0x00, SIZE_MAX_GUILD_NAME);
	pCharacter->GuildUniqueNumber	= 0;
	pCharacter->Level			= 1;
	pCharacter->Experience		= 0;
	pCharacter->BodyCondition	= BODYCON_FLY_MASK;
	pCharacter->Propensity		= 0;
	pCharacter->Status			= 0;
	pCharacter->PKWinPoint		= 0;
	pCharacter->PKLossPoint		= 0;
	pCharacter->Material		= 0;									// 나중에 고려사항
	memset(pCharacter->PetName, 0x00, SIZE_MAX_PET_NAME);
	pCharacter->PetLevel		= 0;
	pCharacter->PetExperience	= 0;
	pCharacter->CharacterMode	= FALSE;

	CFieldMapProject *pCityMapPro = this->GetCityFieldMapProjectPtr(pCharacter->InfluenceType, pCharacter->GetStartCityMapIndex());	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_CREATE
	if(pCityMapPro)
	{
		pCharacter->MapChannelIndex.MapIndex		= pCityMapPro->m_nMapIndex;
		pCharacter->MapChannelIndex.ChannelIndex	= 0;
		pCharacter->PositionVector					= pCityMapPro->GetRandomXZCityWarpTargetPosition();	//
		pCharacter->CharacterMode					= TRUE;			// 2005-10-06 by cmkwon, 도시 일경우 캐릭터 모드로 설정
	}
	else
	{
		pCharacter->MapChannelIndex.MapIndex		= ms_pFieldIOCP->m_pDefaultMapProject->m_nMapIndex;
		pCharacter->MapChannelIndex.ChannelIndex	= 0;
		pCharacter->PositionVector					= ms_pFieldIOCP->m_pDefaultMapProject->GetRandomCityWarpTargetPosition();	//
	}
// 2005-11-10 by cmkwon, 모두 튜토리얼 진
//	if(COMPARE_RACE(m_character.Race, RACE_OPERATION))
	{// 관리자만 튜토리얼맵으로 설정함
		CFieldMapProject *pTutorialFMapPro			= ms_pFieldIOCP->GetFieldMapProjectByMapIndex(TUTORIAL_MAP_INDEX);
		if(pTutorialFMapPro)
		{
			pCharacter->MapChannelIndex.MapIndex	= pTutorialFMapPro->m_nMapIndex;
		}
	}

	// 2005-10-06 by cmkwon, 캐릭터 모두일때 도시가 아니면 기어모드로 변경한다.
	if(pCharacter->CharacterMode
		&& pCityMapPro->m_nMapIndex != pCharacter->MapChannelIndex.MapIndex)
	{
		pCharacter->CharacterMode	= FALSE;
	}

	// 착륙 가능 지역이면 착륙 상태로 set
	TILEINFO *pTile = ms_pFieldIOCP->m_pDefaultMapProject->GetTileInfo(&pCharacter->PositionVector);
	if (pTile && pTile->m_bEnableLand)
	{
		SetBodyConditionBit(pCharacter->BodyCondition, BODYCON_LANDED_MASK);
	}
	pCharacter->MaxLevel		= 1;									// Check 나중에 최대 올라갔던 레벨
	pCharacter->BonusStat		= 0;
// 2005-11-15 by cmkwon, 삭제함
//	pCharacter->BonusSkillPoint	= 0;

	pCharacter->HP			= CAtumSJ::GetCharacterHP(pCharacter->Level);
	pCharacter->CurrentHP	= pCharacter->HP;
	pCharacter->DP			= CAtumSJ::GetCharacterDP(pCharacter->GearStat.ShieldPart, pCharacter->Level);	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	pCharacter->CurrentDP	= pCharacter->DP;
	pCharacter->SP			= CAtumSJ::GetCharacterSP(pCharacter->GearStat.SoulPart, pCharacter->Level);	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	pCharacter->CurrentSP	= pCharacter->SP;
	pCharacter->EP			= CAtumSJ::GetCharacterEP(pCharacter->GearStat.FuelPart, pCharacter->Level);	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	pCharacter->CurrentEP	= pCharacter->EP;

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - 캐릭터 생성시, 계정 처리
	LowercaseOnly_i_forTurkish(pCharacter->AccountName, SIZE_MAX_ACCOUNT_NAME);

	// 처리
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CreateCharacter, this, m_character.AccountUniqueNumber, pCharacter);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	char					*pRecvMsg = NULL;
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;
	MSG_FC_CHARACTER_DELETE	*pMsgDel			= NULL;

	// Client로부터 Character를 삭제하는 요청을 받음
	// 응답으로 T_FC_CHARACTER_DELETE_OK 메세지를 보낸다.

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_DELETE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1400C);
		return RES_RETURN_FALSE;
	}
	pRecvMsg = new char[sizeof(MSG_FC_CHARACTER_DELETE)];
	memcpy(pRecvMsg, pPacket+nBytesUsed, nRecvTypeSize);
	nBytesUsed += nRecvTypeSize;

	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-04 by cmkwon, 서버 다운 진행상태
	if(ms_pFieldIOCP->m_bPrepareShutDown)
	{
		SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_DOING_SERVER_SHUTDOWN);
		return RES_BREAK;
	}

	pMsgDel = (MSG_FC_CHARACTER_DELETE*)pRecvMsg;
	if( pMsgDel->AccountUniqueNumber == 0)
	{
		// Protocol Error 처리
		// - 접속한 AccountUniqueNumber와 요청한 AccountUniqueNumber이 다르다
		// Error Code : ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER
		SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER);
		return RES_BREAK;
	}
	
	if ( pMsgDel->CharacterUniqueNumber == 0)
	{
		// Protocol Error 처리
		// - 요청한 CharacterUniqueNumber가 유효하지 않음
		// Error Code : ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER
		SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - 캐릭터 삭제시 2차패스워드 체크
	if(g_pFieldGlobal->GetUseSecondaryPasswordSystemFlag()
		&& this->IsSettingSecondaryPassword())
	{
		if(FALSE == this->CompareSecondaryPassword(pMsgDel->CurrentSecPassword))
		{
			SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_SECPASS_PASSWORD_NOT_MATCHED);
			return RES_BREAK;
		}
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-11-09 by dhjin, 전진기지 관련하여 처리
	if(IS_VALID_UNIQUE_NUMBER(this->m_character.GuildUniqueNumber)				// 2007-12-18 by dhjin, 버그 수정
		&& ms_pFieldIOCP->m_OutPostManager.CheckALLOutPostWaring()
		&& ms_pFieldIOCP->m_OutPostManager.CheckOutPostPossessByGuildUID(this->m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CHARACTER_DELETE, ERR_WARING_OUTPOST_TO_OWNMAP);
		return RES_BREAK;
	}

		
	// 처리
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteCharacter, this, pMsgDel->AccountUniqueNumber, (MSG_FC_CHARACTER_DELETE*)pRecvMsg);
	pRecvMsg = NULL;
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_OTHER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;
	MSG_FC_CHARACTER_GET_OTHER_INFO *pRecvFCCharacterGetOtherInfo = NULL;

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

// 2006-07-03 by cmkwon, 주석 처리
// 	if (IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
// 	{
// 		return RES_BREAK;
// 	}

	SendCharacterOtherInfo(pRecvFCCharacterGetOtherInfo->ClientIndex);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_OTHER_MOVE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;
	MSG_FC_CHARACTER_GET_OTHER_MOVE *pRecvFCCharacterGetOtherMove = NULL;

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

	CFieldMapChannel *pFMChann = GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	if (pRecvFCCharacterGetOtherMove->OtherClientIndex < MONSTER_CLIENT_INDEX_START_NUM)
	{
		// Character인 경우
		CFieldIOCPSocket *pOtherSock = ms_pFieldIOCP->GetFieldIOCPSocket(pRecvFCCharacterGetOtherMove->OtherClientIndex);

		// stealth 상태이면 return함
		if (pOtherSock == NULL
			|| FALSE == pOtherSock->IsValidCharacter(FALSE)
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//			|| COMPARE_BODYCON_BIT(pOtherSock->m_character.BodyCondition, BODYCON_STEALTH_MASK)
			|| pOtherSock->IsInvisibleCharacter()
			|| IS_TUTORIAL_MAP_INDEX(pFMChann->GetMapChannelIndex().MapIndex)
			)
		{
			return RES_BREAK;
		}

		if (FALSE == pOtherSock->IsValidCharacter(FALSE)
			|| pFMChann != pOtherSock->GetCurrentFieldMapChannel())
		{// 2006-01-10 by cmkwon, 캐릭터가 유효하지 않거나 맵채널이 다르면

			INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DELETE_OTHER_INFO, T_FC_CHARACTER_DELETE_OTHER_INFO, pDeleteOther, pDeleteOtherBuf);
			pDeleteOther->OtherClientIndex = pRecvFCCharacterGetOtherMove->OtherClientIndex;
			SendAddData(pDeleteOtherBuf, MSG_SIZE(MSG_FC_CHARACTER_DELETE_OTHER_INFO));
			return RES_RETURN_TRUE;
		}

		// 거리를 확인함
		D3DXVECTOR3	tmVec3 = pOtherSock->m_character.PositionVector - m_character.PositionVector;
		tmVec3.y = 0.0f;
		if (D3DXVec3Length(&tmVec3) > m_pCurrentFieldMapChannel->GetUserVisibleDiameterW()/2)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DELETE_OTHER_INFO, T_FC_CHARACTER_DELETE_OTHER_INFO, pDeleteOther, pDeleteOtherBuf);
			pDeleteOther->OtherClientIndex = pRecvFCCharacterGetOtherMove->OtherClientIndex;
			SendAddData(pDeleteOtherBuf, MSG_SIZE(MSG_FC_CHARACTER_DELETE_OTHER_INFO));
			return RES_RETURN_TRUE;
		}

		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));
	}
	else
	{
		// Monster인 경우
		CFieldMonster	*pMonster = m_pCurrentFieldMapChannel->GetFieldMonster(pRecvFCCharacterGetOtherMove->OtherClientIndex, 6);

		if(NULL == pMonster
			|| MS_NULL == pMonster->m_enMonsterState
			|| MS_DEAD == pMonster->m_enMonsterState)
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DELETE_OTHER_INFO, T_FC_CHARACTER_DELETE_OTHER_INFO, pDeleteOther, pDeleteOtherBuf);
			pDeleteOther->OtherClientIndex = pRecvFCCharacterGetOtherMove->OtherClientIndex;
			SendAddData(pDeleteOtherBuf, MSG_SIZE(MSG_FC_CHARACTER_DELETE_OTHER_INFO));
			return RES_RETURN_TRUE;
		}

		D3DXVECTOR3	tmVec3 = pMonster->PositionVector - m_character.PositionVector;
		tmVec3.y = 0.0f;
		if (D3DXVec3Length(&tmVec3) > m_pCurrentFieldMapChannel->GetUserVisibleDiameterW()/2
			&& FALSE == IS_MAP_INFLUENCE_INFINITY(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피니티맵에서는 몬스터 정보를 계속 보낸다.
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DELETE_OTHER_INFO, T_FC_CHARACTER_DELETE_OTHER_INFO, pDeleteOther, pDeleteOtherBuf);
			pDeleteOther->OtherClientIndex = pRecvFCCharacterGetOtherMove->OtherClientIndex;
			SendAddData(pDeleteOtherBuf, MSG_SIZE(MSG_FC_CHARACTER_DELETE_OTHER_INFO));
			return RES_RETURN_TRUE;
		}

		INIT_MSG_WITH_BUFFER(MSG_FC_MONSTER_MOVE_OK, T_FC_MONSTER_MOVE_OK, pSendMMoveOK, SendBuf);
		pSendMMoveOK->MonsterIndex		= pMonster->MonsterIndex;
		pSendMMoveOK->TargetIndex		= pMonster->GetAttackerCliIdx();		// 2006-11-07 by cmkwon
		pSendMMoveOK->PositionVector	= pMonster->PositionVector;
		pSendMMoveOK->TargetVector		= pMonster->TargetVector*1000.0f;
		SendAddData(SendBuf, MSG_SIZE(MSG_FC_MONSTER_MOVE_OK));
// 2007-03-29 by cmkwon, 위와 같이 수정함
//		INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_OK, T_FC_MOVE_OK, pMoveOK, pMoveOKBuf);
//		pMoveOK->ClientIndex	= pMonster->MonsterIndex;
//		pMoveOK->CharacterMode0	= FALSE;
//		pMoveOK->PositionVector = pMonster->PositionVector;
//		pMoveOK->TargetVector	= pMonster->TargetVector*1000.0f;
//		pMoveOK->UpVector		= pMonster->UpVector;
//		SendAddData(pMoveOKBuf, MSG_SIZE(MSG_FC_MOVE_OK));
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_OTHER_RENDER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize	= 0;
	MSG_FC_CHARACTER_GET_OTHER_RENDER_INFO *pGetRenderInfo = NULL;

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

	CFieldIOCPSocket *pOtherSock = ms_pFieldIOCP->GetFieldIOCPSocket(pGetRenderInfo->ClientIndex);
	if (pOtherSock == NULL || !pOtherSock->IsUsing())
	{
		// 2004-12-08 by cmkwon, SystemLog로 남기지 않는다
		SendErrorMessage(T_FC_CHARACTER_GET_OTHER_RENDER_INFO, ERR_PROTOCOL_INVALID_CLIENTINDEX, pGetRenderInfo->ClientIndex, 0, NULL, FALSE, FALSE);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_OTHER_RENDER_INFO_OK, T_FC_CHARACTER_GET_OTHER_RENDER_INFO_OK, pRenderInfoOK, pRenderInfoOKBuf);
	pRenderInfoOK->ClientIndex = pGetRenderInfo->ClientIndex;
	pRenderInfoOK->CharacterRenderInfo = pOtherSock->m_UnitRenderInfo;
	SendAddData(pRenderInfoOKBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_RENDER_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_ACCOUNTUNIQUENUMBER(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	MSG_FC_CHARACTER_GET_ACCOUNTUNIQUENUMBER *pGetAccountNum = NULL;

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

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetAccountUniqueNumber, this, m_character.AccountUniqueNumber, pGetAccountNum);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_APPLY_COLLISION_DAMAGE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize	= 0;
	MSG_FC_CHARACTER_APPLY_COLLISION_DAMAGE	*pApplyCollision = NULL;

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

	if (FALSE == IsValidCharacter())
	{
		// 이미 죽은 이후에 오는 MSG는 무시한다.
		return RES_RETURN_TRUE;
	}

	if(GCheckLimitLevel(CHECK_TYPE_LOWLEVEL_ADVANTAGE, m_character.Level))
	{// 2006-03-15 by cmkwon, 낮은 레벨 혜택 처리
		return RES_RETURN_TRUE;
	}

	if(IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{// 2007-07-19 by dhjin, 튜토리얼 맵에서는 데미지를 입지 않는다.
		return RES_RETURN_TRUE;
	}

	float fPenalty = ( (float)(m_character.HP + m_character.DP) ) * CAtumSJ::GetPenaltyCollisionBYSpeed(pApplyCollision->SpeedOfCollision);
	if(0.0f >= fPenalty)
	{// 2006-08-08 by cmkwon, 0보다 작거나 같으면
		return RES_RETURN_TRUE;
	}

	if (TRUE == this->CheckSKILLInvincible())
	{// 2006-11-27 by dhjin, M기어의 무적이면 데미지 0
		fPenalty = 0.0f;
	}

	switch (pApplyCollision->CollisionType)
	{
	case COLLISION_TYPE_LAND:
		{
			if (m_character.PositionVector.y < m_pCurrentFieldMapChannel->m_pFieldMapProject->m_sMaximumAltitude)
			{
				DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION);		// check: 정확한 값 정해야 함
			}
			else
			{
				// 최고 고도 이상이면
				DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION);		// check: 정확한 값 정해야 함
			}
		}
		break;
	case COLLISION_TYPE_BUILDING:
		{
			DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION);		// check: 정확한 값 정해야 함
		}
		break;
	case COLLISION_TYPE_CHARACTER:
		{
			DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION);		// check: 정확한 값 정해야 함
		}
		break;
	case COLLISION_TYPE_MONSTER:
		{
			fPenalty /= 10.0f;			// 2006-08-08 by cmkwon, 몬스터와의 충돌데이지만 10으로 나누어 처리한다
			CFieldMonster *ptmFMon = m_pCurrentFieldMapChannel->GetFieldMonster(pApplyCollision->UnitIndex, 22);
			if(NULL == ptmFMon
				|| ptmFMon->m_enMonsterState != MS_PLAYING
				|| TRUE == COMPARE_BODYCON_BIT(ptmFMon->BodyCondition, BODYCON_DEAD_MASK))
			{
				return RES_RETURN_TRUE;
			}
			if(IS_SAME_CHARACTER_MONSTER_INFLUENCE(m_character.InfluenceType, ptmFMon->MonsterInfoPtr->Belligerence))
			{// 2005-12-28 by cmkwon, 캐릭터와 몬스터의 세력이 같으면 충돌시 데미지 없음
				return RES_RETURN_TRUE;
			}

			if(EVENT_TYPE_NO_OBJECT_MONSTER == ptmFMon->m_byObjectMonsterType)
			{
				DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION, TRUE, ptmFMon);		// check: 정확한 값 정해야 함

				// 2005-08-04 by cmkwon, 몬스터도 HP를 줄인다.
				ptmFMon->CurrentHP = max(1.0f, ptmFMon->CurrentHP-fPenalty);
				m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(ptmFMon, T_FN_MONSTER_CHANGE_HP);				
				return RES_RETURN_TRUE;
			}

			ITEM *pObjectMonsterItem = ptmFMon->FindItemPtrByOrBitTyp(ORBIT_OBJBEAM);
			if(NULL == pObjectMonsterItem)
			{
				DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION, TRUE, ptmFMon);		// check: 정확한 값 정해야 함
				return RES_RETURN_TRUE;
			}

			MSG_FN_BATTLE_ATTACK_PRIMARY attackPri;
			MEMSET_ZERO(&attackPri, sizeof(MSG_FN_BATTLE_ATTACK_PRIMARY));
			attackPri.ChannelIndex		= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
			attackPri.AttackIndex		= ptmFMon->MonsterIndex;
			attackPri.TargetIndex		= this->m_character.ClientIndex;
			attackPri.WeaponItemNumber	= pObjectMonsterItem->ItemNum;
			attackPri.WeaponIndex		= 0;
			attackPri.TargetPosition	= this->m_character.PositionVector;			
			int nTemp = 0;
			ProcessResult reted = Process_FN_BATTLE_ATTACK_PRIMARY(NULL, 0, nTemp, &attackPri, m_pCurrentFieldMapChannel->m_pFieldMapProject);
			if(RES_RETURN_TRUE != reted)
			{
				DecreaseCharacterHPDP(fPenalty, DAMAGE_BY_COLLISION, TRUE, ptmFMon);		// check: 정확한 값 정해야 함
			}
		}
		break;
	default:
		{
			return RES_BREAK;
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_SHOW_EFFECT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_SHOW_EFFECT,
									MSG_FC_CHARACTER_SHOW_EFFECT, pMsgShowEffect);

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_SHOW_EFFECT_OK, T_FC_CHARACTER_SHOW_EFFECT_OK, msgShowOK, msgShowOKBuf);
	msgShowOK->ClientIndex = m_character.ClientIndex;
	msgShowOK->EffectIndex = pMsgShowEffect->EffectIndex;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, msgShowOKBuf, MSG_SIZE(MSG_FC_CHARACTER_SHOW_EFFECT_OK),
													GetCurrentFieldMapChannel(), FALSE, GetCurrentFieldMapChannel()->GetUserVisibleDiameterW());

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_OTHER_PARAMFACTOR(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_OTHER_PARAMFACTOR,
									MSG_FC_CHARACTER_GET_OTHER_PARAMFACTOR, pMsgGetParamFactor);

	CFieldIOCPSocket *pSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgGetParamFactor->ClientIndex);
	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	//if (pSocket == NULL || !pSocket->IsUsing())
	if (pSocket == NULL || FALSE == pSocket->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_CHARACTER_GET_OTHER_PARAMFACTOR, ERR_COMMON_NO_SUCH_CHARACTER);
		return RES_BREAK;
	}

	// 대상의 정보를 자신에게 보내기
	pSocket->SendParamFactorToOthers(pMsgGetParamFactor->ItemPosition, m_character.ClientIndex, FALSE);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE,
									MSG_FC_CHARACTER_SEND_PARAMFACTOR_IN_RANGE, pMsgSendParamFactor);

	// 자신의 정보를 주위에 보내기
	SendParamFactorToOthers(pMsgSendParamFactor->ItemPosition, INVALID_CLIENT_INDEX, TRUE);

	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_SPEED_HACK_USER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_SPEED_HACK_USER,
		MSG_FC_CHARACTER_SPEED_HACK_USER, pRecvMsg);

	///////////////////////////////////////////////////////////////////////////////
	// 서버에서 체크중인 SpeedHack정보도 체크하여 TRUE를 리턴할때만 로그를 남긴다
	if(this->WriteLogMessageSpeedHack(SPEEDHACK_CHECK_TYPE_BY_CLIENT))
	{
		///////////////////////////////////////////////////////////////////////////////
		// 클라이언트로 전송받은 SpeedHack 정보를 LogServer로 전송한다
		// 2004-11-12, cmkwon, Speed Hack 사용자, DB에 저장 해야함
		// AccountName, CharacterName, MapChannelIndex
		// CheckType, ReceivedMoveCounts,
		// 엔진ItemNum, ServerPastTime, ClientPastTime, PastDistance, CurrentSpeed, 현재 시간(초단위)
		CAtumLogSender::SendLogMessageSpeedHack(this, SPEEDHACK_CHECK_TYPE_BY_CLIENT, pRecvMsg->nSendMoveCounts
			, ((m_ItemRear.ItemNum == 0)?0 : ((ITEM_BASE*)m_ItemRear.ItemNum)->ItemInfo->ItemNum)
			, 0, pRecvMsg->dwTimeGap, 0, 0);
		char szSystem[512];
		sprintf(szSystem, "	SpeedHack User by Client ==> AccountName(%10s) CharacterName(%10s) MapChannelIndex(%s) RecvMoveCounts(%5d) ClientPastTime(%4d)\r\n"
			, m_character.AccountName
			, m_character.CharacterName
			, GET_MAP_STRING(m_character.MapChannelIndex)
			, pRecvMsg->nSendMoveCounts
			, pRecvMsg->dwTimeGap);
//		DBGOUT(szSystem);
		g_pFieldGlobal->WriteSystemLog(szSystem);

		// 2013-01-29 by hskim, 스피드핵 자동 블럭 기능 구현
#ifdef S_AUTO_BLOCK_SYSTEM_HSKIM
		m_SpeedHackHistory.InsertResult(TRUE);

		if( TRUE == m_SpeedHackHistory.IsBlock() )
		{
			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_SPEEDHACK_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, "SpdHack");

				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 2013-01-29 by hskim, 스피드핵 자동 블럭 기능 구현
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_CASH_MONEY_COUNT(const char* pPacket, int nLength, int &nBytesUsed)
{
	int nTotalMoney	= 0;
	int nMCash		= 0;
	int nGiftCard	= 0;
	Err_t nRetedErr = CashItemMoneyPay(&nTotalMoney, &nMCash, &nGiftCard);
	if(ERR_NO_ERROR != nRetedErr)
	{
		SendErrorMessage(T_FC_CHARACTER_GET_CASH_MONEY_COUNT, nRetedErr);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 클라이언트에 전송한다
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK, T_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK, pSOK, SendBuf);
	pSOK->nMCash			= nMCash;
	pSOK->nGiftCard			= nGiftCard;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_CASH_MONEY_COUNT_OK));
	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_TUTORIAL_SKIP(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_TUTORIAL_SKIP,
		MSG_FC_CHARACTER_TUTORIAL_SKIP, pRMsg);

	if(FALSE == IsUsing())
	{
		SendErrorMessage(T_FC_CHARACTER_TUTORIAL_SKIP, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock ccLock(&m_mtvectCharacterCache);
	CHARACTER *pCharac = this->GetCharacterCacheNoLock(pRMsg->CharacterUniqueNumber);
	if(NULL == pCharac)
	{
		SendErrorMessage(T_FC_CHARACTER_TUTORIAL_SKIP, ERR_PROTOCOL_NOT_TUTORIAL_MAP, m_character.MapChannelIndex.MapIndex, 1);
		return RES_BREAK;
	}
	if(FALSE == IS_TUTORIAL_MAP_INDEX(pCharac->MapChannelIndex.MapIndex))
	{
		SendErrorMessage(T_FC_CHARACTER_TUTORIAL_SKIP, ERR_PROTOCOL_NOT_TUTORIAL_MAP, pCharac->MapChannelIndex.MapIndex, 2);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 세력별 도시맵으로 설정한다
	CFieldMapProject *pCityMapPro = this->GetCityFieldMapProjectPtr(pCharac->InfluenceType, pCharac->GetStartCityMapIndex());	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_TUTORIAL_SKIP, // 2007-08-01 by cmkwon, 일반세력 도시맵이동 버그 수정
	if(pCityMapPro)
	{
		pCharac->MapChannelIndex.MapIndex		= pCityMapPro->m_nMapIndex;
		pCharac->MapChannelIndex.ChannelIndex	= 0;
		pCharac->PositionVector					= pCityMapPro->GetRandomXZCityWarpTargetPosition();	//
		pCharac->CharacterMode					= TRUE;
	}
	else
	{
		pCharac->MapChannelIndex.MapIndex		= ms_pFieldIOCP->m_pDefaultMapProject->m_nMapIndex;
		pCharac->MapChannelIndex.ChannelIndex	= 0;
		pCharac->PositionVector					= ms_pFieldIOCP->m_pDefaultMapProject->GetRandomCityWarpTargetPosition();	//
		pCharac->CharacterMode					= FALSE;
	}

// 2006-10-13 by cmkwon, pCharac 자체를 수정하는 것으로 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-09-28 by cmkwon,
//	this->UpdateCharacterCacheLock(m_character.CharacterUniqueNumber, &m_character);

	///////////////////////////////////////////////////////////////////////////////
	// 클라이언트에 전송한다
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_TUTORIAL_SKIP_OK, T_FC_CHARACTER_TUTORIAL_SKIP_OK, pSTSkipOK, SendBuf);
	pSTSkipOK->ClientIndex							= this->GetClientArrayIndex();
	pSTSkipOK->CharacterUniqueNumber				= pCharac->CharacterUniqueNumber;
	pSTSkipOK->mapChannelIdx						= pCharac->MapChannelIndex;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_TUTORIAL_SKIP_OK));
	return RES_RETURN_TRUE;
}

// 2005-07-26 by hblee : 착륙장에서 캐릭터 모드 변환.
// 2005-11-14 by cmkwon, 같은맵에서 캐리터 모드 변환이 발생할 때만 클라이언트로부터 받는 메시지
//						 다른맵일 경우는 필요 없음
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_CHARACTER_MODE(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 메시지를 받아온다.
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_CHANGE_CHARACTER_MODE,
		MSG_FC_CHARACTER_CHANGE_CHARACTER_MODE, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-11-14 by cmkwon, 보급 상점 띄우기 체크
	if(pRecvMsg->CharacterMode0)
	{
		if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
		{// 2006-10-10 by cmkwon, P2P PK중에 캐릭터모드로 변경시는 패배처리
			CFieldIOCPSocket *pPeerPKSocket = ms_pFieldIOCP->GetFieldIOCPSocket(m_peerP2PPKClientIndex);
			OnP2PPKEnd(pPeerPKSocket, this);
		}

		if(FALSE == IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex)
			&& FALSE == IS_BAZAAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
		{// 2006-07-20 by cmkwon, P2P PK중이 아니고 바자맵이 아닌경우

			EVENTINFO *pEventInfo = m_pCurrentFieldMapChannel->GetTileEventInfoW(&A2DX(pRecvMsg->PositionAVec3));

			// P2P PK 중이면 상점 못들어감
			if (pEventInfo
				&& pEventInfo->m_bEventType == EVENT_TYPE_ENTER_BUILDING)
			{
		// 2006-07-20 by cmkwon, 필요 없는 부분인것 같음 
//		 		// building에서 나왔을 때 target vector 결정
//		 		D3DXVec3Normalize(&m_character.TargetVector, &-m_character.TargetVector);
//		 
//		 		// building에서 나왔을 때 position vector 결정
//		 		D3DXVECTOR3 vTmp = m_character.PositionVector + (40 * m_character.TargetVector);
//		 		m_pCurrentFieldMapChannel->UpdateBlockPosition(m_character.PositionVector, vTmp, m_character.ClientIndex);
//		 		m_character.PositionVector = vTmp;

				// MSG_FC_EVENT_ENTER_BUILDING 전송
				INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, SendBuf);
				BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pEventInfo->m_EventwParam1);
				if(pBuildingNPC)
				{
					pMsgEnterBuilding->BuildingNPCInfo				= *pBuildingNPC;
		// 2006-02-08 by cmkwon
		//			pMsgEnterBuilding->fCityWarTexRate				= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pBuildingNPC->BuildingIndex, m_character.GuildUniqueNumber);
					pMsgEnterBuilding->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
					SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));
				}
			}
		}// END - if(FALSE == IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex)	&& FALSE == IS_BAZAAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	}// END - if(pRecvMsg->CharacterMode0)

	// 캐릭터 정보를 저장한다.
	D3DXVECTOR3		Vec3BeforePosition = m_character.PositionVector;
	m_character.CharacterMode = pRecvMsg->CharacterMode0;
	m_character.PositionVector = A2DX(pRecvMsg->PositionAVec3);
	m_character.TargetVector = A2DX(pRecvMsg->TargetAVec3);
	
	// 맵(range) 관련
	BOOL bInvalidMapTransition = FALSE;
	BOOL bBlockUpdated = m_pCurrentFieldMapChannel->UpdateBlockPosition(Vec3BeforePosition.x, Vec3BeforePosition.z,
		m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex);
	
	if (bBlockUpdated)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 주위에 떨어져 있는 아이템 정보 보내기
		SendDropItemsAroundPosition(A2DX(pRecvMsg->PositionAVec3));
	}

	// 2006-01-23 by cmkwon
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_CHARACTER_MODE_MASK);
	if(m_character.CharacterMode)
	{
		SetBodyConditionBit(m_character.BodyCondition,	BODYCON_CHARACTER_MODE_STOP);
	}

	///////////////////////////////////////////////////////////////////////////////
	// send MSG_FC_CHARACTER_CHANGE_CHARACTER_MODE_OK
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_CHARACTER_MODE_OK, T_FC_CHARACTER_CHANGE_CHARACTER_MODE_OK, 
							pSFCChangeCharacterMode, SendBuf);
	pSFCChangeCharacterMode->ClientIndex = m_character.ClientIndex;
	pSFCChangeCharacterMode->CharacterMode0 = m_character.CharacterMode;
	pSFCChangeCharacterMode->PositionAVec3 = m_character.PositionVector;
	pSFCChangeCharacterMode->TargetAVec3 = m_character.TargetVector;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(Vec3BeforePosition, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_CHARACTER_MODE_OK)
		, GetCurrentFieldMapChannel());
	//SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(), TRUE);

	// NPC Server에 Character의 모드 변경 메세지를 전송한다.
	INIT_MSG(MSG_FN_CHARACTER_CHANGE_CHARACTER_MODE_OK, T_FN_CHARACTER_CHANGE_CHARACTER_MODE_OK, 
							pSFNCharacterChangeMode, SendBuf);
	pSFNCharacterChangeMode->ChannelIndex = m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;	
	pSFNCharacterChangeMode->ClientIndex = m_character.ClientIndex;
	pSFNCharacterChangeMode->CharacterMode0 = m_character.CharacterMode;
	
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_CHARACTER_MODE_OK));

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_FALLING_BY_FUEL_ALLIN(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-08-19 ~ 2005-08-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_FALLING_BY_FUEL_ALLIN(const char* pPacket, int nLength, int &nBytesUsed)
{
	// No Body

	m_character.CurrentEP 	= 0.0f;

	CharacterDeadRoutine(DAMAGE_BY_FUEL_ALLIN);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_WARP_BY_AGEAR_LANDING_FUEL_ALLIN(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-08-19 ~ 2005-08-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_WARP_BY_AGEAR_LANDING_FUEL_ALLIN(const char* pPacket, int nLength, int &nBytesUsed)
{
	// No Body

	ProcessSPIPenaltyOnDead(IUT_PENALTY_AGEAR_FUEL_ALLIN);

	WarpToCityMap();
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK,
		MSG_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

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

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRecvMsg->ItemUID0);
	if (NULL == pItemGeneral)
	{
		char szErrTxt[1024];
		sprintf(szErrTxt, "No such ItemUID !! ItemUID(%I64d)", pRecvMsg->ItemUID0);
		SendErrorMessage(T_FC_CHARACTER_GET_REAL_WEAPON_INFO_OK, ERR_PROTOCOL_NO_SUCH_ITEM, 0, 0, szErrTxt);
		return RES_BREAK;
	}
	this->CheckMemoryHackWeapon(pItemGeneral, pRecvMsg);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK,
		MSG_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

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

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRecvMsg->ItemUID0);
	if (NULL == pItemGeneral)
	{
		SendErrorMessage(T_FC_CHARACTER_GET_REAL_ENGINE_INFO_OK, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}
	this->CheckMemoryHackEngine(pItemGeneral, pRecvMsg);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK,
		MSG_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral, Process_FC_CHARACTER_GET_REAL_TOTAL_WEIGHT_OK()_
	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRecvMsg->ItemUID0);
	if (NULL == pItemGeneral)
	{
		return RES_BREAK;
	}
	this->CheckMemoryHackTotalWeight(pItemGeneral, pRecvMsg);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_MEMORY_HACK_USER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-21 ~ 2005-12-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_MEMORY_HACK_USER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_MEMORY_HACK_USER,
		MSG_FC_CHARACTER_MEMORY_HACK_USER, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral, Process_FC_CHARACTER_MEMORY_HACK_USER()_
	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRecvMsg->ItemUID0);
	if (NULL == pItemGeneral)
	{
		SendErrorMessage(T_FC_CHARACTER_MEMORY_HACK_USER, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	CheckMemoryHackByMemoryHackCheckTy(pItemGeneral, HACK_CHECK_TYPE_POSITION, pRecvMsg->ValidMoveDistance, pRecvMsg->CurrentMoveDistance, pRecvMsg->TickGap);	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_UPDATE_SUBLEADER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-02-14 ~ 2007-02-14
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_UPDATE_SUBLEADER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_UPDATE_SUBLEADER,
		MSG_FC_CHARACTER_UPDATE_SUBLEADER, pRecvMsg);

	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
	{// 2007-10-06 by cmkwon, 자신이 지도자인지 체크
		return RES_BREAK;
	}
	
	CFieldIOCPSocket * pPeerFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pRecvMsg->CharacterName);
	if(pPeerFISoc 
		&& pPeerFISoc->IsValidCharacter(FALSE))
	{// 2007-10-06 by cmkwon, 설정하려는 대상이 접속중인 상태라면 

		if(m_character.InfluenceType != pPeerFISoc->GetCharacter()->InfluenceType
			|| COMPARE_RACE(pPeerFISoc->m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
		{// 2007-10-06 by dhjin, 설정하는 대상이 지도자나, 부지도자면 오류를 준다.
			return RES_BREAK;
		}

		if(!COMPARE_RACE(this->m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
		{// 2008-08-21 by dhjin, 일반, 특수 계정의 부지도자 임명 제한 - 일반 권한 캐릭터 일때
			if(COMPARE_RACE(pPeerFISoc->m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
			{// 부지도자가 일반 권한 캐릭터가 아니면 에러 메시지 전송
				this->SendString128(STRING_128_USER_NOTICE, STRMSG_080821_0001);
				return RES_BREAK;
			}
		}

	}

	QPARAM_UPDATE_SUBLEADER	*qQParamUpdateSubleader =  new QPARAM_UPDATE_SUBLEADER;
	strcpy(qQParamUpdateSubleader->CharacterName, pRecvMsg->CharacterName);
	qQParamUpdateSubleader->InflType		= pRecvMsg->InflType;
	qQParamUpdateSubleader->SubLeaderRank	= pRecvMsg->SubLeaderRank;
	if(COMPARE_RACE(this->m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR|RACE_GUEST|RACE_DEMO))
	{// 2008-08-21 by dhjin, 일반, 특수 계정의 부지도자 임명 제한
		qQParamUpdateSubleader->OrderNormalRace = FALSE;
	}
	else
	{
		qQParamUpdateSubleader->OrderNormalRace = TRUE;
	}
	this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateSubleader, this, m_character.AccountUniqueNumber, qQParamUpdateSubleader);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_OBSERVER_START(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-03-27 ~ 2007-03-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_OBSERVER_START(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_OBSERVER_START,
		MSG_FC_CHARACTER_OBSERVER_START, pRecvMsg);

	if(FALSE == this->IsValidCharacter())
	{
		SendErrorMessage(T_FC_CHARACTER_OBSERVER_START, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	if(FALSE == this->IsInvisibleCharacter())
	{// 2007-03-27 by dhjin, 투명상태에서만 가능
		SendErrorMessage(T_FC_CHARACTER_OBSERVER_START, ERR_NOT_INVISIBLE_STATE);
		return RES_BREAK;
	}
	
	CFieldIOCPSocket *pTargetSocket = this->ms_pFieldIOCP->GetFieldIOCPSocket(pRecvMsg->TargetClientIndex);
	if(NULL == pTargetSocket
		|| FALSE == this->ObserverTargetCharacterCheck(pTargetSocket))
	{
		SendErrorMessage(T_FC_CHARACTER_OBSERVER_START, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}
	// 정보가 필요하다고 요청이 오면 옵저버 대상에 정보를 전송한다.

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_OTHER_INFO_OK, T_FC_CHARACTER_GET_OTHER_INFO_OK, pMsgOtherInfo, SendBuf);
	pMsgOtherInfo->CharacterInfo					= pTargetSocket->m_character;
	memcpy(pMsgOtherInfo->CharacterInfo.szCharacterMent, pTargetSocket->m_szCharacterMent, SIZE_STRING_32);
	pMsgOtherInfo->CharacterInfo.CityWarTeamType	= pTargetSocket->m_byCityWarTeamType;
	pMsgOtherInfo->CharacterRenderInfo				= pTargetSocket->m_UnitRenderInfo;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_OTHER_INFO_OK));

	// 지금 현재 상태의 옵저버 대상의 정보를 전송한다.
	INIT_MSG(MSG_FC_CHARACTER_OBSERVER_INFO, T_FC_CHARACTER_OBSERVER_INFO, pMsg, SendBuf);
	pMsg->ClientIndex	= 	pTargetSocket->m_character.ClientIndex;
	pMsg->HP			= 	pTargetSocket->m_character.HP;
	pMsg->DP			= 	pTargetSocket->m_character.DP;
	pMsg->SP			= 	pTargetSocket->m_character.SP;
	pMsg->EP			= 	pTargetSocket->m_character.EP;
	pMsg->CurrentHP		= 	pTargetSocket->m_character.CurrentHP;
	pMsg->CurrentDP		= 	pTargetSocket->m_character.CurrentDP;
	pMsg->CurrentSP		= 	pTargetSocket->m_character.CurrentSP;
	pMsg->CurrentEP		= 	pTargetSocket->m_character.CurrentEP;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_OBSERVER_INFO));

	// 옵저버 대상에게 피, 쉴드등 변화시 알려줘야 하는 옵저버를 추가한다.
	pTargetSocket->AddObserver(this);

	INIT_MSG(MSG_FC_CHARACTER_OBSERVER_START, T_FC_CHARACTER_OBSERVER_START_OK, pMsgObStartOk, SendBuf);
	pMsgObStartOk->TargetClientIndex		= pTargetSocket->m_character.ClientIndex;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_OBSERVER_START));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_OBSERVER_END(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-03-27 ~ 2007-03-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_OBSERVER_END(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_OBSERVER_END,
		MSG_FC_CHARACTER_OBSERVER_END, pRecvMsg);
	
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	// 옵저버 대상에게 피, 쉴드등 변화시 알려줘야 하는 옵저버를 삭제한다.
	CFieldIOCPSocket *pTragetSocket = this->ms_pFieldIOCP->GetFieldIOCPSocket(pRecvMsg->TargetClientIndex);
	if(NULL == pTragetSocket
		|| FALSE == pTragetSocket->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	pTragetSocket->PopObserver(this);
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_OBSERVER_END, T_FC_CHARACTER_OBSERVER_END_OK, pMsg, SendBuf);
	pMsg->TargetClientIndex		= pRecvMsg->TargetClientIndex;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_OBSERVER_END));

	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_SHOW_MAP_EFFECT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2007-04-20 ~ 2007-04-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_SHOW_MAP_EFFECT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_SHOW_MAP_EFFECT,
		MSG_FC_CHARACTER_SHOW_MAP_EFFECT, pRecvMsg);
	
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_SHOW_MAP_EFFECT_OK, T_FC_CHARACTER_SHOW_MAP_EFFECT_OK, pMapEffOK, SendBuf);
	pMapEffOK->ClientIdx		= m_character.ClientIndex;
	pMapEffOK->EffectIndex		= pRecvMsg->EffectIndex;
	pMapEffOK->avec3Up			= pRecvMsg->avec3Up;
	pMapEffOK->avec3Target		= pRecvMsg->avec3Target;
	pMapEffOK->avec3Position	= pRecvMsg->avec3Position;
	pMapEffOK->nLifetime		= pRecvMsg->nLifetime;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_SHOW_MAP_EFFECT_OK),
													GetCurrentFieldMapChannel(), FALSE, GetCurrentFieldMapChannel()->GetUserVisibleDiameterW());
	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 통합 - 아레나 서버에서 필드 서버로 게임 시작을 하기 전 클라이언트 준비 도와주기 
/// \author		dhjin
/// \date		2008-01-31 ~ 2008-01-31
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////	
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER,
		MSG_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER, pRecvMsg);
		
	if(pRecvMsg->ClientIndex != this->m_character.ClientIndex
		|| CS_ARENASERVER_PLAYING != this->GetClientState())		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - CS_ARENA_PLAYING => CS_ARENASERVER_PLAYING 변경
	{
		SendErrorMessage(T_FC_CHARACTER_READY_GAMESTART_FROM_ARENA_TO_MAINSERVER, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	this->OnCharacterReadyGameStartFromArenaToMainServer();

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		아레나 통합 - 아레나 서버에서 필드 서버로 게임 시작을 
/// \author		dhjin
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER,
		MSG_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER, pRecvMsg);
	
	if(pRecvMsg->ClientIndex != this->m_character.ClientIndex)
	{
		SendErrorMessage(T_FC_CHARACTER_GAMESTART_FROM_ARENA_TO_MAINSERVER, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	this->OnCharacterGameStartFromArenaToMainServer();

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_USER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 유저정보옵션 - 다른 유저 정보 요청
/// \author		dhjin
/// \date		2008-06-23 ~ 2008-06-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_USER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_USER_INFO,
		MSG_FC_CHARACTER_GET_USER_INFO, pRecvMsg);
	
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	
	CFieldIOCPSocket * TargetCFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRecvMsg->TargetCharcterUID);
	if(NULL == TargetCFISoc
		|| FALSE == TargetCFISoc->IsValidCharacter(FALSE))	// 2009-02-24 by cmkwon, 체크 추가
	{
		this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetUserInfo, this, m_character.AccountUniqueNumber, NULL, NULL, pRecvMsg->TargetCharcterUID);		
	}
	else
	{
		SUSER_INFO_OPTION	UserInfoOption;
		MEMSET_ZERO(&UserInfoOption,sizeof(SUSER_INFO_OPTION));
		STRNCPY_MEMSET(UserInfoOption.CharacterName, TargetCFISoc->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		UserInfoOption.GuildUID			= TargetCFISoc->m_character.GuildUniqueNumber;
		STRNCPY_MEMSET(UserInfoOption.GuildName, TargetCFISoc->m_character.GuildName, SIZE_MAX_GUILD_NAME);
		UserInfoOption.LastStartedTime	= TargetCFISoc->m_character.LastStartedTime;
		UserInfoOption.Level			= TargetCFISoc->m_character.Level;
		UserInfoOption.MapChannelIndex	= TargetCFISoc->m_character.MapChannelIndex;
		UserInfoOption.PilotFace		= TargetCFISoc->m_character.PilotFace;
		UserInfoOption.Propensity		= TargetCFISoc->m_character.Propensity;
		UserInfoOption.UnitKind			= TargetCFISoc->m_character.UnitKind;
		UserInfoOption.SecretInfoOption	= TargetCFISoc->m_character.SecretInfoOption;
		STRNCPY_MEMSET(UserInfoOption.NickName, TargetCFISoc->m_character.NickName, SIZE_MAX_CHARACTER_NAME);	// 2009-02-12 by cmkwon, EP3-3 월드랭킹시스템 구현 - 
		this->SendUserInfoBySecretOption(&UserInfoOption);
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		EP3 유저정보옵션 - 유저정보옵션 변경
/// \author		dhjin
/// \date		2008-06-23 ~ 2008-06-23
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET,
		MSG_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET, pRecvMsg);
	
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}
	// 2012-10-17 by jhseol, 아템 미리보기 무조건 ON 시키기
#ifdef SC_ITEM_VIEW_UNCONDITIONAL_ON_JHSEOL
	pRecvMsg->SecretInfoOption = pRecvMsg->SecretInfoOption & USER_INFO_OPTION_ITEMINFO_DELETE_ALL_MASK;
#endif
	// end 2012-10-17 by jhseol, 아템 미리보기 무조건 ON 시키기
	
	this->m_character.SecretInfoOption	= pRecvMsg->SecretInfoOption;

	this->SendAddMessageType(T_FC_CHARACTER_CHANGE_INFO_OPTION_SECRET_OK);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_NICKNAME(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_CHARACTER_CHANGE_NICKNAME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_CHANGE_NICKNAME,
		MSG_FC_CHARACTER_CHANGE_NICKNAME, pRecvMsg);
	
	if(FALSE == this->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_CHARACTER_CHANGE_NICKNAME, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(0 < strlen(m_character.NickName))
	{
		SendErrorMessage(T_FC_CHARACTER_CHANGE_NICKNAME, ERR_ALREADY_REG, 0, 0, m_character.NickName);
		return RES_BREAK;
	}

	if(m_character.CharacterUniqueNumber != pRecvMsg->CharacUID)
	{
		SendErrorMessage(T_FC_CHARACTER_CHANGE_NICKNAME, ERR_DB_INVALID_PARAMETER, m_character.CharacterUniqueNumber, pRecvMsg->CharacUID);
		return RES_BREAK;
	}

	if(FALSE == CAtumSJ::IsValidNickName(pRecvMsg->NickName))
	{
		SendErrorMessage(T_FC_CHARACTER_CHANGE_NICKNAME, ERR_PROTOCOL_INVALID_CHARACTER_NAME, strlen(pRecvMsg->NickName), 0, pRecvMsg->NickName);
		return RES_BREAK;
	}

	if(FALSE == g_pFieldGlobal->CheckProhibitedName(pRecvMsg->NickName))
	{// 2009-03-10 by cmkwon, 체크 추가함.
		SendErrorMessage(T_FC_CHARACTER_CHANGE_NICKNAME, ERR_PROTOCOL_INVALID_CHARACTER_NAME, 0, 100, pRecvMsg->NickName);
		return RES_BREAK;
	}

	MSG_FC_CHARACTER_CHANGE_NICKNAME *pQParam = new MSG_FC_CHARACTER_CHANGE_NICKNAME;
	*pQParam	= *pRecvMsg;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateNickName, this, m_character.AccountUniqueNumber, pQParam);
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX# 추가
/// \author		cmkwon
/// \date		2009-10-13 ~ 2009-10-13
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX,
		MSG_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX, pRecvMsg);

	if(FALSE == this->IsUsing())
	{
		return RES_BREAK;
	}

	mt_auto_lock ccLock(&m_mtvectCharacterCache);
	CHARACTER *pCharac = this->GetCharacterCacheNoLock(pRecvMsg->CharacUID);
	if(NULL == pCharac)
	{
		ccLock.auto_unlock_cancel();
		SendErrorMessage(T_FC_CHARACTER_CHANGE_START_CITY_MAPINDEX, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		Close(0x14016);
		return RES_RETURN_FALSE;
	}			
	pCharac->Material = pRecvMsg->nStartCityMapIdx;
	ccLock.auto_unlock_cancel();

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeStartCityMapIndex, this, m_character.AccountUniqueNumber, NULL, NULL, pRecvMsg->CharacUID, pRecvMsg->nStartCityMapIdx);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_DEBUFF_DOT_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		인피니티 - Debuff, Dot 정보 요청 - F -> C
/// \author		dhjin
/// \date		2009-09-09 ~ 2010
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_DEBUFF_DOT_INFO(const char* pPacket, int nLength, int &nBytesUsed) {
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_DEBUFF_DOT_INFO,
		MSG_FC_CHARACTER_DEBUFF_DOT_INFO, pRecvMsg);

	CFieldIOCPSocket * TargetCFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRecvMsg->CharacterUID);
	if(NULL == TargetCFISoc
		|| FALSE == TargetCFISoc->IsValidCharacter(FALSE)) {
		SendErrorMessage(T_FC_CHARACTER_DEBUFF_DOT_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;		
	}		

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK, T_FC_CHARACTER_DEBUFF_DOT_INFO_OK, pSendMsg, SendBuf);
	pSendMsg->CharacterUID		= pRecvMsg->CharacterUID;
	pSendMsg->DebuffCount		= TargetCFISoc->m_SkillManager.m_FieldDebuff.MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK((MSG_DEBUFF_INFO*)(SendBuf+MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK)));
	pSendMsg->DotCount			= TargetCFISoc->m_SkillManager.m_FieldDot.MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK((MSG_DOT_INFO*)(SendBuf+MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK)));
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_DEBUFF_DOT_INFO_OK) + ( pSendMsg->DebuffCount*sizeof(MSG_DEBUFF_INFO) ) + ( pSendMsg->DotCount*sizeof(MSG_DOT_INFO) ) );

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult Process_FC_CHARACTER_GET_USER_ITEM_INFO(const char* pPacket, int nLength, int &nBytesUsed);
/// \brief		아템미리보기 - 살펴볼 케릭터 UID
/// \author		jhseol
/// \date		2012-06-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
// 2012-06-05 by jhseol, 아템미리보기 - 살펴볼 케릭터 아이템 정보 로딩
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_USER_ITEM_INFO(const char* pPacket, int nLength, int &nBytesUsed) {

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_USER_ITEM_INFO,
		MSG_FC_CHARACTER_GET_USER_ITEM_INFO, pRecvMsg);

#ifdef SC_ENEMY_INFO_JHSEOL_ISSHIN	// 2012-07-19 by jhseol, 아템미리보기
	
	CFieldIOCPSocket * TargetCFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRecvMsg->TargetCharcterUID);
	if(NULL == TargetCFISoc
		|| FALSE == TargetCFISoc->IsValidCharacter(FALSE)) {
		SendErrorMessage(T_FC_CHARACTER_GET_USER_ITEM_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;		
	}

	mt_auto_lock igLock(&(TargetCFISoc->m_ItemManager.m_mapItemGeneral));			// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
	
	//int nItemCnt		= m_ItemManager.m_mapItemGeneral.size();		// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
	int nTotalSend		= 0;
	int nSendCnt		= 0;
	//int dsgsgsdgsdg		= sizeof(MSG_FC_ENEMY_ITEM_INFO);			// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
	
	INIT_MSG_WITH_BUFFER(MSG_FC_ENEMY_ITEM_INFO, T_FC_CHARACTER_GET_USER_ITEM_INFO_OK, pSInsertItem, SendBuf);
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_USER_ITEM_INFO_OK_DONE, T_FC_CHARACTER_GET_USER_ITEM_INFO_OK_DONE, pSPutItemDone, SendBuf2);
	int EnchantCount = 0;
	mtmapUID2ItemGeneral::iterator itr = TargetCFISoc->m_ItemManager.m_mapItemGeneral.begin();
	for(; TargetCFISoc->m_ItemManager.m_mapItemGeneral.end() != itr; itr++)
	{
		ITEM_GENERAL *pItemG = itr->second;
		if(NULL == pItemG)
		{
			break;
		}
		if(WEAR_ATTACHED == pItemG->Wear)
		{
			if(POS_PROW <= pItemG->ItemInfo->Position || POS_PET >= pItemG->ItemInfo->Position)
			{
				pSInsertItem->FromCharacterUniqueNumber		= TargetCFISoc->m_character.CharacterUniqueNumber;
				pSInsertItem->ItemInsertionType				= IUT_GENERAL;
				pSInsertItem->ItemGeneral					= *pItemG;
				nSendCnt++;
				nTotalSend++;
				
				if(		POS_PROWOUT == pItemG->ItemInfo->Position
					||	POS_WINGOUT == pItemG->ItemInfo->Position
					||	POS_CENTER == pItemG->ItemInfo->Position
					||	POS_PROW == pItemG->ItemInfo->Position
					||	POS_REAR == pItemG->ItemInfo->Position
					||	POS_ACCESSORY_UNLIMITED == pItemG->ItemInfo->Position)
				{
					mt_auto_lock mtA(&TargetCFISoc->m_mapEnchant);		// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
					mtmapUID2EnchantVector::iterator itrEnchantList = TargetCFISoc->m_mapEnchant.find(pItemG->UniqueNumber);
					if (itrEnchantList != TargetCFISoc->m_mapEnchant.end())		// 2012-09-20 by jhseol, MAP 오토락 서버 다운 버그 수정
					{
						int EnchantCardIndex = 0;
						int EnchantCardType = 8;	//인첸트 카드 종류
						vectENCHANT &vecECH = itrEnchantList->second;
						vectENCHANT::iterator tempEnchant = vecECH.begin();
						for( ; tempEnchant != vecECH.end(); tempEnchant++ )
						{
							int itrEnchant = 0;
							for( itrEnchant = 0; itrEnchant < EnchantCardType; itrEnchant++ )
							{
								// 2013-01-24 by jhseol, 아템미리보기 패킷 사이즈 초과로 인한 버그 수정
								if( pSPutItemDone->ItemEnchant[EnchantCount][itrEnchant].TargetItemUniqueNumber	== tempEnchant->TargetItemUniqueNumber
								&&	pSPutItemDone->ItemEnchant[EnchantCount][itrEnchant].TargetItemNum			== tempEnchant->TargetItemNum
								&&	pSPutItemDone->ItemEnchant[EnchantCount][itrEnchant].EnchantItemNum			== tempEnchant->EnchantItemNum )
								// end 2013-01-24 by jhseol, 아템미리보기 패킷 사이즈 초과로 인한 버그 수정
 								{
									pSPutItemDone->ItemEnchant[EnchantCount][itrEnchant].EnchantCount++;
									break;
								}
							}
							if( EnchantCardType <= itrEnchant )
							{
								// 2013-01-24 by jhseol, 아템미리보기 패킷 사이즈 초과로 인한 버그 수정
								pSPutItemDone->ItemEnchant[EnchantCount][EnchantCardIndex].TargetItemUniqueNumber	= tempEnchant->TargetItemUniqueNumber;
								pSPutItemDone->ItemEnchant[EnchantCount][EnchantCardIndex].TargetItemNum			= tempEnchant->TargetItemNum;
								pSPutItemDone->ItemEnchant[EnchantCount][EnchantCardIndex].EnchantItemNum			= tempEnchant->EnchantItemNum;
								// end 2013-01-24 by jhseol, 아템미리보기 패킷 사이즈 초과로 인한 버그 수정
								pSPutItemDone->ItemEnchant[EnchantCount][EnchantCardIndex].EnchantCount++;
								EnchantCardIndex++;
							}
						}
						EnchantCount++;
					}
				}
				
				if((nSendCnt+1)*MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO) > SIZE_MAX_PACKET)
				{
					this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO));
					nSendCnt		= 0;
					MEMSET_ZERO(SendBuf, SIZE_MAX_PACKET);
					*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO)) ) = T_FC_CHARACTER_GET_USER_ITEM_INFO_OK;
					pSInsertItem	= (MSG_FC_ENEMY_ITEM_INFO*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO) + SIZE_FIELD_TYPE_HEADER);
				}
				else
				{
					*( (MessageType_t*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO)) ) = T_FC_CHARACTER_GET_USER_ITEM_INFO_OK;
					pSInsertItem	= (MSG_FC_ENEMY_ITEM_INFO*)(SendBuf + nSendCnt*MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO) + SIZE_FIELD_TYPE_HEADER);
				}
			}
		}
	}
	
	if(0 < nSendCnt)
	{
		this->SendAddData(SendBuf, nSendCnt * MSG_SIZE(MSG_FC_ENEMY_ITEM_INFO));
		nSendCnt		= 0;
	}
	
	this->SendAddData(SendBuf2, MSG_SIZE(MSG_FC_CHARACTER_GET_USER_ITEM_INFO_OK_DONE));
#endif	//#ifdef SC_ENEMY_INFO_JHSEOL_ISSHIN	// 2012-07-19 by jhseol, 아템미리보기

	return RES_RETURN_TRUE;
}
// end 2012-06-05 by jhseol, 아템미리보기 - 살펴볼 케릭터 아이템 정보 로딩

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult Process_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET(const char* pPacket, int nLength, int &nBytesUsed);
/// \brief		아템미리보기 On / Off 기능 - 공개 여부
/// \author		jhseol
/// \date		2012-07-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
// 2012-07-12 by jhseol, 아템미리보기 On / Off 기능 - 공개 여부
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET(const char* pPacket, int nLength, int &nBytesUsed) {

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET,
		MSG_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET, pRecvMsg);
	
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET_OK, T_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET_OK, pSendMsg, SendBuf);

#ifdef SC_ENEMY_INFO_JHSEOL_ISSHIN	// 2012-07-19 by jhseol, 아템미리보기
	CFieldIOCPSocket * TargetCFISoc = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRecvMsg->TargetCharcterUID);
	if(NULL == TargetCFISoc
		|| FALSE == TargetCFISoc->IsValidCharacter(FALSE)) {
		SendErrorMessage(T_FC_CHARACTER_GET_USER_ITEM_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;		
	}
	if( (!strcmp(this->m_character.GuildName, TargetCFISoc->m_character.GuildName)) && this->m_character.GuildUniqueNumber != NULL && TargetCFISoc->m_character.GuildUniqueNumber != NULL )		// 여단공개 관련버그 수정
	{
		if(ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(this->m_character.CharacterUniqueNumber))
		{
			pSendMsg->bItemInfoSecret = TRUE;
		}
		else
		{
			if( 0 == (USER_INFO_OPTION_SECRET_GUILD_ITEMINFO & TargetCFISoc->m_character.SecretInfoOption) )
			{
				pSendMsg->bItemInfoSecret = TRUE;
			}
		}
	}
	else
	{
		if( 0 == (USER_INFO_OPTION_SECRET_ITEMINFO & TargetCFISoc->m_character.SecretInfoOption) )
		{
			pSendMsg->bItemInfoSecret = TRUE;
		}
	}
#endif	//#ifdef SC_ENEMY_INFO_JHSEOL_ISSHIN	// 2012-07-19 by jhseol, 아템미리보기

	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_GET_USER_ITEM_INFO_SECRET_OK));
	
	return RES_RETURN_TRUE;
}
// end 2012-07-12 by jhseol, 아템미리보기 On / Off 기능 - 공개 여부

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_WARP_SAME_MAP_DONE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK);
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_SELECTCHANNEL_MASK);		// 2006-06-15 by cmkwon
#ifdef _DEBUG
	//m_pCurrentFieldMapChannel->printMap();
#endif
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "  Warp  DONE(SAME MAP) : %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);

	// 워프 완료 처리 루틴
	OnWarpDone(WT_SAME_MAP);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_WARP_SAME_FIELD_SERVER_DONE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int			nRecvTypeSize = 0;

	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK);
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_SELECTCHANNEL_MASK);		// 2006-06-15 by cmkwon
	//DBGOUT("ClearBodyConditionBit: SAME_FIELD_SERVER_DONE\n");

	CFieldMapChannel *pOldCurFMapChann = GetCurrentFieldMapChannel();
	if(NULL == pOldCurFMapChann)
	{// 2008-06-20 by cmkwon, 체크 추가
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Error] CurrentMapChannel Error !! %s\n", GetCharacterString(GetCharacter(), string()));
		return RES_RETURN_FALSE;	// 2008-06-20 by cmkwon, 소켓 종료
	}

	MapIndex_t nOldMapIndex = pOldCurFMapChann->GetMapChannelIndex().MapIndex;	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 

	//////////////////////////////////////////////////////////////////////////
	// 2007-06-04 by dhjin, 아레나 맵인지 체크 변수
	BOOL CheckDeleteArenaItem = FALSE;
	CheckDeleteArenaItem = IS_MAP_INFLUENCE_ARENA(pOldCurFMapChann->GetMapInfluenceTypeW());

	// 맵 관리를 위해서 추가, added by ywlee, 20021029
	SetCurrentFieldMapChannel(GetFieldMapChannel(&m_character.MapChannelIndex, TRUE, FALSE));
	if (m_pCurrentFieldMapChannel == NULL)
	{
		// ERROR! All Channel Unavailable
		DBGOUT("[%d] All Channel Unavailable: [%04d]\n", m_character.ClientIndex, m_character.MapChannelIndex.MapIndex);
		Close(0x1412);
		return RES_RETURN_FALSE;
	}

	// 이동 불가 지역인 경우 map의 default position으로 이동, 도시는 체크하지 않는다
	if (0.0f == D3DXVec3Length(&m_character.PositionVector)
		|| FALSE == m_pCurrentFieldMapChannel->m_pFieldMapProject->CheckCharacterPosition(&m_character.PositionVector, TRUE)
		)
	{
		m_character.PositionVector = m_pCurrentFieldMapChannel->GetDefaultPointW();
	}

	// NPC Server에게 T_FN_CLIENT_GAMESTART_OK를 보낸다
	// 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			= this->GetStealthState();		// 2013-05-09 by hskim, 세력 포인트 개선
	pSendClientGameStartOK->bInvisible				= this->m_UnitRenderInfo.RI_Invisible;		// 2006-11-27 by dhjin
	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CLIENT_GAMESTART_OK));

	///////////////////////////////////////////////////////////////////////////
	// 맵 Block에 추가한다.
	if(FALSE == m_pCurrentFieldMapChannel->SetInitialPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
	{
		char szTemp[256];
		sprintf(szTemp, "[Error] SetInitialPosition_1 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 [트리거 시스템] - 화산재 / 모래 폭풍

	// 주위에 있는 아이템의 정보를 얻어온다.
	SendDropItemsAroundPosition(m_character.PositionVector);

	// Speed Hack 변수를 초기화 한다.
	for(int i=0 ; i < ARRAYSIZE_SPEED_HACK_DATA; i++)
	{
		m_arrSpeedHackCheck[i].ResetSPEED_HACK_DATA();
	}
	
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그
	char szSystemLog[1024];
	sprintf(szSystemLog, "  Warp  DONE(SAME Field Server) : %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);

#ifdef _DEBUG
	//m_pCurrentFieldMapChannel->printMap();
#endif

	// 파티원의 정보를 업데이트함
	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pFParty)
	{
		pFParty->UpdateMemberInfoAllInMap(this, m_pCurrentFieldMapChannel);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 아레나 맵, 자신의 세력에서의 워프시에는 백맵 관련 체크 필요 없다.
	if(FALSE == CheckDeleteArenaItem
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_EVENT_WARP_SAME_FIELD_SERVER_DONE#, 처리
//		&& FALSE == IS_SAME_CHARACTER_8_MAP_INFLUENCE(this->GetCharacter()->InfluenceType, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_nMapInfluenceType))
		&& FALSE == CAtumSJ::IsSameCharacterInfluence8MapInfluence(m_character.InfluenceType, m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()) )	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
	{
		if(nOldMapIndex == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_nBeforeMapIndex
			|| nOldMapIndex == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_nBeforeMapIndex2)
		{// 2008-06-20 by cmkwon, 이전맵이 현재맵의 백맵과 같이 것이 있는지 체크
			
			this->UpdateBackMapIndex(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex, nOldMapIndex);
		}
	}

	// 워프 완료 처리 루틴
	OnWarpDone(WT_DIFF_MAP_SAME_SERVER);

	//////////////////////////////////////////////////////////////////////////
	// 2007-06-04 by dhjin, 아레나 전용 아이템 처리
	if(CheckDeleteArenaItem)
	{
		m_ItemManager.DeleteAllArenaItem();
	}

	// 일시 정지된 타이머 재가동
	m_TimerManager.ContinueAllTimerEvents();

	// 2015-01-27 by shchoi 워프 시 일시 무적
#ifdef S_WARP_INVINCIBLE_SHCHOI
	char strlog[256];
 	sprintf(strlog,"[CUID : %7d, AUID : %7d, Map : %4d] Portal : Invinicible Start\n",m_character.CharacterUniqueNumber,m_character.AccountUniqueNumber,m_character.MapChannelIndex.MapIndex);
// 	this->SendString128(STRING_128_USER_NOTICE, "무적 시작 : 포탈");
	g_pFieldGlobal->WriteSystemLogEX(TRUE,strlog);
	CParamFactor *pParamFactor = this->GetParamFactor();
	pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible = TRUE;
	m_InvincibleTime = timeGetTime()+m_defaultaddInvTime;
	m_bPortalInvincible = TRUE;
#endif
	// end 2015-01-27 by shchoi 워프 시 일시 무적

	// IM Server에 전송
	INIT_MSG(MSG_FI_CHARACTER_UPDATE_MAP_CHANNEL, T_FI_CHARACTER_UPDATE_MAP_CHANNEL, pUpdateMap, SendBuf);
	pUpdateMap->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
	pUpdateMap->MapChannel = m_character.MapChannelIndex;
	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CHARACTER_UPDATE_MAP_CHANNEL));

	///////////////////////////////////////////////////////////////////////////////
	// 2005-11-14 by cmkwon, 보급 상점 띄우기 체크
	if(FALSE == m_character.CharacterMode
		|| IS_BAZAAR_MAP_INDEX(pOldCurFMapChann->GetMapChannelIndex().MapIndex))
	{// 2006-07-20 by cmkwon, 캐릭터모드가 아니거나 소스맵이 바자맵이면 보급상점을 뛰우지 않는다
		return RES_BREAK;
	}

	if(IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex)
		|| IS_BAZAAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{// 2006-07-20 by cmkwon, P2P PK 중이거나 바자맵일경우 상점 못 들어 감
		return RES_BREAK;
	}

	// Enter Building Event 등 처리
	EVENTINFO *pEventInfo = m_pCurrentFieldMapChannel->GetTileEventInfoW(&m_character.PositionVector);
	if ( NULL == pEventInfo
		|| pEventInfo->m_bEventType != EVENT_TYPE_ENTER_BUILDING)
	{
		return RES_BREAK;
	}

// 2006-07-20 by cmkwon, 필요 없는 부분인것 같음 
// 		// building에서 나왔을 때 target vector 결정
// 		D3DXVec3Normalize(&m_character.TargetVector, &-m_character.TargetVector);
// 
// 		// building에서 나왔을 때 position vector 결정
// 		D3DXVECTOR3 vTmp = m_character.PositionVector + (40 * m_character.TargetVector);
// 		m_pCurrentFieldMapChannel->UpdateBlockPosition(m_character.PositionVector, vTmp, m_character.ClientIndex);
// 		m_character.PositionVector = vTmp;

	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pEventInfo->m_EventwParam1);
	if(NULL == pBuildingNPC)
	{
		return RES_BREAK;
	}

	INIT_MSG(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, SendBuf);
	pMsgEnterBuilding->BuildingNPCInfo				= *pBuildingNPC;
// 2006-02-08 by cmkwon
//			pMsgEnterBuilding->fCityWarTexRate				= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pBuildingNPC->BuildingIndex, m_character.GuildUniqueNumber);
	pMsgEnterBuilding->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_DEAD_GAMESTART(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize	= 0;
	MSG_FC_CHARACTER_DEAD_GAMESTART	*pRecvDeadGameStart	= NULL;

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

	if (CS_PLAYING != GetClientState())
	{
		// Protocol Error 처리
		// - 유효하지 않은 Game Start 메세지
		// Error Code : ERR_PROTOCOL_INVALID_GAMESTART
		char szSystemLog[256];
		sprintf(szSystemLog, STRERR_S_F2NOTIFY_0001, GetClientState());
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);

		SendErrorMessage(T_FC_CHARACTER_DEAD_GAMESTART, ERR_PROTOCOL_INVALID_GAMESTART, (int)GetClientState());
		return RES_BREAK;
	}

	if (m_character.ClientIndex == 0 || m_character.ClientIndex != pRecvDeadGameStart->ClientIndex)
	{
		// Protocol Error 처리
		// - 접속한 client index와 요청한 client index이 다르다
		// Error Code : ERR_PROTOCOL_INVALID_CLIENTINDEX
		SendErrorMessage(T_FC_CHARACTER_DEAD_GAMESTART, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	if(FALSE == this->IsValidCharacter(FALSE))
	{// 2007-09-28 by cmkwon, 체크 추가함
		SendErrorMessage(T_FC_CHARACTER_DEAD_GAMESTART, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2011-06-27 by shcho, 아르헨티나 좀비모드 수정 
	if(m_character.CurrentHP >=0)
	{ // HP가 0일경우 죽은것으로 간주한다.
		DbgOut("!!!!!!!!!HP ZERO!!!!!!!!!: %s %#08x%08x \r\n", GetCharacterString(GetCharacter(), string()), HIDWORD(m_character.BodyCondition), LODWORD(m_character.BodyCondition));
		SetBodyConditionBit(m_character.BodyCondition, BODYCON_DEAD_MASK);
	}
	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK) == FALSE) // 추가 HP가 0이상이고 데드가 아닐경우
	// END 2011-06-27 by shcho, 아르헨티나 좀비모드 수정 
	{
		SendErrorMessage(T_FC_CHARACTER_DEAD_GAMESTART, ERR_PROTOCOL_INVALID_GAMESTART);
		return RES_BREAK;
	}

	// 파티전이 끝나지 않았으면 워프 불가
	if (this->IsPartyBattleState())
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0026);
		SendErrorMessage(T_FC_CHARACTER_DEAD_GAMESTART, ERR_PROTOCOL_DOING_PARTY_BATTLE);
		return RES_BREAK;
	}

	// 2015-01-27 by shchoi 워프 시 일시 무적 
#ifdef S_WARP_INVINCIBLE_SHCHOI
	char strlog[256];
	sprintf(strlog,"[CUID : %7d, AUID : %7d, Map : %4d] Revive : Invinicible Start\n",m_character.CharacterUniqueNumber,m_character.AccountUniqueNumber,m_character.MapChannelIndex.MapIndex);
//	this->SendString128(STRING_128_USER_NOTICE, "무적 시작 : 사망 부활");
	g_pFieldGlobal->WriteSystemLogEX(TRUE,strlog);
	CParamFactor *pParamFactor = this->GetParamFactor();
	pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible = TRUE;
	m_InvincibleTime = timeGetTime()+m_defaultaddInvTime;
	m_bPortalInvincible = TRUE;
#endif
	// end 2015-01-27 by shchoi 워프 시 일시 무적

	// 2007-09-16 by dhjin, 밑 부분 이쪽으로 이동
	CFieldMapProject *pFMPro = this->GetCurrentFieldMapProject();
	if(NULL == pFMPro)
	{
		return RES_RETURN_TRUE;
	}
	int nMapInfluenceTy = pFMPro->GetMapInfluenceType();
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-05-11 by dhjin, 아레나 맵에서 사망 후 부활시는 만피 시켜준다.
	if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		this->CharacterDeadGameStartRoutine(TRUE, m_character.HP, m_character.DP, m_character.SP, m_character.EP);
		this->m_bDeadReasonByPK		= FALSE;
		// 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
#ifdef SC_ARENA_EX_1ST_JHSEOL_MSPARK
		m_bArenaNoDamage = TRUE;
		m_atimeArenaNoDamage.SetCurrentDateTime(FALSE);
		SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0107);
#endif
		// end 2012-06-14 by jhseol, 아레나 추가개발part2 - 무적 : 아레나 리스폰 후 무적 시간
	}
	else
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-05 by cmkwon, 캐릭터가 죽은 후 재시작시 도시맵 or 현재맵 부활 선택가능
		if(pRecvDeadGameStart->bRebirthInCityMap
			|| this->IsCityCurrentFieldMapChannel()
			|| IS_OUTPOST_CITY_MAP_INDEX(pFMPro->m_nMapIndex)	// 2007-09-28 by cmkwon, 전진기지도시맵일 경우도 세력도시맵으로 이동
			|| 0 >= this->GetCharacter()->CurrentEP)			// 2005-12-06 by cmkwon, 연료가 0일때는 무조건 도시맵으로 이동
		{
			// 2007-10-05 by cmkwon, 연료가 0일때 죽은것인지 체크 후에 아래 사항 처리가 필요함
			this->CharacterDeadGameStartRoutine(TRUE, m_character.HP, m_character.DP);
			this->m_bDeadReasonByPK		= FALSE;
			WarpToCityMap();	// 도시맵으로
			
			// 2007-09-28 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
			char szSystemLog[1024];
			sprintf(szSystemLog, "[Notify] WarpToMap(300) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
			g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
			return RES_RETURN_TRUE;
		}
		
		this->CharacterDeadGameStartRoutine(TRUE, m_character.HP, m_character.DP);
		this->m_bDeadReasonByPK		= FALSE;

		if(IS_MAP_INFLUENCE_OUTPOST(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{// 2007-09-15 by dhjin, 전진기지맵(전진기지도시맵제외)에서 사망시 조건에 맞게 워프
			MAP_CHANNEL_INDEX	warpMapChannelIdx(pFMPro->m_nMapIndex, 0);

			if(ms_pFieldIOCP->m_OutPostManager.CheckValidGuildUID(pFMPro->m_nMapIndex, m_character.GuildUniqueNumber))
			{// 2007-09-15 by dhjin, 전진기지 소유 여단이면 전진기지 도시 맵 나오는 곳에서 부활한다.

				int	nTeleportWarpObjectIndex	= this->GetCurrentFieldMapChannel()->GetTeleportWarpObjectIndexW();
				WarpToMap(warpMapChannelIdx, nTeleportWarpObjectIndex);
			
				// 2007-09-28 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
				char szSystemLog[1024];
				sprintf(szSystemLog, "[Notify] WarpToMap(301) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
				g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
				return RES_RETURN_TRUE;			// 2007-09-28 by cmkwon, 빠진것 같음 대호씨에게 확인 해야함
			}
			
			// 2007-09-15 by dhjin, 전진기지 소유 여단이 아니면 세력 별 소환 위치에서 소환한다.
			// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 아래와 같이 GetBackMapIndex() 를 호출하여 처리
			//CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pFMPro->m_nBeforeMapIndex);
			MapIndex_t	nBackMapIndex		= this->GetBackMapIndex(pFMPro);
			CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nBackMapIndex);	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 
			if(pBackMapFMPro)
			{
				warpMapChannelIdx.MapIndex		= nBackMapIndex;	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 
				warpMapChannelIdx.ChannelIndex	= 0;
				int nWarpObjectIndex			= pBackMapFMPro->GetWarpObjectIndex(m_character.InfluenceType);
				if(0 == nWarpObjectIndex)
				{// 2006-12-08 by cmkwon, 세력별 WarpObjectIndex가 설정되어 있지 않다
					nWarpObjectIndex			= pBackMapFMPro->GetRandomWarpTargetEventIndex();
				}
				WarpToMap(warpMapChannelIdx, nWarpObjectIndex);

				// 2007-09-28 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
				char szSystemLog[1024];
				sprintf(szSystemLog, "[Notify] WarpToMap(302) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
				g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
				return RES_RETURN_TRUE;		// 2007-09-28 by cmkwon, 빠진것 같음 대호씨에게 확인 해야함
			}
		}
		else if(ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(m_character.InfluenceType)
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_DEAD_GAMESTART#, 아래와 같이 수정 
//				&& IS_OTHER_INFLUENCE_MAP(m_character.InfluenceType, nMapInfluenceTy))
				&& CAtumSJ::IsOtherInfluenceMap(m_character.InfluenceType, m_character.GetStartCityMapIndex(), nMapInfluenceTy))	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
		{// 2007-09-16 by dhjin, 세력전이 진행중인지 체크, 상대세력 맵에서 사망시

			MapIndex_t TelePortMapIndex =  ms_pFieldIOCP->m_InflWarManager.GetTeleportMapIndex(m_character.InfluenceType);
			if(0 >= TelePortMapIndex)
			{// 2007-09-16 by dhjin, 설치된 텔레포트가 없으면 마을로
				
				WarpToCityMap();

				// 2007-09-28 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
				char szSystemLog[1024];
				sprintf(szSystemLog, "[Notify] WarpToMap(303) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
				g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
				return RES_RETURN_TRUE;
			}

			MAP_CHANNEL_INDEX	warpMapChannelIdx(TelePortMapIndex, 0);
			int	nTeleportWarpObjectIndex	= ms_pFieldIOCP->GetFieldMapProjectByMapIndex(TelePortMapIndex)->GetTeleportWarpObjectIndex();
			WarpToMap(warpMapChannelIdx, nTeleportWarpObjectIndex);
			return RES_RETURN_TRUE;
		}
		// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
		else if( TRUE == IS_MAP_INFLUENCE_HELL(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()) )
		{
			MAP_CHANNEL_INDEX	warpMapChannelIdx(pFMPro->m_nMapIndex, 0);
			MapIndex_t	nBackMapIndex = this->GetBackMapIndex(pFMPro);
			CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nBackMapIndex);
			if(pBackMapFMPro)
			{
				warpMapChannelIdx.MapIndex		= nBackMapIndex;
				warpMapChannelIdx.ChannelIndex	= 0;
				int nWarpObjectIndex			= pBackMapFMPro->GetWarpObjectIndex(m_character.InfluenceType);
				if(0 == nWarpObjectIndex)
				{
					nWarpObjectIndex			= pBackMapFMPro->GetRandomWarpTargetEventIndex();
				}
				WarpToMap(warpMapChannelIdx, nWarpObjectIndex);

				char szSystemLog[1024];
				sprintf(szSystemLog, "[Notify] MapInfluenceType(Hell) WarpToMap (302) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
				g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
				return RES_RETURN_TRUE;
			}
		}
		// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	}

	// 2007-09-28 by cmkwon, 소스 위치 이동 - 아래에 있던 소스를 이동
	if(IsGoToInfluenceCity(GetCharacter()->InfluenceType, nMapInfluenceTy))
	{
		WarpToCityMap();	// 도시맵으로

		// 2007-09-28 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
		char szSystemLog[1024];
		sprintf(szSystemLog, "[Notify] WarpToMap(304) : %s Map(%4d)	Position(%5d, %5d, %5d)\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);
		g_pFieldGlobal->WriteSystemLogEX(FALSE, szSystemLog);
		return RES_RETURN_TRUE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-28 by cmkwon, 소스 위치 이동 - 아래에 있던 소스를 이동
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-08 by cmkwon, 각 세력별 부활 워프게이트가 따로 설정된다.
	MAP_CHANNEL_INDEX	warpMapChannelIdx	= this->GetCurrentFieldMapChannel()->GetMapChannelIndex();
	int					nWarpObjectIndex	= this->GetCurrentFieldMapChannel()->GetWarpObjectIndexW(m_character.InfluenceType);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-02 by cmkwon, 상대 세력 맵일경우 이전맵에서 부활됨
	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 
	//if(0 != pFMPro->m_nBeforeMapIndex
	if(pFMPro->IsValidBeforeMapIndex()												// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - IsValidBeforeMapIndex() 로 체크
// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_DEAD_GAMESTART#, 아래와 같이 수정
//		&& IS_OTHER_INFLUENCE_MAP(m_character.InfluenceType, nMapInfluenceTy)
		&& CAtumSJ::IsOtherInfluenceMap(m_character.InfluenceType, m_character.GetStartCityMapIndex(), nMapInfluenceTy)		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - 
		&& FALSE == m_pCurrentFieldMapChannel->IsOccupyStrategyPointMonster())		// 2006-11-21 by cmkwon, 전략포인트 몬스터 관련 체크
	{
		// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 아래와 같이 GetBackMapIndex() 를 호출하여 처리
		//CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pFMPro->m_nBeforeMapIndex);
		MapIndex_t nBackMapIndex		= this->GetBackMapIndex(pFMPro);
		CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(nBackMapIndex);	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 
		if(pBackMapFMPro)
		{
			warpMapChannelIdx.MapIndex		= nBackMapIndex;	// 2008-06-20 by cmkwon, EP3 백맵 시스템 수정(맵당 백맵을 2개 설정 할 수 있다) - 
			warpMapChannelIdx.ChannelIndex	= 0;
			nWarpObjectIndex				= pBackMapFMPro->GetWarpObjectIndex(m_character.InfluenceType);
			if(0 == nWarpObjectIndex)
			{// 2006-12-08 by cmkwon, 세력별 WarpObjectIndex가 설정되어 있지 않다
				nWarpObjectIndex			= pBackMapFMPro->GetRandomWarpTargetEventIndex();
			}
		}
	}
	
	if(0 == nWarpObjectIndex)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2005-12-12 by cmkwon, 현재 위치에서 가장 가까운 타겟 워프 게이트를 찾는다
		EVENTINFO *pEvInfo = m_pCurrentFieldMapChannel->GetEventInfoByMinimumDistanceW(EVENT_TYPE_WARP_TARGET, &m_character.PositionVector);
		if(pEvInfo)
		{
			nWarpObjectIndex	= pEvInfo->m_EventwParam1;
		}
	}

	WarpToMap(warpMapChannelIdx, nWarpObjectIndex);

	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(100) : %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);
	return RES_RETURN_TRUE;


// 2005-12-05 by cmkwon, 아래와 같이 수정됨
//	EventResult_t ret;
//	if(FALSE == this->m_bDeadReasonByPK
//		|| this->IsCityCurrentFieldMapChannel())
//	{// 1:1 PK로 죽은 상태가 아닐 때 처리
//		ret = WarpToCityMap();	// 도시맵으로
//		if (ret == EVENT_RESULT_BREAK)
//		{
//			DBGOUT(STRMSG_S_F2NOTIFY_0027,
//				this->GetCityFieldMapProjectPtr()->m_nMapIndex, GetCharacterString(&m_character, string()));
//		}
//		return RES_RETURN_TRUE;
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 1:1 PK로 죽은 상태이크로 현재맵의 워프게이트로 이동 시킨다.
//	this->m_bDeadReasonByPK		= FALSE;
//	ret = WarpToMap(m_pCurrentFieldMapChannel->m_MapChannelIndex);		// 현재맵의 워프게이트로
//	if (ret == EVENT_RESULT_BREAK)
//	{
//		DBGOUT(STRMSG_S_F2NOTIFY_0027,
//			m_pCurrentFieldMapChannel->m_MapChannelIndex.MapIndex, GetCharacterString(&m_character, string()));
//	}

//	///////////////////////////////////////////////////////////////////////////////
//	// 2005-12-05 by cmkwon, 캐릭터가 죽은 후 재시작시 도시맵 or 현재맵 부활 선택가능
//	this->m_bDeadReasonByPK		= FALSE;
//	if(pRecvDeadGameStart->bRebirthInCityMap
//		|| this->IsCityCurrentFieldMapChannel()
//		|| 0 >= this->GetCharacter()->CurrentEP)	// 2005-12-06 by cmkwon, 연료가 0일때는 무조건 도시맵으로 이동
//	{
//		WarpToCityMap();	// 도시맵으로
//		return RES_RETURN_TRUE;
//	}

// 2007-09-16 by dhjin, 상위로 이동.
//	CFieldMapProject *pFMPro = this->GetCurrentFieldMapProject();
//	if(NULL == pFMPro)
//	{
//		return RES_RETURN_TRUE;
//	}
//
//	int nMapInfluenceTy = pFMPro->GetMapInfluenceType();

// 2007-09-28 by cmkwon, 소스 위치 이동 - 위쪽으로 이동
//	if(IsGoToInfluenceCity(GetCharacter()->InfluenceType, nMapInfluenceTy))
//	{
//		WarpToCityMap();	// 도시맵으로
//		return RES_RETURN_TRUE;
//	}

// 2006-12-08 by cmkwon, 각 세력별 워프게이트를 찾아서 처리한다.
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-08-02 by cmkwon, 상대 세력 맵일경우 이전맵에서 부활됨
//	if(0 != pFMPro->m_nBeforeMapIndex
//		&& IS_OTHER_INFLUENCE_MAP(m_character.InfluenceType, nMapInfluenceTy)
//		&& FALSE == m_pCurrentFieldMapChannel->IsOccupyStrategyPointMonster())		// 2006-11-21 by cmkwon, 전략포인트 몬스터 관련 체크
//	{
//		CFieldMapProject *pBeforeFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pFMPro->m_nBeforeMapIndex);
//		if(pBeforeFMPro)
//		{
//			WarpToMap(pFMPro->m_nBeforeMapIndex, 0, pBeforeFMPro->GetRandomWarpTargetEventIndex());
//			return RES_RETURN_TRUE;
//		}
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2005-12-12 by cmkwon, 현재 위치에서 가장 가까운 타겟 워프 게이트를 찾는다
//	int TargetIndex		= ~0;
//	EVENTINFO *pEvInfo = m_pCurrentFieldMapChannel->GetEventInfoByMinimumDistanceW(EVENT_TYPE_WARP_TARGET, &m_character.PositionVector);
//	if(pEvInfo)
//	{
//		TargetIndex		= pEvInfo->m_EventwParam1;
//	}
//	WarpToMap(m_pCurrentFieldMapChannel->m_MapChannelIndex, TargetIndex);		// 현재맵의 워프게이트로

// 2007-09-28 by cmkwon, 소스 위치 이동 - 위로 이동
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-12-08 by cmkwon, 각 세력별 부활 워프게이트가 따로 설정된다.
//	MAP_CHANNEL_INDEX	warpMapChannelIdx	= this->GetCurrentFieldMapChannel()->GetMapChannelIndex();
//	int					nWarpObjectIndex	= this->GetCurrentFieldMapChannel()->GetWarpObjectIndexW(m_character.InfluenceType);
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-08-02 by cmkwon, 상대 세력 맵일경우 이전맵에서 부활됨
//	if(0 != pFMPro->m_nBeforeMapIndex
//		&& IS_OTHER_INFLUENCE_MAP(m_character.InfluenceType, nMapInfluenceTy)
//		&& FALSE == m_pCurrentFieldMapChannel->IsOccupyStrategyPointMonster())		// 2006-11-21 by cmkwon, 전략포인트 몬스터 관련 체크
//	{
//		CFieldMapProject *pBackMapFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pFMPro->m_nBeforeMapIndex);
//		if(pBackMapFMPro)
//		{
//			warpMapChannelIdx.MapIndex		= pFMPro->m_nBeforeMapIndex;
//			warpMapChannelIdx.ChannelIndex	= 0;
//			nWarpObjectIndex				= pBackMapFMPro->GetWarpObjectIndex(m_character.InfluenceType);
//			if(0 == nWarpObjectIndex)
//			{// 2006-12-08 by cmkwon, 세력별 WarpObjectIndex가 설정되어 있지 않다
//				nWarpObjectIndex			= pBackMapFMPro->GetRandomWarpTargetEventIndex();
//			}
//		}
//	}
//	
//	if(0 == nWarpObjectIndex)
//	{
//		///////////////////////////////////////////////////////////////////////////////
//		// 2005-12-12 by cmkwon, 현재 위치에서 가장 가까운 타겟 워프 게이트를 찾는다
//		EVENTINFO *pEvInfo = m_pCurrentFieldMapChannel->GetEventInfoByMinimumDistanceW(EVENT_TYPE_WARP_TARGET, &m_character.PositionVector);
//		if(pEvInfo)
//		{
//			nWarpObjectIndex	= pEvInfo->m_EventwParam1;
//		}
//	}
//
//	WarpToMap(warpMapChannelIdx, nWarpObjectIndex);
//	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
//	char szSystemLog[1024];
//	sprintf(szSystemLog, "[Notify] WarpToMap(100) : %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);
//	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GAMESTART(const char* pPacket, int nLength, int &nBytesUsed)
{
	DbgOut("[1]Process_FC_CHARACTER_GAMESTART들어왔음...\r\n");
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	MSG_FC_CHARACTER_GAMESTART		*pRecvCharacterGameStart	= NULL;

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_GAMESTART);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		DbgOut("[2]5545\r\n");
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14013);
		return RES_RETURN_FALSE;
	}
	pRecvCharacterGameStart = (MSG_FC_CHARACTER_GAMESTART*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(FALSE == IsUsing())
	{// 2006-10-13 by cmkwon, 
		DbgOut("[3]6654\r\n");
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-13 by cmkwon, 튜토리얼 스킵 등으로 수정된 정보를 다시 설정한다.
	// m_mtvectCharacterCache에서 m_character를 load
	mt_auto_lock ccLock(&m_mtvectCharacterCache);
	CHARACTER *pCharac = this->GetCharacterCacheNoLock(pRecvCharacterGameStart->CharacterUniqueNumber);
	DbgOut("[2]Character UniqueNumber[%d]\r\n",pRecvCharacterGameStart->CharacterUniqueNumber);
	if(NULL == pCharac)
	{
		DbgOut("[4]7789\r\n");
		ccLock.auto_unlock_cancel();
		SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		Close(0x14016);
		return RES_RETURN_FALSE;
	}			
	m_character		= *pCharac;
	ccLock.auto_unlock_cancel();
	
	// 2012-06-07 by hskim, 관리자 계정 보안 강화 - 특수계정은 등록된 아이피가 아니면 접속 차단
#ifdef S_ADMIN_CHARACTER_LOGIN_IP_CHECK
	if( m_character.Race & RACE_ACCOUNT_TYPE_MASK )
	{
		// 2013-03-14 by jhseol, 버전인포 리로드 시 접속 허용 IP리스트도 갱신
#ifdef S_ALLOWED_IP_RELOAD_JHSEOL
		if(FALSE == g_pFieldGlobal->CheckAllowedAdminClientIP(this->GetPeerIP()))	// 2013-03-14 by jhseol, 버전인포 리로드 시 접속 허용 IP리스트도 갱신
#else
		if(FALSE == g_pFieldGlobal->CheckAllowedToolIP(this->GetPeerIP()))		// 2008-06-05 by cmkwon, AdminTool, Monitor 접근 가능 IP를 server config file 에 설정하기 -
#endif
		// end 2013-03-14 by jhseol, 버전인포 리로드 시 접속 허용 IP리스트도 갱신
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "  [Notify] Admin Character : Deny Login (Not Allowed IP) : %s Type(%d) IP(%s)\r\n", GetCharacterString(GetCharacter(), string()), m_character.Race, this->GetPeerIP());

			SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_NOT_ALLOWED_IP);
			Close(0x14101);
			return RES_RETURN_FALSE;
		}
	}
#endif // S_ADMIN_CHARACTER_LOGIN_IP_CHECK
	// end 2012-06-07 by hskim, 관리자 계정 보안 강화 - 특수계정은 등록된 아이피가 아니면 접속 차단

	// START 2011-11-03 by shcho, yedang 셧다운제 구현
#ifdef SC_SHUT_DOWNMIN_SHCHO
	vectShutDownUserData::iterator iter(ms_pFieldIOCP->m_ShutDownData.begin());

	DbgOut( "[3]ms_pFieldIOCP->m_ShutDownData size = [%d]\r\n", ms_pFieldIOCP->m_ShutDownData.size() );

	for(;iter !=ms_pFieldIOCP->m_ShutDownData.end(); iter++ )
	{
		if(m_character.AccountUniqueNumber==iter->Account_UniqueNumber)		// 2012-06-07 by hskim, 코드 보안 (아주 예외적인 경우 죽을 수 있음)
		{	// 같은 값이 있다.
			DbgOut("[1-1]Process_FC_CHARACTER_GAMESTART UpdateShutDownData CharacterUniqueNumber = [%d]\r\n!!", iter->CharacterUniqueNumber[0]);	 	 
			iter->CharacterUniqueNumber[0] = pRecvCharacterGameStart->CharacterUniqueNumber;	// 미성년 계정이지만 최초 케릭터를 만들경우
			DbgOut("[1-2]Process_FC_CHARACTER_GAMESTART UpdateShutDownData CharacterUniqueNumber = [%d]\r\n!!", pRecvCharacterGameStart->CharacterUniqueNumber);
			break;
		}
	}
#endif // SC_SHUT_DOWNMIN_SHCHO
	// END 2011-11-03 by shcho, yedang 셧다운제 구현

	///////////////////////////////////////////////////////////////////////////////
	// 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, ERR_DOING_SERVER_SHUTDOWN);
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_CHARACTER_GAMESTART#, 일반세력 시작 도시맵이 설정되지 않음
	if(IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType)
		&& 0 == m_character.Material)
	{
		SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_REQ_CHOOSE_START_CIIY_MAP_INDEX, m_character.Material);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-06-05 by cmkwon, 보안 관련 처리
	// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
	//Err_t err = this->SecurityCheckVersion();
	Err_t err = this->SecurityClientInit();		// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_CHARACTER_GAMESTART, err);
		return RES_BREAK;
	}

	if(CS_GOTCHARACTER > GetClientState() || CS_PLAYING <= GetClientState())
	{
		// Protocol Error 처리
		// - 유효하지 않은 Game Start 메세지
		// Error Code : ERR_PROTOCOL_INVALID_GAMESTART
		char szSystemLog[256];
		sprintf(szSystemLog, STRERR_S_F2NOTIFY_0002, GetClientState());
		g_pFieldGlobal->WriteSystemLog(szSystemLog);
		DBGOUT(szSystemLog);

		SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_INVALID_GAMESTART, (int)GetClientState());
		return RES_BREAK;
	}

	if(m_character.ClientIndex == 0 || m_character.ClientIndex != pRecvCharacterGameStart->ClientIndex)
	{
		// Protocol Error 처리
		// - 접속한 client index와 요청한 client index이 다르다
		// Error Code : ERR_PROTOCOL_INVALID_CLIENTINDEX
		SendErrorMessage(T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 팅긴 유저 재접속 처리
	if(FALSE == g_pFieldGlobal->IsArenaServer()
		&& TRUE == IS_INFINITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{
		this->SendAddMessageType(T_FC_INFINITY_REQUEST_RESTART_BY_DISCONNECT);
	}

	CFieldMapProject *pFieldMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(m_character.MapChannelIndex.MapIndex);	
	if (pFieldMapProject == NULL)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FC_CHARACTER_GAMESTART# MapChannel is invalid !!, %s Map(%s) will change to defaultMap(%d) \r\n"
			, GetCharacterString(GetCharacter(), string()), GetMapString(m_character.MapChannelIndex, string()), ms_pFieldIOCP->m_pDefaultMapProject->m_nMapIndex);

		pFieldMapProject							= ms_pFieldIOCP->m_pDefaultMapProject;
		m_character.MapChannelIndex.MapIndex		= pFieldMapProject->m_nMapIndex;
		m_character.MapChannelIndex.ChannelIndex	= 0;
	}

// 2006-07-03 by cmkwon - 주석처리
// 	if(IS_CITY_MAP_INDEX(pFieldMapProject->m_nMapIndex))
// 	{
// 		m_character.PositionVector					= pFieldMapProject->GetRandomXZCityWarpTargetPosition();
// 	}

	m_atLoginDate.SetCurrentDateTime();		// 2013-03-29 by jhseol, 아이템 이벤트 - 서브타입 추가구조로 변경 - 서버시간 기준으로 계정의 게임 시작시간을 저장
	BOOL bResult = CharacterGameStartRoutine(GST_GAMESTART);
	if (!bResult)
	{
		SendErrorMessage (T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_GAMESTARTROUTINE_FAILED, 0, 0, NULL, TRUE);
		return RES_RETURN_FALSE;
	}
// 2007-04-09 by cmkwon, 위와 같이 하나의 필드서버만 처리함
//	if (pFieldMapProject->BelongsToServer())
//	{
//		BOOL bResult = CharacterGameStartRoutine(GST_GAMESTART);
//		if (!bResult)
//		{
//			SendErrorMessage (T_FC_CHARACTER_GAMESTART, ERR_PROTOCOL_GAMESTARTROUTINE_FAILED, 0, 0, NULL, TRUE);
//			return RES_RETURN_FALSE;
//		}
//	}
//	else
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 다른 필드서버에서 connect_gamestart를 하는 경우
//
//		// 필드 서버 변경을 위한 close가 발생한다.
//		m_bFieldServerChangeFlag = TRUE;
//
//		// PreServer에게 client의 FieldServer IP를 통지한다
//		*(MessageType_t*)SendBuf = T_FP_CONNECT_NOTIFY_FIELDSERVER_CHANGE;
//		MSG_FP_CONNECT_NOTIFY_FIELDSERVER_CHANGE *pSendMsgNotifyFieldServerChange
//			= (MSG_FP_CONNECT_NOTIFY_FIELDSERVER_CHANGE*)(SendBuf+SIZE_FIELD_TYPE_HEADER);
//		STRNCPY_MEMSET(pSendMsgNotifyFieldServerChange->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
//		pSendMsgNotifyFieldServerChange->FieldServerID.SetValue(pFieldMapProject->m_strFieldIP, pFieldMapProject->m_sFieldListenPort);
//		pSendMsgNotifyFieldServerChange->ClientIndex = this->GetClientArrayIndex();
//		ms_pFieldIOCP->m_pPreWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FP_CONNECT_NOTIFY_FIELDSERVER_CHANGE));
//
//		// 이후의 부분은 PreServer로부터 MSG_FP_CONNECT_NOTIFY_FIELDSERVER_CHANGE_OK를 받고 난 후 처리
//		// 이후의 부분: client에게 gamestart_ok 보내기
//	}

// 2014-03-12 by jekim, 주민번호당 아이템 지급 - 주석처리함
// 	// 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
// #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
// 	// end 2013-03-29 by jhseol, 아이템 이벤트 - 매월 첫 결재시 선물지급
// end 2014-03-12 by jekim, 주민번호당 아이템 지급


// 2014-04-21 by jekim, 웹 캐시 상점 보완 - 첫구매
 #ifdef S_MONTHL_CASH_BUY_GIFT_JHSEOL
 	if ( FALSE == g_pFieldGlobal->IsArenaServer() )
 	{
 		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetFirstPurchaseFromXMLRPC, this, m_character.AccountUniqueNumber, NULL);
 	}
#endif
// end 2014-04-21 by jekim, 웹 캐시 상점 보완

	// 2014-02-11 by jhseol, 클라요청 캐쉬샵 판매 아이템 리스트 보내주기
	map<UINT, CShopInfo*>::iterator itr
		=  m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(CASH_SHOP_BUILDING_INDEX);
	if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
	{
		SendErrorMessage(T_FC_SHOP_GET_SHOP_ITEM_LIST, ERR_PROTOCOL_NO_SUCH_SHOP, CASH_SHOP_BUILDING_INDEX);
		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);
	// end 2014-02-11 by jhseol, 클라요청 캐쉬샵 판매 아이템 리스트 보내주기

	return RES_RETURN_TRUE;
}

//FC_CHARACTER_CONNECT_GAMESTART가 FC_CHARACTER_GAMESTART에서 추가적으로 수행해야 할 일
//- 프리 서버에 AUTH_USER
//- m_character에 정보 loading - DB 질의 필요
//- Client는 자신의 ClientIndex는 FC_CHARACTER_CONNECT_GAMESTART_OK에서 설정해야 한다
//- 원래 gamestart에서 처리하던 부분은 ResConnectGameStart()에서 처리함
ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CONNECT_GAMESTART(const char* pPacket, int nLength, int &nBytesUsed)
{
	return RES_RETURN_FALSE;
// 2005-07-21 by cmkwon, 다른 필드서버로의 GameStart는 없으므로 삭제함
//#ifdef _DEBUG
//	DBGOUT("CONNECT_GAME_START(%s) %s\n", ms_pFieldIOCP->m_FieldServerID.GetString(string()), m_character.CharacterName, DBG_GET_POSITION_STRING(m_character.PositionVector, string()));
//#endif
//	int						nRecvTypeSize	= 0;
//	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
//	const CHARACTER			*pCharacter			= NULL;
//	char					SendBuf[SIZE_MAX_PACKET];
//
//	MSG_FC_CHARACTER_CONNECT_GAMESTART		*pRecvCharacterConnectGameStart = NULL;
//
//	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_CONNECT_GAMESTART);
//	if(nLength - nBytesUsed < nRecvTypeSize)
//	{
//		// Protocl Error 처리
//		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
//		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
//		SendErrorMessage(T_FC_CHARACTER_CONNECT_GAMESTART, ERR_PROTOCOL_INVALID_FIELD_DATA);
//		Close(0x14017);
//		return RES_RETURN_FALSE;
//	}
//	pRecvCharacterConnectGameStart = (MSG_FC_CHARACTER_CONNECT_GAMESTART*)(pPacket+nBytesUsed);
//	nBytesUsed += nRecvTypeSize;
//
//	if( CS_CONNECTED != GetClientState())
//	{
//		// Protocol Error 처리
//		// - 유효하지 않은 Game Start 메세지
//		// Error Code : ERR_PROTOCOL_INVALID_GAMESTART
//		SendErrorMessage(T_FC_CHARACTER_CONNECT_GAMESTART, ERR_PROTOCOL_INVALID_CONNECT_GAMESTART);
//	}
//
//	// 접속자의 정보들을 설정한다.
//	strncpy(m_character.AccountName, pRecvCharacterConnectGameStart->AccountName, SIZE_MAX_ACCOUNT_NAME);
//	m_character.CharacterUniqueNumber = pRecvCharacterConnectGameStart->CharacterUniqueNumber;
//	m_character.AccountUniqueNumber= pRecvCharacterConnectGameStart->AccountUniqueNumber;
//
//	// 처리: Pre Server AUTH_USER를 요청한다.
//	MSG_FP_CONNECT_AUTH_USER msgAuthUser;
//
//	// set header
//	*(MessageType_t*)SendBuf = T_FP_CONNECT_AUTH_USER;
//
//	// set body
//	strncpy(msgAuthUser.AccountName, pRecvCharacterConnectGameStart->AccountName, SIZE_MAX_ACCOUNT_NAME);
//	msgAuthUser.FieldServerID = ms_pFieldIOCP->m_FieldServerID;
//	strncpy(msgAuthUser.PrivateIP, pRecvCharacterConnectGameStart->PrivateIP, SIZE_MAX_IPADDRESS);
//	msgAuthUser.ClientIndex = this->GetClientArrayIndex();
//	msgAuthUser.AuthType = PRESERVER_AUTH_TYPE_CONNECT_GAMESTART;
//	memcpy(SendBuf + SIZE_FIELD_TYPE_HEADER, &msgAuthUser, sizeof(MSG_FP_CONNECT_AUTH_USER));
//
//	// send message to PreServer
//	ms_pFieldIOCP->m_pPreWinSocket->Write((char*)SendBuf, MSG_SIZE(MSG_FP_CONNECT_AUTH_USER));
//	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_GAMEEND(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	const CHARACTER				*pCharacter = NULL;
	MSG_FC_CHARACTER_GAMEEND	*pRecvCharacterGameEnd = NULL;

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

	if(m_character.ClientIndex != pRecvCharacterGameEnd->ClientIndex)
	{
		// Protocl Error 처리
		// - GameEnd가 유효 하지 않음
		// Error Code : ERR_PROTOCOL_INVALID_GAMEEND
		SendErrorMessage(T_FC_CHARACTER_GAMEEND, ERR_PROTOCOL_INVALID_GAMEEND, m_character.ClientIndex, pRecvCharacterGameEnd->ClientIndex);
		Close(0x1401A);
		return RES_RETURN_FALSE;
	}

	///////////////////////////////////////////////////////////////////////////
	// 종료가 가능한지의 여부를 체크
	// check --> 20021227 cmkwon

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피니티에서는 케릭터 선택창 이동을 막는다.!!
	if(TRUE == pRecvCharacterGameEnd->SelectCharacterView
		&& CS_ARENASERVER_PLAYING == this->GetClientState()) {
		SendErrorMessage(T_FC_CHARACTER_GAMEEND, ERR_PROTOCOL_INVALID_GAMEEND);
		return RES_RETURN_FALSE;
	}

	// 정상적인 game end이므로
	m_bFieldServerChangeFlag = FALSE;

	// start 2012-10-08 by khkim, GLog
	// GameEnd 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 (일반유저만 기록)	
	{
		INT nPay = 0;

		{
			mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
		
			ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
			if (pMoney == NULL )
			{
				nPay = 0;
			}
			else
			{
				nPay = pMoney->CurrentCount;
			}
		}

		MSG_FL_LOG_CHARDATA LogCharDataParameter;
		MEMSET_ZERO(&LogCharDataParameter, sizeof(LogCharDataParameter));		// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
		LogCharDataParameter.LogType			= GLOG_CD_LT_GAMEEND;
		LogCharDataParameter.UserSerial			= (UID64_t)m_character.AccountUniqueNumber; 
		LogCharDataParameter.CharSerial			= (UID64_t)m_character.CharacterUniqueNumber;
		LogCharDataParameter.Class				= (SHORT)m_character.UnitKind;
		LogCharDataParameter.Lv					= (SHORT)m_character.Level;
		LogCharDataParameter.Exp				= (UID64_t)m_character.Experience;
		LogCharDataParameter.GameMoney			= (UID64_t)nPay;
		LogCharDataParameter.Playtime			= (UID64_t)GetTotalPlayTimeInSeconds();		// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅			// 2013-01-18 by khkim, GLog (총 플레이시간 수정)
		LogCharDataParameter.GameServerID		= (int)g_pFieldGlobal->GetMGameServerID();

// 2013-01-03 by khkim, GLog (버그 확인용)
#ifdef S_KOR_TEST_GLOG_CHARDATA
		if(LogCharDataParameter.UserSerial < 0 || LogCharDataParameter.UserSerial > 7000000 )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE,"[DEBUG] GLog #002 [%d,%I64d,%I64d,%d,%d,%I64d,%I64d,%I64d,%d]\r\n ", 
				LogCharDataParameter.LogType,	LogCharDataParameter.UserSerial,	LogCharDataParameter.CharSerial,
				LogCharDataParameter.Class,		LogCharDataParameter.Lv,			LogCharDataParameter.Exp, 
				LogCharDataParameter.GameMoney, LogCharDataParameter.Playtime,		LogCharDataParameter.GameServerID);
		}
#endif 
// end 2013-01-03 by khkim, GLog (버그 확인용)	

		CAtumLogSender::SendLogCharData(&LogCharDataParameter);
	}
	// end 2012-10-08 by khkim, GLog

	///////////////////////////////////////////////////////////////////////////
	// 종료 루틴을 호출한다.
	this->CharacterGameEndRoutine();

	INIT_MSG_WITH_BUFFER(MSG_FP_EVENT_ENTER_SELECT_SCREEN, T_FP_EVENT_ENTER_SELECT_SCREEN, msgEnterSelectScreen, msgEnterSelectScreenBuf);
	STRNCPY_MEMSET(msgEnterSelectScreen->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	ms_pFieldIOCP->m_pPreWinSocket->Write(msgEnterSelectScreenBuf, MSG_SIZE(MSG_FP_EVENT_ENTER_SELECT_SCREEN));

	///////////////////////////////////////////////////////////////////////////////
	// 2012-10-05 by jhseol, NPlay pc방 모듈 - 캐릭터 선택 화면으로 갈때  NPlay 과금중단 요청을 보낸다
#ifdef S_NPLAY_PCBANG_MODULE_JHSEOL
	if( TRUE == pRecvCharacterGameEnd->SelectCharacterView )
	{
		INIT_MSG_WITH_BUFFER(MSG_FP_PCBANG_USER_PREMIUN_END, T_FP_PCBANG_USER_PREMIUN_END, msgPREMIUN_END, msgPREMIUN_ENDBuf);
		STRNCPY_MEMSET(msgPREMIUN_END->AccountName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
		ms_pFieldIOCP->m_pPreWinSocket->Write(msgPREMIUN_ENDBuf, MSG_SIZE(MSG_FP_PCBANG_USER_PREMIUN_END));
	}
#endif
	// end 2012-10-05 by jhseol, NPlay pc방 모듈 - 캐릭터 선택 화면으로 갈때  NPlay 과금중단 요청을 보낸다

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_REPAIR(const char* pPacket, int nLength, int &nBytesUsed)
{
	char					*pRecvMsg = NULL;
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	// Client로부터 Character를 수리하는 요청을 받음
	// 응답으로 T_FC_CHARACTER_REPAIR_OK 혹은 T_FC_CHARACTER_REPAIR_ERR 메세지를 보낸다.

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_REPAIR);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_CHARACTER_REPAIR, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1401B);
		return RES_RETURN_FALSE;
	}
	pRecvMsg = new char[sizeof(MSG_FC_CHARACTER_REPAIR)];
	memcpy(pRecvMsg, pPacket+nBytesUsed, nRecvTypeSize);
	nBytesUsed += nRecvTypeSize;

	// 처리
	//ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(this, (MSG_FC_CHARACTER_REPAIR*)pRecvMsg, QT_RepairCharacter);
	pRecvMsg = NULL;

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_DOCKING(const char* pPacket, int nLength, int &nBytesUsed)
{
	char					*pRecvMsg = NULL;
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	// Client로부터 아이템 장착 요청을 받음
	// 응답으로 T_FC_CHARACTER_DOCKING 메세지를 보낸다.

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_DOCKING);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_CHARACTER_DOCKING, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1401C);
		return RES_RETURN_FALSE;
	}
	pRecvMsg = new char[sizeof(MSG_FC_CHARACTER_DOCKING)];
	memcpy(pRecvMsg, pPacket+nBytesUsed, nRecvTypeSize);
	nBytesUsed += nRecvTypeSize;

	// 처리
	//ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueQuery(this, (MSG_FC_CHARACTER_DOCKING*)pRecvMsg, QT_RepairCharacter);
	//pRecvMsg = NULL;


	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_UNDOCKING(const char* pPacket, int nLength, int &nBytesUsed)
{
	char					*pRecvMsg = NULL;
	int						nRecvTypeSize	= 0;
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	// Client로부터 아이템 제거 요청을 받음
	// 응답으로 T_FC_CHARACTER_UNDOCKING 메세지를 보낸다.
	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_UNDOCKING);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_CHARACTER_UNDOCKING, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1401D);
		return RES_RETURN_FALSE;
	}
	pRecvMsg = new char[sizeof(MSG_FC_CHARACTER_UNDOCKING)];
	memcpy(pRecvMsg, pPacket+nBytesUsed, nRecvTypeSize);
	nBytesUsed += nRecvTypeSize;

	// 처리
	//ms_pFieldIOCP->m_pAtumDBManager->RepairCharacter(this, (MSG_FC_CHARACTER_UNDOCKING*)pRecvMsg);
	//pRecvMsg = NULL;


	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_BODYCONDITION(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize	= 0;
	MSG_FC_CHARACTER_CHANGE_BODYCONDITION	*pMsgChangeBodyCon = NULL;
	BOOL									bSendIncludingMe = FALSE;

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_CHANGE_BODYCONDITION);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14020);
		return RES_RETURN_FALSE;
	}

	pMsgChangeBodyCon = (MSG_FC_CHARACTER_CHANGE_BODYCONDITION*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(m_character.ClientIndex != pMsgChangeBodyCon->ClientIndex)
	{
		// Protocol Error 처리
		// - 접속한 ClientIndex와 요청한 ClientIndex가 다르다
		// Error Code : ERR_PROTOCOL_INVALID_CLIENTINDEX

		SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	// body condition이 같다면 무시
	if (m_character.BodyCondition == pMsgChangeBodyCon->BodyCondition)
	{
		return RES_BREAK;
	}

	/*
	// exclusive body condition 확인: EX_BIT은 모두 0으로 보내야 함
	if ((BODYCON_EX_STATE_CLEAR_MASK & pMsgChangeBodyCon->BodyCondition) != 0)
	{
		SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_BODYCONDITION);
		Close(0x14021);
		return RES_RETURN_FALSE;
	}
	*/

	BodyCond_t flag = ((~BODYCON_SET_OR_CLEAR_MASK) & pMsgChangeBodyCon->BodyCondition);
	BOOL characterModeFlag = FALSE;

	if (COMPARE_BODYCON_BIT(pMsgChangeBodyCon->BodyCondition, BODYCON_SET_OR_CLEAR_MASK) == TRUE)
	{
		// body condition 설정
		switch(flag)
		{
		case 0:			// 2006-11-02 by cmkwon, BodyCondition 초기
			{
				m_character.BodyCondition			= 0;		// 2006-11-02 by cmkwon
			}
			break;
		case BODYCON_SPRAY_MASK:
		case BODYCON_FLY_MASK:
		case BODYCON_LANDING_MASK:
		case BODYCON_LANDED_MASK:
		case BODYCON_WEAPON_POSITION_MASK:			// 2005-12-16 by cmkwon, 필요없지만 추가함
		case BODYCON_BOOSTER1_MASK:
		case BODYCON_BOOSTER4_MASK:
		case BODYCON_BOOSTER5_MASK:
		case BODYCON_NIGHTFLY_MASK:
		case BODYCON_EXPLOSION_MASK:
		case BODYCON_DAMAGE1_MASK:
		case BODYCON_DAMAGE2_MASK:
		case BODYCON_DAMAGE3_MASK:
		case BODYCON_CREATION_MASK:
		case BODYCON_FIRE_MASK:
		case BODYCON_BULLET_MASK:
		case BODYCON_HIT_MASK:
		case BODYCON_SIEGE_ON_MASK:
		case BODYCON_SIEGE_OFF_MASK:
		case BODYCON_ROLLING_MASK:			// 2009-07-07 by cmkwon, 로봇 아머 관련 처리 추가 - 
		case BODYCON_STOP_MASK:				// 2010-03-30 by cmkwon, 필드창고 비행중 이용 버그 수정(E0044710) - 
			{
				SetBodyConditionBit(m_character.BodyCondition, flag);
			}
			break;
		case BODYCON_BOOSTER2_MASK:
			{
				bSendIncludingMe = TRUE;

				if ( COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_BOOSTER3_MASK)	// 부스터 끄기로 사용
//					&& !COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER)		// 관리자는 EP 소모 안 됨
				)
				{
					// 부스터 끄기, do nothing for now, 20031017, kelovon
				}
				SetBodyConditionBit(m_character.BodyCondition, flag);
			}
			break;
		case BODYCON_BOOSTER3_MASK:
			{
				bSendIncludingMe = TRUE;
// 2007-03-09 by cmkwon, WEIGHT_RATE_VERY_HEAVY초과시 부스터 사용 불가로 아래와 같이 수정(기존에는 WEIGHT_RATE_VERY_HEAVY 이상 이었음)
//				// 최대 적재량의 80% 부스터 사용 금지 
//				if (GetCurrentLoadagePercentage() < WEIGHT_RATE_VERY_HEAVY)
//				{
//					SetBodyConditionBit(m_character.BodyCondition, flag);
//				}
//				else
//				{
//					// 2006-10-13 by cmkwon, 에러 전송 추가
//					SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_CANNOT_BOOSTER);
//					return RES_BREAK;
//				}
				if (WEIGHT_RATE_VERY_HEAVY < GetCurrentLoadagePercentage())
				{
					// 2006-10-13 by cmkwon, 에러 전송 추가
					SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_CANNOT_BOOSTER);
// 2007-11-02 by cmkwon, 부스터 관련은 클라이언트에서 처리 하도록 한다. 서버는 에러만 보내도 정상적으로 처리한다.
//					return RES_BREAK;
				}
				SetBodyConditionBit(m_character.BodyCondition, flag);

				// 부스터가 가동되면 GRADUAL_HP_UP 취소
// 				m_nRemainedTimeOfGradualHPUP = 0;
			}
			break;
		// 2005-07-28 by hblee : 캐릭터모드 바디 컨디션 추가.
		case BODYCON_CHARACTER_MODE_STOP:
		case BODYCON_CHARACTER_MODE_WALK:
		case BODYCON_CHARACTER_MODE_RUN:
			{
				characterModeFlag = TRUE;
				SetBodyConditionBit(m_character.BodyCondition, flag);
			}
			break;
		default:
			SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_BODYCONDITION, HIDWORD(flag), LODWORD(flag));
			return RES_BREAK;
		}
	}
	else
	{
		// body condition 해제
		switch(flag)
		{
		case BODYCON_SPRAY_MASK:
		case BODYCON_FLY_MASK:
		case BODYCON_LANDING_MASK:
		case BODYCON_LANDED_MASK:
		case BODYCON_WEAPON_POSITION_MASK:			// 2005-12-16 by cmkwon, 필요없지만 추가함
		case BODYCON_BOOSTER1_MASK:
		case BODYCON_BOOSTER2_MASK:
		case BODYCON_BOOSTER3_MASK:
		case BODYCON_BOOSTER4_MASK:
		case BODYCON_BOOSTER5_MASK:
		case BODYCON_NIGHTFLY_MASK:
		case BODYCON_EXPLOSION_MASK:
		case BODYCON_DAMAGE1_MASK:
		case BODYCON_DAMAGE2_MASK:
		case BODYCON_DAMAGE3_MASK:
		case BODYCON_CREATION_MASK:
		case BODYCON_FIRE_MASK:
		case BODYCON_BULLET_MASK:
		case BODYCON_HIT_MASK:
		case BODYCON_SIEGE_ON_MASK:
		case BODYCON_SIEGE_OFF_MASK:
		case BODYCON_ROLLING_MASK:			// 2009-07-07 by cmkwon, 로봇 아머 관련 처리 추가 - 
		case BODYCON_STOP_MASK:				// 2010-03-30 by cmkwon, 필드창고 비행중 이용 버그 수정(E0044710) - 
			{
				ClearBodyConditionBit(m_character.BodyCondition, flag);
			}
			break;
		default:
			SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION, ERR_PROTOCOL_INVALID_BODYCONDITION, HIDWORD(flag), LODWORD(flag));
			return RES_BREAK;
		}
	}

	if(characterModeFlag == FALSE)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, pMsgChangeBodyConClientBuf);
		pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
		pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
		SendInRangeMessageAroundMe(pMsgChangeBodyConClientBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION), bSendIncludingMe);		
		// 2009-07-28 by cmkwon, [TEMP] 테스트 - 
		//DbgOut("BodyConition: %s %#08x%08x \r\n", GetCharacterString(GetCharacter(), string()), HIDWORD(m_character.BodyCondition), LODWORD(m_character.BodyCondition));
		//DbgOut("BodyConition: %s RollingBodyCon %d \r\n", GetCharacterString(GetCharacter(), string()), COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_ROLLING_MASK));
	}
	else if(bSendIncludingMe)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, pMsgChangeBodyConClientBuf);
		pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
		pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
		SendAddData(pMsgChangeBodyConClientBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION));
	}
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_CHANGE_BODYCONDITION_ALL(const char* pPacket, int nLength, int &nBytesUsed)
{
	int											nRecvTypeSize	= 0;
	MSG_FC_CHARACTER_CHANGE_BODYCONDITION_ALL	*pMsgChangeBodyConAll = NULL;
	BOOL										bSendIncludingMe = TRUE;

	nRecvTypeSize = sizeof(MSG_FC_CHARACTER_CHANGE_BODYCONDITION_ALL);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION_ALL, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14020);
		return RES_RETURN_FALSE;
	}

	pMsgChangeBodyConAll = (MSG_FC_CHARACTER_CHANGE_BODYCONDITION_ALL*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(m_character.ClientIndex != pMsgChangeBodyConAll->ClientIndex)
	{
		// Protocol Error 처리
		// - 접속한 ClientIndex와 요청한 ClientIndex가 다르다
		// Error Code : ERR_PROTOCOL_INVALID_CLIENTINDEX

		SendErrorMessage(T_FC_CHARACTER_CHANGE_BODYCONDITION_ALL, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	////////////////////////////////////////////////////////////////////
	// check: 확인하는 루틴은 나중에 추가해야 함! 20040228, kelovon
	////////////////////////////////////////////////////////////////////

	// 값 설정
	m_character.BodyCondition = pMsgChangeBodyConAll->BodyCondition;

	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, pMsgChangeBodyConClientBuf);
	pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
	pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
	SendInRangeMessageAroundMe(pMsgChangeBodyConClientBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION), TRUE);
	
	return RES_RETURN_TRUE;
}

void CFieldIOCPSocket::SendDropItemsAroundPosition(D3DXVECTOR3 &pos)
{
	TWO_BLOCK_INDEXES blockIdx;
	int i, j;
	float radius = m_pCurrentFieldMapChannel->GetUserVisibleDiameterW() * 0.6f;

	m_pCurrentFieldMapChannel->m_pFieldMapProject->GetBlockAdjacentToPosition(pos.x, pos.z, radius, blockIdx);

	i = blockIdx.sMinX;
	while(i <= blockIdx.sMaxX)
	{
		j = blockIdx.sMinZ;
		while(j <= blockIdx.sMaxZ)
		{
			CMapBlock *pMapBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(i,j);

			// MapBlock 거리 확인하기
			if ( GGetLength(pMapBlock->m_CenterPositionX - pos.x,
					pMapBlock->m_CenterPositionZ - pos.z) > radius )
			{
				j++;
				continue;
			}

			SendDropItems(pMapBlock);

			j++;
		}
		i++;
	}
}

// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - 아래와 같이 수정함, 이곳에서는 삭제 처리를 하면 안된다., 마인은 사용하지 않으므로 처리 제외함.
// void CFieldIOCPSocket::SendDropItems(CMapBlock *pBlock)
// {
// 	if (pBlock == NULL){						return;}
// 
// 	INIT_MSG_OF_SIZE(MSG_FC_ITEM_SHOW_ITEM, T_FC_ITEM_SHOW_ITEM, pShowItem, pShowItemBuf);
// 	int	nSend = MSG_SIZE(MSG_FC_ITEM_SHOW_ITEM);
// 
// 	// 아이템류 보내기
// 	if (!pBlock->m_DropItemMtmap.empty())
// 	{
// 		pBlock->m_DropItemMtmap.lock();
// 		mtmapDropItem::iterator dropItemItr = pBlock->m_DropItemMtmap.begin();
// 		while (dropItemItr != pBlock->m_DropItemMtmap.end())
// 		{
// 			if(FALSE == IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex)
// 				|| 0 == dropItemItr->second.FirstCharacterUID1)
// 			{
// 				pShowItem->ItemFieldIndex		= (UINT)dropItemItr->second.pItem;
// 				pShowItem->ItemNum				= dropItemItr->second.pItem->ItemNum;
// 				pShowItem->FirstCharacterUID	= 0;
// 				pShowItem->Amount				= dropItemItr->second.pItem->CurrentCount;
// 				pShowItem->Position				= dropItemItr->second.Position;
// 				pShowItem->DropItemType			= DROP_ITEM_TYPE_PICKUP;
// 				SendAddData(pShowItemBuf, nSend);
// 			}
// 			else
// 			{				
// 				CFieldIOCPSocket *pPossessFSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(dropItemItr->second.FirstCharacterUID1);
// 				if(NULL == pPossessFSock
// 					|| FALSE == pPossessFSock->IsUsing())
// 				{// 아이템 소유자가 없음, 아이템 삭제 필요
// 
// 					ITEM_GENERAL *pItemGeneralToDel = dropItemItr->second.pItem;
// 					pBlock->m_DropItemMtmap.erase(dropItemItr++);
// 					SAFE_DELETE(pItemGeneralToDel);
// 					continue;
// 				}
// 				else if(pPossessFSock == this)
// 				{
// 					pShowItem->ItemFieldIndex		= (UINT)dropItemItr->second.pItem;
// 					pShowItem->ItemNum				= dropItemItr->second.pItem->ItemNum;
// 					pShowItem->FirstCharacterUID	= 0;
// 					pShowItem->Amount				= dropItemItr->second.pItem->CurrentCount;
// 					pShowItem->Position				= dropItemItr->second.Position;
// 					pShowItem->DropItemType			= DROP_ITEM_TYPE_PICKUP;
// 					SendAddData(pShowItemBuf, nSend);
// 				}
// 			}
// 
// 			dropItemItr++;
// 		}
// 		pBlock->m_DropItemMtmap.unlock();
// 	}
// 
// 	if(IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
// 	{// 튜토리얼맵에서 마인은 정보 전송 필요 없음
// 		return;
// 	}
// 
// 	// 마인류 보내기
// 	if (false == pBlock->m_setMapBlockDropMine.empty())
// 	{
// 		// lock m_setMapBlockDropMine
// 		mt_auto_lock mapBlockMineLock(&pBlock->m_setMapBlockDropMine);
// 		mtsetDropMine::iterator dropMineItr = pBlock->m_setMapBlockDropMine.begin();
// 		while(dropMineItr != pBlock->m_setMapBlockDropMine.end())
// 		{
// 			DROPMINE *pMine = (*dropMineItr);
// 			CFieldIOCPSocket *pMineSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMine->ClientIndex);
// 
// 			if(pMineSocket == this)
// 			{// 2004-11-18 by cmkwon, 자신의 마인정보는 전송할 필요없음
// 				dropMineItr++;
// 				continue;
// 			}
// 			
// 			if (pMineSocket != NULL && pMineSocket->IsUsingRestrict(pMine->ClientIndex, pMine->CharacterUniqueNumber))
// 			{
// 				pShowItem->ItemFieldIndex		= (UINT)pMine;
// 				pShowItem->ItemNum				= pMine->pItemInfo->ItemNum;
// 				pShowItem->FirstCharacterUID	= 0;
// 				pShowItem->Amount				= 1;
// 				pShowItem->Position				= pMine->Position;
// 				pShowItem->DropItemType			= DROP_ITEM_TYPE_ATTACK_MINE;
// 				SendAddData(pShowItemBuf, nSend);
// 			}
// 			else
// 			{
// 				pBlock->m_setMapBlockDropMine.erase(dropMineItr++);
// 				continue;
// 			}
// 			dropMineItr++;
// 		}
// 	}
// }

// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - 기존 함수를 아래와 같이 수정함.
void CFieldIOCPSocket::SendDropItems(CMapBlock *pBlock)
{
	if (pBlock == NULL){								return;}
	if(FALSE == this->IsValidCharacter(FALSE)){			return;}

	///////////////////////////////////////////////////////////////////////////////	
	// 아이템류 보내기
	if (!pBlock->m_DropItemMtmap.empty())
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_SHOW_ITEM, T_FC_ITEM_SHOW_ITEM, pShowItem, SendBuf);
		int	nSendBytes = 0;
		mt_auto_lock mtA(&pBlock->m_DropItemMtmap);
		mtmapDropItem::iterator dropItemItr = pBlock->m_DropItemMtmap.begin();
		for(; dropItemItr != pBlock->m_DropItemMtmap.end(); dropItemItr++)
		{
			DROPITEM *pDropItem = &(dropItemItr->second);

			if(FALSE == this->IsValidCharacter(FALSE))
			{
				break;
			}
			if(nSendBytes + MSG_SIZE(MSG_FC_ITEM_SHOW_ITEM) > SIZE_MAX_PACKET)
			{
// 2008-02-18 by cmkwon
// 				g_pFieldGlobal->WriteSystemLogEX(TRUE, " CFieldIOCPSocket::SendDropItems [%d][%d] 1: %s SendBytes(%d)\r\n"
// 					, pBlock->m_x, pBlock->m_z, GetCharacterString(GetCharacter(), string()), nSendBytes);
				SendAddData(SendBuf, nSendBytes);
				pShowItem		= (MSG_FC_ITEM_SHOW_ITEM*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
				nSendBytes		= 0;
			}

			// 2008-02-18 by cmkwon, 초기화 처리
			*(MessageType_t*)(SendBuf + nSendBytes)		= T_FC_ITEM_SHOW_ITEM;
			pShowItem									= (MSG_FC_ITEM_SHOW_ITEM*)(SendBuf + nSendBytes + SIZE_FIELD_TYPE_HEADER);

			// 2008-02-18 by cmkwon, 드랍 아이템 정보 설정
			pShowItem->ItemFieldIndex					= (UINT)(pDropItem->pItem);
			pShowItem->ItemNum							= pDropItem->pItem->ItemNum;
			pShowItem->FirstCharacterUID				= 0;
			pShowItem->Amount							= pDropItem->pItem->CurrentCount;
			pShowItem->Position							= pDropItem->Position;
			pShowItem->DropItemType						= DROP_ITEM_TYPE_PICKUP;

			// 2008-02-18 by cmkwon, 전송 할 데이터 증가
			nSendBytes									+= MSG_SIZE(MSG_FC_ITEM_SHOW_ITEM);
		}
		mtA.auto_unlock_cancel();

		// 2008-02-18 by cmkwon, 마지막 남은 데이터 전송
		if(this->IsValidCharacter(FALSE)
			&& 0 < nSendBytes)
		{
// 2008-02-18 by cmkwon
// 			g_pFieldGlobal->WriteSystemLogEX(TRUE, " CFieldIOCPSocket::SendDropItems [%d][%d] 2: %s SendBytes(%d)\r\n"
// 				, pBlock->m_x, pBlock->m_z, GetCharacterString(GetCharacter(), string()), nSendBytes);
			SendAddData(SendBuf, nSendBytes);
		}
	}
}


// 캐릭터의 뿌려놓은 모든 마인을 제거한다
void CFieldIOCPSocket::ClearAllCharacterMines()
{
	// lock m_setCharacDropMine
	mt_auto_lock mineLock(&m_setCharacDropMine);

	mtsetDropMine::iterator itrDropMine = m_setCharacDropMine.begin();
	while (itrDropMine != m_setCharacDropMine.end())
	{
		DROPMINE *pDropMine = *itrDropMine;

		// 지우기, 자기 자신은 제외함
		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_HIDE_ITEM, T_FC_ITEM_HIDE_ITEM, pMsgHideItem, pMsgHideItemBuf);
		pMsgHideItem->ClientIndex = 0;
		pMsgHideItem->ItemFieldIndex = (UINT)pDropMine;
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropMine->Position, pMsgHideItemBuf,
			MSG_SIZE(MSG_FC_ITEM_HIDE_ITEM),
			m_pCurrentFieldMapChannel,
			m_character.ClientIndex);

		// MapBlock 찾기
		CMapBlock *pTmpMapBlock	= m_pCurrentFieldMapChannel->GetBlock(pDropMine->Position.x, pDropMine->Position.z);

		// MapBlock에서 제거
		if (pTmpMapBlock != NULL)
		{
			BOOL ret = pTmpMapBlock->m_setMapBlockDropMine.deleteLock(pDropMine);
		}

		// 캐릭터로부터 삭제
		m_setCharacDropMine.erase(itrDropMine++);

		SAFE_DELETE(pDropMine);
	}
	m_setCharacDropMine.clearLock();								// 캐릭터의 drop mine list에서 모두 삭제
}

BOOL CFieldIOCPSocket::IsValidDropMine(DROPMINE *i_pDropMine, CMapBlock *&o_pMapBlock)
{
	o_pMapBlock = NULL;

	// lock mt_auto_lock
	mt_auto_lock mineLock(&m_setCharacDropMine);

	// 마인의 존재 여부 확인
	DROPMINE *pDropMineInCharacter = m_setCharacDropMine.findLock(i_pDropMine);
	if (pDropMineInCharacter == NULL)
	{
		return FALSE;
	}

	// m_pCurrentFieldMapChannel 확인
	if (m_pCurrentFieldMapChannel == NULL)
	{
		return FALSE;
	}

	// 마인의 위치 확인
	o_pMapBlock = m_pCurrentFieldMapChannel->GetBlock(pDropMineInCharacter->Position.x, pDropMineInCharacter->Position.z);
	if (o_pMapBlock == NULL)
	{
		return FALSE;
	}

	// MapBlock에서의 마인 존재 여부 확인
	DROPMINE *pDropMineInMapBlock = o_pMapBlock->m_setMapBlockDropMine.findLock(i_pDropMine);
	if (pDropMineInMapBlock == NULL)
	{
		return FALSE;
	}

	if (i_pDropMine != pDropMineInMapBlock || i_pDropMine != pDropMineInCharacter)
	{
		return FALSE;
	}

	// 자신이 뿌린 마인인지 확인
	if (i_pDropMine->CharacterUniqueNumber != m_character.CharacterUniqueNumber)
	{
		return FALSE;
	}

	return TRUE;
}

// 2010-03-08 by cmkwon, FieldIOCPSocket.cpp파일 2개로 나누기 - FieldIOCPSocket.h 파일로 옮김.
//#define CHARACTER_SPEED_HACK_CHECK_TERM				10000			// Speed Hack을 체크하는 시간 Term

ProcessResult CFieldIOCPSocket::Process_FC_MOVE(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	BYTE					SendBuf[SIZE_MAX_PACKET];
	CFieldIOCPSocket		*pFieldIOCPSocket	= NULL;
	const CHARACTER			*pCharacter			= NULL;

	// Client의 이동 정보를 받음
	// 응답으로 T_FC_MOVE_OK 메세지를 보낸다. Lock on 정보도 같이 보낸다.
	MSG_FC_MOVE		*pRecvMove = NULL;
	
	nRecvTypeSize = sizeof(MSG_FC_MOVE);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14022);
		return RES_RETURN_FALSE;
	}
	pRecvMove = (MSG_FC_MOVE*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(pRecvMove->ClientIndex >= ms_pFieldIOCP->GetArrayClientSize() || m_character.ClientIndex != pRecvMove->ClientIndex)
	{
		// Protocol Error 처리(Close 처리함)
		// - 유효가지 않은 Client Index
		// Error Code : ERR_PROTOCOL_INVALID_CLIENTINDEX
		// 2008-04-22 by dhjin, 통합아레나 테스트 중
		SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_INVALID_CLIENTINDEX, pRecvMove->ClientIndex);
		Close(0x14023);
		return RES_BREAK;
	}

	// game end 이후에 오는 move message를 무시한다
	if (GetClientState() !=  CS_PLAYING)
	{
		return RES_BREAK;
	}

	float		fDistanceGap = D3DXVec3Length(&(A2DX(pRecvMove->PositionVector) - m_character.PositionVector));
	CheckSpeedHack(pRecvMove->TimeGap, fDistanceGap);

	// 거래중에 일정 거리 이상 떨어지면 거래 취소한다
	if (IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		// 해당 캐릭터가 없음
		CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(m_peerTraderCharacterUniqueNumber);
		if (NULL == pTargetSocket)
		{
			SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_TOO_FAR_TO_TRADE, m_peerTraderCharacterUniqueNumber);
			SendTradeCanceledAndReset(NULL, FALSE);
			return RES_BREAK;
		}

		if (D3DXVec3Length(&(m_character.PositionVector-pTargetSocket->m_character.PositionVector)) > REQUERED_TRADE_DISTANCE)
		{
			SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_TOO_FAR_TO_TRADE);
			SendTradeCanceledAndReset(pTargetSocket, TRUE);
			return RES_BREAK;
		}
	}

	// map 밖으로 나가는 것 방지
	if (FALSE == m_pCurrentFieldMapChannel->m_pFieldMapProject->IsValidPosition((float)pRecvMove->PositionVector.x, (float)pRecvMove->PositionVector.z))
	{
		if(FALSE == m_pCurrentFieldMapChannel->DeleteBlockPosition(m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex))
		{
			char szTemp[256];
			sprintf(szTemp, "[Error] DeleteBlockPosition_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_pFieldGlobal->WriteSystemLog(szTemp);
		}
		m_pCurrentFieldMapChannel->m_mapCharacterUniqueNumberMapProject.deleteLock(m_character.CharacterUniqueNumber);
		// Protocol Error 처리(Close 처리함)
		// - 유효하지 않은 Client Index
		// Error Code : ERR_PROTOCOL_INVALID_POSITION
		SendErrorMessage(T_FC_MOVE, ERR_PROTOCOL_INVALID_POSITION, (int)m_character.PositionVector.x, (int)m_character.PositionVector.z);

		// 기본 위치로 보내고 접속을 끊는다
		m_character.PositionVector = m_pCurrentFieldMapChannel->GetDefaultPointW();

		Close(0x14025);
		return RES_BREAK;
	}
//#ifdef _DEBUG
//	DBGOUT("%s(%d): MOVE(%d, %d)\n", m_character.CharacterName, m_character.ClientIndex, (int)(pRecvMove->PositionVector.x), (int)(pRecvMove->PositionVector.z));
//#endif

// 2007-04-26 by cmkwon, 사용하지 않는 루틴임
//	///////////////////////////////////////////////////////////////////////////
//	// PK 지역 처리
//	if (m_bPKMode)
//	{
//		TILEINFO *pTileInfo
//			= m_pCurrentFieldMapChannel->m_pFieldMapProject->GetTileInfo(pRecvMove->PositionVector.x, pRecvMove->PositionVector.z);
//
//		if(pTileInfo && pTileInfo->m_bPKType == PK_TYPE_SAFE)
//		{
//			m_bPKMode = FALSE;
//			MessageType_t msgType = T_FC_BATTLE_CANCEL_PK;
//			SendAddData((BYTE*)&msgType, SIZE_FIELD_TYPE_HEADER);
//		}
//	}

	BodyCond_t &bodyCondition = m_character.BodyCondition;
	if(COMPARE_BODYCON_BIT(bodyCondition, BODYCON_EVENT_HANDLE_MASK))
	{// EVENT 처리 중인지 확인

		return RES_BREAK;
	}

///////////////////////////////////////////////////////////////////////////////
// Event 처리 중이 아닐 때	
	// check: get current time
	TimeUnit_t CurrentTick = GetTickCount();

	// 클라이언트가 Dead 상태가 아니면
	if(FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK)
		&& m_character.CurrentHP > 0
		&& GetClientState() == CS_PLAYING)
	{
		// 2015-01-27 by shchoi 워프 시 일시 무적
#ifdef S_WARP_INVINCIBLE_SHCHOI
		if(TRUE == m_bPortalInvincible){
			DWORD dwCurTiick = timeGetTime();
			if(m_InvincibleTime <= dwCurTiick){
				CParamFactor *pParamFactor = this->GetParamFactor();
				pParamFactor->pfb_BitFlag.pfb_SKILL_Invincible = FALSE;
				m_bPortalInvincible = FALSE;
				char strlog[256];
				sprintf(strlog,"[CUID : %7d, AUID : %7d, Map : %4d] Portal/Revive : Invinicible End\n",m_character.CharacterUniqueNumber,m_character.AccountUniqueNumber,m_character.MapChannelIndex.MapIndex);
//				this->SendString128(STRING_128_USER_NOTICE, "무적 해제");
			g_pFieldGlobal->WriteSystemLogEX(TRUE,strlog);
			}
		} // end 2015-01-27 by shchoi 워프 시 일시 무적
#endif
		///////////////////////////////////////////////////////////////////////
		// HP 회복 관련
		///////////////////////////////////////////////////////////////////////
		m_TimerManager.m_fSumDistanceForDPConsumption += fDistanceGap;

		///////////////////////////////////////////////////////////////////////
		// EP 소모
		///////////////////////////////////////////////////////////////////////
		m_TimerManager.m_fSumDistanceForEPConsumption += fDistanceGap;
		// 2005-07-11 by cmkwon, 기획팀 요청 - 레벨 1부터 연료 소모
		//if (m_character.Level <= 5
		//	|| IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
		// 2005-08-02 by cmkwon, 캐릭터모드에서는 연료소모가 없다
		if(m_character.CharacterMode
			|| IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex)
			|| IS_MAP_INFLUENCE_INFINITY(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피니티 맵에서도 연료 소모 없다.
		{// 튜토리얼맵이면 연료 소모가 없도록 처리
			
			m_TimerManager.m_fSumDistanceForEPConsumption = 0;
			m_TimerManager.m_EPConsumptionTimeStamp = CurrentTick;
		}
		else if(m_TimerManager.m_fSumDistanceForEPConsumption > EP_CONSUMPTION_DISTANCE
			|| CurrentTick - m_TimerManager.m_EPConsumptionTimeStamp > EP_CONSUMPTION_TIME)
		{
			// 적재량이 많으면 두 배 소모
			float fCurrentEPConsumptionWeight = 1.0f;
			if (WEIGHT_RATE_HEAVY < GetCurrentLoadagePercentage())
			{// 2007-03-09 by cmkwon, xx 초과(xx 이상으로 수정함)
				fCurrentEPConsumptionWeight *= 2.0f;
			}

			// 부스터 상태이면 두 배 소모
			if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_BOOSTER3_MASK))
			{
				fCurrentEPConsumptionWeight *= 2.0f;
			}

			ChangeCurrentEP(-fCurrentEPConsumptionWeight*EP_CONSUMPTION_VALUE*(m_TimerManager.m_fSumDistanceForEPConsumption/EP_CONSUMPTION_DISTANCE));

			// 움직인 거리 및 시간 초기화
			m_TimerManager.m_fSumDistanceForEPConsumption = 0;
			m_TimerManager.m_EPConsumptionTimeStamp = CurrentTick;

			if (m_character.CurrentEP <= 0)
			{
				// EP가 다 소모됨, 정지시킴
				m_character.CurrentEP = 0;
				// check: 정지시키는 거 구현하기
			}
		}

// 2004-10-26 by cmkwon, 현재는 사용하지 않는 기능임
//		///////////////////////////////////////////////////////////////////////////////
//		// 자신이 공격하고 있는 몬스터인덱스 리스트를 체크한다
//			CheckAttackTargetIndexVector();


		InfluenceWarCheckInvasion();
	}

	// 맵(range) 관련
	BOOL			bInvalidMapTransition = FALSE;
	D3DXVECTOR3		Vec3BeforePosition = m_character.PositionVector;
	m_character.PositionVector = A2DX(pRecvMove->PositionVector);
	D3DXVec3Normalize(&m_character.TargetVector, &(A2DX(pRecvMove->TargetVector)));
	m_character.UpVector = A2DX(pRecvMove->UpVector);

	BOOL bBlockUpdated = m_pCurrentFieldMapChannel->UpdateBlockPosition(Vec3BeforePosition.x, Vec3BeforePosition.z,
		m_character.PositionVector.x, m_character.PositionVector.z, m_character.ClientIndex);
	
	if (bBlockUpdated)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 주위에 떨어져 있는 아이템 정보 보내기
		CMapBlock *oldBlock, *newBlock, *pTmpBlock;
		oldBlock = m_pCurrentFieldMapChannel->GetBlock(Vec3BeforePosition.x, Vec3BeforePosition.z);
		newBlock = m_pCurrentFieldMapChannel->GetBlock(m_character.PositionVector.x, m_character.PositionVector.z);

		int xDiff = newBlock->m_x - oldBlock->m_x;
		int zDiff = newBlock->m_z - oldBlock->m_z;

		if (0 == xDiff && 0 != zDiff)
		{
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x-1, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+1, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
		}
		else if (0 != xDiff && 0 == zDiff)
		{
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z-1);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z+1);
			SendDropItems(pTmpBlock);
		}
		else if (1 == xDiff*xDiff && 1 == zDiff*zDiff)
		{
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x+xDiff, newBlock->m_z-zDiff);
			SendDropItems(pTmpBlock);
			pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(newBlock->m_x-xDiff, newBlock->m_z+zDiff);
			SendDropItems(pTmpBlock);
		}
		else
		{
			// 1 block 이상의 이동
			bInvalidMapTransition = TRUE;
#ifdef _DEBUG
			SendString128(STRING_128_ADMIN_CMD, "JUMP (%d, %d)->(%d, %d)"
				, oldBlock->m_x, oldBlock->m_z, newBlock->m_x, newBlock->m_z);
#endif

			if (!COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER|RACE_MONITOR))
			{
				// not reachable
				char szSystemLog[256];
				sprintf(szSystemLog, "Unbelievable Map Block Transition: (%d, %d)->(%d, %d) %s\r\n"
					,oldBlock->m_x, oldBlock->m_z, newBlock->m_x, newBlock->m_z, GetCharacterString(&m_character, string()) );
				g_pFieldGlobal->WriteSystemLog(szSystemLog);
				DBGOUT(szSystemLog);
			}
		}
		// 주위에 떨어져 있는 아이템 정보 보내기_end
		///////////////////////////////////////////////////////////////////////////////
		
		///////////////////////////////////////////////////////////////////////////////
		// 주위에 떨어져 있는 마인 정보 보내기
		if (bInvalidMapTransition)
		{// 1 block 이상의 transition
			
			SendDropItemsAroundPosition(A2DX(pRecvMove->PositionVector));
		}
		else
		{// 정상적인 transition

			TWO_BLOCK_INDEXES	blockIdx;
			CMapBlock		*pTmpBlock;
			short			tempoX, tempoZ;

			m_pCurrentFieldMapChannel->m_pFieldMapProject->GetBlockAdjacentToPositionHalfDistance(pRecvMove->PositionVector.x
				, pRecvMove->PositionVector.z
				, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW(), blockIdx);

			tempoX = blockIdx.sMinX; tempoZ = blockIdx.sMinZ;
			while(tempoX <= blockIdx.sMaxX)
			{
				pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(tempoX, tempoZ);
				SendDropItems(pTmpBlock);
				tempoX++;
			}
			while(tempoZ <= blockIdx.sMaxZ)
			{
				pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(tempoX, tempoZ);
				SendDropItems(pTmpBlock);
				tempoZ++;
			}

			tempoX = blockIdx.sMinX; tempoZ = blockIdx.sMinZ;
			while(tempoZ <= blockIdx.sMaxZ)
			{
				pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(tempoX, tempoZ);
				SendDropItems(pTmpBlock);
				tempoZ++;
			}
			while(tempoX <= blockIdx.sMaxX)
			{
				pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(tempoX, tempoZ);
				SendDropItems(pTmpBlock);
				tempoX++;
			}
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// NPC 서버에 캐릭터 이동 정보 전송
	if(FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK)
		&& m_character.HP > 0
		&& GetClientState() == CS_PLAYING)
	{	// 클라이언트가 Dead 상태가 아니면
		// 클라이언트의 이동 정보를 NPC 서버에 전송한다.

		INIT_MSG(MSG_FN_MOVE_OK, T_FN_MOVE_OK, pSendMoveOK, SendBuf);
		pSendMoveOK->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
		pSendMoveOK->ClientIndex	= m_character.ClientIndex;
		pSendMoveOK->PositionVector	= m_character.PositionVector;
		pSendMoveOK->TargetVector	= m_character.TargetVector*1000.0f;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_MOVE_OK));
	}

	///////////////////////////////////////////////////////////////////////////////
	// 주위 캐릭터에게 이동 정보 전송
// 2006-11-08 by cmkwon, 아래와 같이 수정함(IsInvisibleCharacter 변수로 처리 함)
//	if(FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_STEALTH_MASK)
	if(FALSE == this->IsInvisibleCharacter()
		&& FALSE == IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{
		// Send Move OK
		INIT_MSG(MSG_FC_MOVE_OK, T_FC_MOVE_OK, msgMoveOK, SendBuf);
		msgMoveOK->ClientIndex		= m_character.ClientIndex;
// 2007-03-29 by cmkwon, 아래와 같이 비트플래그 변수 추가함
//		msgMoveOK->CharacterMode0	= m_character.CharacterMode;
		msgMoveOK->moveBitFlag		= this->Get_MSG_FC_MOVE_BIT_FLAG();		
		msgMoveOK->PositionVector	= m_character.PositionVector;
		msgMoveOK->TargetVector		= m_character.TargetVector*1000.0f;
		msgMoveOK->UpVector			= m_character.UpVector;
// 2005-09-23 by cmkwon		
//		this->m_mtvectClientIdxForSend.lock();
//		this->m_mtvectClientIdxForSend.clear();
//		this->m_mtvectClientIdxForExcludeSend.clear();
//		{
//			m_dwSendCountsMoveOK++;
//			ms_pFieldIOCP->SendInRangeCharacterMoveOK(this, SendBuf, MSG_SIZE(MSG_FC_MOVE_OK)
//				, m_pCurrentFieldMapChannel, m_dwSendCountsMoveOK);
//		}
//		this->m_mtvectClientIdxForSend.unlock();
		m_dwSendCountsMoveOK++;
			
		//////////////////////////////////////////////////////////////////////////
		// 2007-04-26 by dhjin,	아레나 맵이면 맵에 있는 유저에게 위치 정보를 모두 보낸다.
		if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{
			ms_pFieldIOCP->SendInArenaCharacterMoveOK(this, SendBuf, MSG_SIZE(MSG_FC_MOVE_OK)
				, m_pCurrentFieldMapChannel, m_dwSendCountsMoveOK);
		}
		else if(IS_MAP_INFLUENCE_INFINITY(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())) {
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피니티에서도 모두 보냄.
			m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_MOVE_OK));
		}
		else
		{
			ms_pFieldIOCP->SendInRangeCharacterMoveOK(this, SendBuf, MSG_SIZE(MSG_FC_MOVE_OK)
				, m_pCurrentFieldMapChannel, m_dwSendCountsMoveOK);
		}

	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MOVE_LOCKON(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_LOCKON
		, MSG_FC_MOVE_LOCKON, pRLockOn);

	if(m_character.ClientIndex != pRLockOn->AttackIndex
		|| pRLockOn->AttackIndex == pRLockOn->TargetIndex)
	{
		SendErrorMessage(T_FC_MOVE_LOCKON, ERR_PROTOCOL_INVALID_CLIENTINDEX, pRLockOn->AttackIndex, pRLockOn->TargetIndex);
		return RES_BREAK;
	}

	if(FALSE == IS_VALID_CLIENT_INDEX(pRLockOn->TargetIndex))
	{
		return RES_BREAK;
	}	

	CFieldIOCPSocket *pTargFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRLockOn->TargetIndex);
	if(NULL == pTargFISock
		|| FALSE == pTargFISock->IsUsing())
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 타겟으로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_LOCKON_OK, T_FC_MOVE_LOCKON_OK, pSOK, SendBuf);
	STRNCPY_MEMSET(pSOK->AttackCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pSOK->AttackIndex	= pRLockOn->AttackIndex;
	pSOK->TargetIndex	= pRLockOn->TargetIndex;
	pTargFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_LOCKON_OK));
	
	///////////////////////////////////////////////////////////////////////////////
	// 자신에게 전송
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_LOCKON_OK));
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_UNLOCKON(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_UNLOCKON
		, MSG_FC_MOVE_UNLOCKON, pRUnlockOn);

	if(m_character.ClientIndex != pRUnlockOn->AttackIndex
		|| pRUnlockOn->AttackIndex == pRUnlockOn->TargetIndex)
	{
		SendErrorMessage(T_FC_MOVE_UNLOCKON, ERR_PROTOCOL_INVALID_CLIENTINDEX, pRUnlockOn->AttackIndex, pRUnlockOn->TargetIndex);
		return RES_BREAK;
	}

	if(FALSE == IS_VALID_CLIENT_INDEX(pRUnlockOn->TargetIndex))
	{
		return RES_BREAK;
	}	

	CFieldIOCPSocket *pTargFISock = ms_pFieldIOCP->GetFieldIOCPSocket(pRUnlockOn->TargetIndex);
	if(NULL == pTargFISock
		|| FALSE == pTargFISock->IsUsing())
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 타겟으로 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_UNLOCKON_OK, T_FC_MOVE_UNLOCKON_OK, pSOK, SendBuf);
	STRNCPY_MEMSET(pSOK->AttackCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pSOK->AttackIndex	= pRUnlockOn->AttackIndex;
	pSOK->TargetIndex	= pRUnlockOn->TargetIndex;
	pTargFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_UNLOCKON_OK));
	
	///////////////////////////////////////////////////////////////////////////////
	// 자신에게 전송
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_UNLOCKON_OK));
	return RES_RETURN_TRUE;
}

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

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

	TILEINFO *pTileInfo = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetTileInfo(&m_character.PositionVector);
	if (pTileInfo == NULL)
	{
		SendErrorMessage(T_FC_MOVE_LANDING, ERR_PROTOCOL_INVALID_POSITION);
		return RES_BREAK;
	}

	if (FALSE == pTileInfo->m_bEnableLand)
	{
		return RES_BREAK;
	}

	// 전송
	*(MessageType_t*)SendBuf = T_FC_MOVE_LANDING_OK;

	MSG_FC_MOVE_LANDING_OK *pSendMsgLandingOK = (MSG_FC_MOVE_LANDING_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
	pSendMsgLandingOK->Position.x = pRecvMsgLanding->Position.x;
	pSendMsgLandingOK->Position.y = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetMapHeightIncludeWater(&A2DX(pRecvMsgLanding->Position));
	pSendMsgLandingOK->Position.z = pRecvMsgLanding->Position.z;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_LANDING_OK));

	// Send BODYCON_LANDING_MASK, 자기 자신에게도 보냄
	SetBodyConditionBit(m_character.BodyCondition, BODYCON_LANDING_MASK);
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_BOOSTER_EX_STATE_CLEAR_MASK);

	INIT_MSG(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, SendBuf);
	pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
	pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION)
		, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
	return RES_RETURN_TRUE;
}

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

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

	// check: DT는 착륙 상태의 개념이 다르므로 MSG_FC_MOVE_LANDING 을 보내지 않고
	// 바로 MSG_FC_MOVE_LANDING_DONE을 보낸다. 따라서 다른 기종과는 달리 아래와
	// 같이 여기서 착륙 상태로 만들어준다. 20031102, kelovon with jinking

	SetBodyConditionBit(m_character.BodyCondition, BODYCON_LANDED_MASK);
	ClearBodyConditionBit(m_character.BodyCondition, BODYCON_BOOSTER_EX_STATE_CLEAR_MASK);
	
	INIT_MSG(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, SendBuf);
	pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
	pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION)
		, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);	// HP 회복 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);	// DP 회복 시작
	m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);	// SP 회복 시작

// 2005-08-02 by cmkwon, 착륙시는 아무것도 처리하지 않는다. 대신 캐릭터모드로 변경시에 처리한다.
//	TILEINFO *pTile = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetTileInfo(&A2DX(pRecvMsgLandingDone->Position));
//	if ( m_pCurrentFieldMapChannel->m_pFieldMapProject->m_bAutoDPRecovery
//		 || (pTile && pTile->m_bEnableLand)
//		 )
//	{// 자동회복 맵이거나 착륙지역 안에서 착륙 할 경우
//		m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_HP);
//		m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_DP);
//		m_TimerManager.CheckRecoveryTimer(TE_TYPE_RECOVER_SP);
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 1형, 2형 총알을 가득 채워 준다.
//		// 2005-06-29 by cmkwon,
//		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);}
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 연료를 가득 채워 준다.
//		if(m_character.CurrentEP < m_character.EP)
//		{
//			m_character.CurrentEP	= m_character.EP;
//			SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
//		}	
//	}
//
//
	if(IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex)
		|| IS_BAZAAR_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{// 2006-07-20 by cmkwon, P2P PK 중이거나 바자맵일경우 상점 못 들어 감
		return RES_BREAK;
	}

	// Enter Building Event 등 처리
	EVENTINFO *pEventInfo = m_pCurrentFieldMapChannel->GetTileEventInfoW(&A2DX(pRecvMsgLandingDone->Position));
	if ( NULL == pEventInfo
		|| pEventInfo->m_bEventType != EVENT_TYPE_ENTER_BUILDING)
	{
		return RES_BREAK;
	}
// 2006-07-20 by cmkwon, 필요 없는 부분인것 같음 
// 	// building에서 나왔을 때 target vector 결정
// 	D3DXVec3Normalize(&m_character.TargetVector, &-m_character.TargetVector);
// 
// 	// building에서 나왔을 때 position vector 결정
// 	D3DXVECTOR3 vTmp = m_character.PositionVector + (40 * m_character.TargetVector);
// 	m_pCurrentFieldMapChannel->UpdateBlockPosition(m_character.PositionVector, vTmp, m_character.ClientIndex);
// 	m_character.PositionVector = vTmp;

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_MOVE_LANDING_DONE, 현재 상점을 사용중 이라면 아래의 이벤트 체크는 하지 않는다.
	if(m_pCurrentBuildingNPC)
	{
		return RES_BREAK;
	}

	// MSG_FC_EVENT_ENTER_BUILDING 전송
	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pEventInfo->m_EventwParam1);
	if(NULL == pBuildingNPC)
	{
		return RES_BREAK;
	}

	INIT_MSG(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, SendBuf);
	pMsgEnterBuilding->BuildingNPCInfo				= *pBuildingNPC;
// 2006-02-08 by cmkwon
//		pMsgEnterBuilding->fCityWarTexRate				= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pBuildingNPC->BuildingIndex, m_character.GuildUniqueNumber);
	pMsgEnterBuilding->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));

	return RES_RETURN_TRUE;
}

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

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

/*
	if (!COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_LANDED_MASK))
	{
		// 착륙 상태가 아님!
		SendErrorMessage(T_FC_MOVE_TAKEOFF, ERR_PROTOCOL_INVALID_BODYCONDITION, 0, 0, m_character.CharacterName);
		return RES_BREAK;
	}
*/

	// 전송
	*(MessageType_t*)SendBuf = T_FC_MOVE_TAKEOFF_OK;
	MSG_FC_MOVE_TAKEOFF_OK *pSendMsgTakeOffOK = (MSG_FC_MOVE_TAKEOFF_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
	pSendMsgTakeOffOK->Position.x = pRecvMsgTakeoff->Position.x;
	pSendMsgTakeOffOK->Position.y = HEIGHT_FLYING_ALTITUDE;
	pSendMsgTakeOffOK->Position.z = pRecvMsgTakeoff->Position.z;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_TAKEOFF_OK));

	// Body Condition 설정
	SetBodyConditionBit(m_character.BodyCondition, BODYCON_FLY_MASK);
	SetBodyConditionBit(m_character.BodyCondition, BODYCON_BOOSTER1_MASK);

	INIT_MSG(MSG_FC_CHARACTER_CHANGE_BODYCONDITION, T_FC_CHARACTER_CHANGE_BODYCONDITION, pMsgChangeBodyConClient, SendBuf);
	pMsgChangeBodyConClient->ClientIndex = m_character.ClientIndex;
	pMsgChangeBodyConClient->BodyCondition = m_character.BodyCondition;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_BODYCONDITION)
		, m_pCurrentFieldMapChannel, FALSE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MOVE_TARGET(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize	= 0;
	MSG_FC_MOVE_TARGET		*pRecvMoveTarget = NULL;

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

	
	CFieldIOCPSocket *pFSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pRecvMoveTarget->ClientIndex);
	if(NULL == pFSocket
		|| FALSE == pFSocket->IsValidCharacter(FALSE))
	{
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_OK, T_FC_MOVE_OK, pSMoveOK, SendBuf);
	pSMoveOK->ClientIndex		= m_character.ClientIndex;
// 2007-03-29 by cmkwon, 아래와 같이 비트플래그 변수 추가함
//	pSMoveOK->CharacterMode0	= m_character.CharacterMode;
	pSMoveOK->moveBitFlag		= this->Get_MSG_FC_MOVE_BIT_FLAG();	
	pSMoveOK->PositionVector	= m_character.PositionVector;
	pSMoveOK->TargetVector		= m_character.TargetVector*1000.0f;
	pSMoveOK->UpVector			= m_character.UpVector;
	pFSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_MOVE_OK));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MOVE_WEAPON_VEL(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_WEAPON_VEL,
									MSG_FC_MOVE_WEAPON_VEL, pMsgWeaponVel);

	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_WEAPON_VEL_OK, T_FC_MOVE_WEAPON_VEL_OK, pMsgWeaponVelOK, pMsgWeaponVelOKBuf);
	pMsgWeaponVelOK->ClientIndex = m_character.ClientIndex;
	pMsgWeaponVelOK->WeaponVel = pMsgWeaponVel->WeaponVel;
	pMsgWeaponVelOK->PetLeftVel		= pMsgWeaponVel->PetLeftVel;
	pMsgWeaponVelOK->PetRightVel	= pMsgWeaponVel->PetRightVel;
	SendInRangeMessageAroundMe(pMsgWeaponVelOKBuf, MSG_SIZE(MSG_FC_MOVE_WEAPON_VEL_OK), FALSE);

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_ROLLING(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_ROLLING,
									MSG_FC_MOVE_ROLLING, pRRolling);
	CParamFactor *pPFactor = this->GetParamFactor();

	if (ROLLING_USE_CONSUMPTION_SP > m_character.CurrentSP)
	{// SP 확인

		SendErrorMessage(T_FC_MOVE_ROLLING, ERR_PROTOCOL_NOT_ENOUGH_SP, ROLLING_USE_CONSUMPTION_SP, m_character.CurrentSP, NULL, FALSE, FALSE);
		return RES_BREAK;		
	}


	//////////////////////////////////////////////////////////////////////////
	// 2006-11-17 by dhjin, 체인롤링 스킬중이면 롤링 재사용 시간없이 사용할 수 있다.
	if(FALSE == this->CheckSKILLChainRolling())
	{
		DWORD dwCurTick = timeGetTime();
		DWORD dwElapseTick = dwCurTick - this->m_dwLastTickRolling;
		if(dwElapseTick < ROLLING_USE_INTERVAL_TICK)
		{
			SendErrorMessage(T_FC_MOVE_ROLLING, ERR_PROTOCOL_NOT_ENOUGH_ELAPSE_TIME, ROLLING_USE_CONSUMPTION_SP, m_character.CurrentSP, NULL, FALSE, FALSE);
			return RES_BREAK;
		}
		this->m_dwLastTickRolling	= dwCurTick;
	}
// 2005-11-22 by cmkwon
//	this->ChangeCurrentSP(-ROLLING_USE_CONSUMPTION_SP);		// SP 소모
	this->DecreaseCurrentSP(ROLLING_USE_CONSUMPTION_SP);

	///////////////////////////////////////////////////////////////////////////////
	// 2005-07-07 by cmkwon, 주위 캐릭터에게 전송한다.
	INIT_MSG_WITH_BUFFER(MSG_FC_MOVE_ROLLING_OK, T_FC_MOVE_ROLLING_OK, pSRollingOK, SendBuf);
	pSRollingOK->ClientIndex			= m_character.ClientIndex;
	pSRollingOK->PositionAVec3			= pRRolling->PositionAVec3;
	pSRollingOK->TargetAVec3			= pRRolling->TargetAVec3;
	pSRollingOK->UpAVec3				= pRRolling->UpAVec3;
	pSRollingOK->byLeftDirectionFlag	= pRRolling->byLeftDirectionFlag;
	this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_MOVE_ROLLING_OK), TRUE);
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_GuidAckMsg(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-05 ~ 2006-06-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_GuidAckMsg(const char* pPacket, int nLength, int &nBytesUsed)
{
// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 사용하지 않음
// 	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_HACKSHIELD_GuidAckMsg,
// 									MSG_FC_MOVE_HACKSHIELD_GuidAckMsg, pRGuidAckMsg);
// 
// 	this->SecurityCheckVersion(pRGuidAckMsg);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_CRCAckMsg(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-05 ~ 2006-06-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_CRCAckMsg(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_HACKSHIELD_CRCAckMsg,
									MSG_FC_MOVE_HACKSHIELD_CRCAckMsg, pRAckMsg);

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{// 2008-03-24 by cmkwon, 핵쉴드 2.0 적용 - 체크 추가
		return RES_BREAK;
	}

	// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 아래와 같이 수정함
	//this->SecurityCheckClient_1(pRAckMsg);
	this->SecurityClientCheck(pRAckMsg);	// 2008-04-03 by cmkwon, 핵쉴드 서버 연동 시스템 수정 - 
	return RES_RETURN_TRUE;
}
///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_HACKING_CLIENT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-06-05 ~ 2006-06-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_HACKSHIELD_HACKING_CLIENT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_HACKSHIELD_HACKING_CLIENT,
									MSG_FC_MOVE_HACKSHIELD_HACKING_CLIENT, pRHackingClient);

	CAtumLogSender::SendLogMessageHackingLog(this, pRHackingClient->lHackingClinetCode, pRHackingClient->szErrString);
	SendErrorMessage(T_FC_MOVE_HACKSHIELD_HACKING_CLIENT, ERR_SECURITY_HACKING_CLIENT, pRHackingClient->lHackingClinetCode, 0, NULL, TRUE);
	this->Close(0x14066, FALSE, 3000);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
/// \author		cmkwon
/// \date		2008-11-28 ~ 2008-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK,
		MSG_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK, pRMsg);

	Err_t errCode = this->SecurityXignCodeInit(pRMsg);
	if(ERR_NO_ERROR != errCode)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] SecurityXignCodeInit# error !! %s, %s(%d)\r\n"
			, GetCharacterString(this->GetCharacter(), string()), GetErrorString(errCode), errCode);

		CAtumLogSender::SendLogMessageHackingLog(this, errCode);
		SendErrorMessage(T_FC_MOVE_XIGNCODE_REQ_SCAN_INIT_OK, errCode, 0, 0, NULL, TRUE); 
		this->Close(0x14067, FALSE, 3000);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-11-28 by cmkwon, 대만 Netpower_Tpe XignCode(게임가드) 적용 - 
/// \author		cmkwon
/// \date		2008-11-28 ~ 2008-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK,
		MSG_FC_MOVE_XIGNCODE_REQ_SCAN_CHECK_OK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{// 2008-11-28 by cmkwon, 체크 추가
		return RES_BREAK;
	}
	
	this->SecurityClientCheck((MSG_FC_MOVE_HACKSHIELD_CRCAckMsg*)pRMsg);	// 2008-11-28 by cmkwon

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2015-01-05 by shchoi GameForge 게임가드 nProtect로 변경
/// \author		shchoi
/// \date	
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK,
		MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))
	{
		return RES_BREAK;
	}
	
	this->SecurityClientCheck_GFNP((MSG_FC_MOVE_NPROTECT_NEW_REQ_AUTH_DATA_OK*)pRMsg);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-03-09 by cmkwon, 일본 Arario nProtect에 CS인증 적용하기 - 
/// \author		cmkwon
/// \date		2009-03-09 ~ 2009-03-09
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK,
		MSG_FC_MOVE_NPROTECT_REQ_AUTH_DATA_OK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{// 2009-03-09 by cmkwon
		return RES_BREAK;
	}
	
	this->SecurityClientCheck((MSG_FC_MOVE_HACKSHIELD_CRCAckMsg*)pRMsg);	// 2009-03-09 by cmkwon, 체크 호출
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-10-06 by cmkwon, 베트남 게임 가드 X-TRAP으로 변경 -
/// \author		cmkwon
/// \date		2009-10-07 ~ 2009-10-07
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_XTRAP_REQ_STEP_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_XTRAP_REQ_STEP_OK,
		MSG_FC_MOVE_XTRAP_REQ_STEP_OK, pRMsg);

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))		// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{// 2009-03-09 by cmkwon
		return RES_BREAK;
	}
	
	this->SecurityClientCheck((MSG_FC_MOVE_HACKSHIELD_CRCAckMsg*)pRMsg);	// 2009-10-07 by cmkwon, 체크 호출
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2009-11-04 by cmkwon, 태국 게임가드 Apex로 변경 - 
/// \author		cmkwon
/// \date		2009-11-04 ~ 2009-11-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_MOVE_APEX_REQ_APEXDATA_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_MOVE_APEX_REQ_APEXDATA_OK,
		MSG_FC_MOVE_APEX_REQ_APEXDATA_OK, pRMsg);

// 2010-04-22 by cmkwon
//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[TEMP] 100422 CFieldIOCPSocket::Process_FC_MOVE_APEX_REQ_APEXDATA_OK# %s ValidCharacter(%d) \r\n"
//		, GetCharacterString(GetCharacter(), string()), this->IsValidCharacter(FALSE, TRUE));

	if(FALSE == this->IsValidCharacter(FALSE, TRUE))	// 2010-04-22 by cmkwon, 아레나 플레이 상태도 유효한 캐릭터로 처리 - 
	{// 2009-03-09 by cmkwon
		return RES_BREAK;
	}
	
	this->SecurityClientCheck((MSG_FC_MOVE_HACKSHIELD_CRCAckMsg*)pRMsg);
	return RES_RETURN_TRUE;
}


BYTE CFieldIOCPSocket::CalcDamageKind(float fDistance, float fDistanceVar)
{
	// A-GEAR인 경우는 검사 안 함
	if (IS_AGEAR(m_character.UnitKind))
	{
		return DAMAGEKIND_NORMAL;
	}

	if(fDistance < 0.0f || fDistance > DAMAGE_KIND_ANGLE_DISTANCE + fDistanceVar)
	{
		return DAMAGEKIND_NO_DAMAGE;
	}
	else
	{
		return DAMAGEKIND_NORMAL;
	}
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ATTACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_ATTACK,
									MSG_FC_BATTLE_ATTACK, pMsgAttack);

	// 각종 변수 준비
	ITEM				*pAttackItem		= NULL;
	ITEM_GENERAL		*pAttackItemGeneral	= NULL;
	enumAttackToTarget	eAttack2Target		= ERR2ERR;
	CFieldIOCPSocket	*pTargetSocket		= NULL;
	CHARACTER			*pTargetCharacter	= NULL;
	CFieldMonster		*pTargetMonster		= NULL;

	float				fDistance			= 0.0f;		// 공격자와 공격대상과의 거리를 저장
	float				fSkillAppliedRange	= 0.0f;		// 보정값 적용된 공격 범위 저장
	float				fDamage				= 0.0f;		// 최종 데미지
	BYTE				DamageKind			= DAMAGEKIND_NORMAL;
	INT					temp_Petattack		= 0;		// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리(변수 추가)
	
	ITEM				*pITEMforProcessSplashAttack = NULL;	// 2006-12-01 by dhjin,
	D3DXVECTOR3			tmVecTargetPos		= A2DX(pMsgAttack->TargetInfo.TargetPosition);
		
	// 공격자가  유효한지 체크
	if (FALSE == this->IsValidCharacter()
		|| COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
	{
		return RES_BREAK;
	}

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사일런트 디버프 체크, 상위에서 체크한다.
	if( (this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_SILENCE_PRIMARY)
		&& IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType) ) 
		|| (this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_SILENCE_SECOND)
			&& IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType) )
		) {
		SendErrorMessage(T_FC_BATTLE_ATTACK, ERR_DEBUFF_SKILL_APPLYING_SLIENCE);
		return RES_BREAK;
	}
	///////////////////////////////////////////////////////////////////////////////
	// 2006-12-01 by dhjin
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

	//////////////////////////////////////////////////////////////////////////
	// 2007-07-16 by dhjin, Tutorial 맵이면 전용 무기 할당.
	if(IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{
		pAttackItem = GetTutorialWeaponInfo(pMsgAttack->AttackType);
		if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
		{
			return RES_BREAK;
		}
	}	
	else
	{
		// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리(처리 변경)
		// Attack Item 할당 및 확인
		if (IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType))
		{				
			pAttackItem = &m_ItemProwOut; 
			pAttackItemGeneral	= (ITEM_GENERAL*)pAttackItem->ItemNum;

			// 2010. 11. 23. by hsLee.	pAttackItemGeneral 포인터 NULL 관련 체크 추가.
			//pAttackItem			= pAttackItemGeneral->ItemInfo;				// 2007-02-06 by cmkwon, 장착 아이템의 포인터를 lock과 상관없는 포인터로 변경한다.
			if ( pAttackItemGeneral )
				pAttackItem = pAttackItemGeneral->ItemInfo;
			// End 2010. 11. 23. by hsLee.	pAttackItemGeneral 포인터 NULL 관련 체크 추가.
		}
		else if (IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType)) 
		{
			pAttackItem = &m_ItemWingOut; 
			pAttackItemGeneral	= (ITEM_GENERAL*)pAttackItem->ItemNum;

			// 2010. 11. 23. by hsLee.	pAttackItemGeneral 포인터 NULL 관련 체크 추가.
			//pAttackItem			= pAttackItemGeneral->ItemInfo;				// 2007-02-06 by cmkwon, 장착 아이템의 포인터를 lock과 상관없는 포인터로 변경한다.
			if ( pAttackItemGeneral )
				pAttackItem = pAttackItemGeneral->ItemInfo;
			// End 2010. 11. 23. by hsLee.	pAttackItemGeneral 포인터 NULL 관련 체크 추가.
		}
		
		if(ATT_TYPE_PET_ATK == pMsgAttack->AttackType)
		{
			temp_Petattack = ms_pFieldIOCP->m_cPetDataManager.GetPetLevelDataFromAttackItemNum(m_ItemPet.LinkItem,m_ItemPet.SkillLevel);
			pAttackItem = ms_pFieldIOCP->GetItemInfo( temp_Petattack );
			//pAttackItemGeneral	= (ITEM_GENERAL*)pAttackItem->ItemNum;
			//pAttackItem			= pAttackItemGeneral->ItemInfo;
			// 2010-11-01 by jskim, 펫 데미지 View 변경
			DamageKind			= DAMAGEKIND_PET;
			// end 2010-11-01 by jskim, 펫 데미지 View 변경
		} //펫 공격 1형 무기 아이템 정보

		// end 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리(처리 변경)
		if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
		{
			return RES_BREAK;
		}
		//pAttackItemGeneral	= (ITEM_GENERAL*)pAttackItem->ItemNum;
		//pAttackItem			= pAttackItemGeneral->ItemInfo;				// 2007-02-06 by cmkwon, 장착 아이템의 포인터를 lock과 상관없는 포인터로 변경한다.
	}

	// MSG_FC_BATTLE_ATTACK_OK 준비
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pMsgAttackOK, pMsgAttackOKBuf);
	pMsgAttackOK->AttackIndex		= m_character.ClientIndex;
	pMsgAttackOK->TargetInfo		= pMsgAttack->TargetInfo;
	pMsgAttackOK->FirePosition		= pMsgAttack->FirePosition;
	pMsgAttackOK->WeaponIndex		= m_WeaponIndexGenerator.GetNext();
	pMsgAttackOK->AttackType		= pMsgAttack->AttackType;
	pMsgAttackOK->ItemNum			= pAttackItem->ItemNum;
	pMsgAttackOK->SkillNum			= pMsgAttack->SkillNum;
	pMsgAttackOK->TargetInfo.MultiTargetIndex = pMsgAttack->TargetInfo.MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
//	pMsgAttackOK->RemainedBulletFuel= ;	// OnXXXAttack() 이후에 할당

 
	// AttackToTarget 결정
	eAttack2Target = CAtumSJ::GetAttackToTarget(m_character.ClientIndex, pMsgAttack->TargetInfo);
	if (eAttack2Target == ERR2ERR)
	{
		return RES_BREAK;
	}

	// 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화
	if ( DAMAGEKIND_NORMAL == DamageKind )
	{
		switch(eAttack2Target)
		{
		case C2C:
		case C2M:
		case C2I:
		case C2CI:
			{
				D3DXVECTOR3 tsetTargetPosition = tmVecTargetPos;
				int	AttackDistance = (int)D3DXVec3Length(&(tsetTargetPosition - m_character.PositionVector));
				int	AttackPossibleRange = 0;

				if ( IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType) )
				{
					AttackPossibleRange = (int)max(0.1f, m_ItemProw.AbilityMin*(1.0f+m_ParamFactor.pfm_RANGE_01+m_ParamFactor.pfm_ATTACK_RANGE_01));
				}
				else if ( IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType) ) 
				{
					AttackPossibleRange = (int)max(0.1f, m_ItemProw.AbilityMax*(1.0f+m_ParamFactor.pfm_RANGE_02+m_ParamFactor.pfm_ATTACK_RANGE_02));
				}
//				SendString128(STRING_128_ADMIN_CMD, "사거리:%.4f,  공격거리:%.4f", fAttackRange, testfDist);

				if ( 100 <= AttackDistance - AttackPossibleRange )
				{
//					SendString128(STRING_128_ADMIN_CMD, "버그쓰냐?? 블락당해볼텨??");
					g_pFieldGlobal->WriteSystemLogEX(FALSE, "[HACK_USER] AttackRange Hacking _ AUID(%d) CUID(%d) AttackPossibleRange(%d) AttackDistance(%d)\r\n"
						, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber, AttackPossibleRange, AttackDistance);
					return RES_BREAK;
				}
			}
			break;
		default:
			break;
		}
	}
	// end 2014-02-05 by jhseol, 캐나다 공격위조 메모리핵 보안강화

	///////////////////////////////////////////////////////////////////////////////
	// 2006-01-20 by cmkwon, 세력전 보스 몬스터 공격 메시지 
	if(C2M == eAttack2Target)
	{
		CFieldMonster *pFMon = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(m_character.MapChannelIndex.ChannelIndex, pMsgAttack->TargetInfo.TargetIndex, 110);
		if(pFMon
			&& MS_PLAYING == pFMon->m_enMonsterState
			&& COMPARE_MPOPTION_BIT(pFMon->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER)
			// 2007-08-23 by cmkwon, 모선전 보스 몬스터 구분 처리 - 아래와 같이 수정함, 추가된 디파인 사용
			//&& IS_INFLWAR_MONSTER(pFMon->MonsterInfoPtr->Belligerence)
			&& IS_MOTHERSHIPWAR_MONSTER(pFMon->MonsterInfoPtr->Belligerence)
			&& FALSE == COMPARE_BODYCON_BIT(pFMon->BodyCondition, BODYCON_DEAD_MASK))
		{
			DWORD		dwCurTick = timeGetTime();
			if(dwCurTick - pFMon->m_dwLastTickInfluenceBossAttackedMsg > TICKGAP_SEND_INVASION_MSG)
			{
				pFMon->m_dwLastTickInfluenceBossAttackedMsg		= dwCurTick;

				INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION, T_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION, pSInvasion, Sendbuf);
				pSInvasion->MonsterUnitkind		= pFMon->MonsterInfoPtr->MonsterUnitKind;
				ms_pFieldIOCP->SendMessageToAllClients(Sendbuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION), GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(pFMon->MonsterInfoPtr->Belligerence));
			}
		}			

		///////////////////////////////////////////////////////////////////////////////
		// 2009-12-11 by cmkwon, 데미지 어그로로 타겟을 변경하는 몬스터 구현 - 
		if(pFMon && pFMon->IsValidMonster())
		{
			this->SetTargetMonsterIndex(pMsgAttack->TargetInfo.TargetIndex);
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// 2007-02-06 by cmkwon
	// 1. 1형, 2형 무기 총알수 체크
	if(IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType))
	{// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리( 팻일 경우 탄약 처리 안하게 변경)
		if (FALSE == OnPrimaryAttack(pMsgAttack->AttackType))
		{
			return RES_BREAK;
		}
	}
	else // IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType)
	{
		// 공격 범위 확인
		if (CAtumSJ::IsCharacterTarget(eAttack2Target) || CAtumSJ::IsMonsterTarget(eAttack2Target))
		{
			D3DXVECTOR3 tmpTargetPosition = tmVecTargetPos;
			float fDist = D3DXVec3Length(&(tmpTargetPosition - m_character.PositionVector));
			if (fDist > 1.5f * CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor))
			{
				return RES_BREAK;
			}
		}
		// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리( 팻일 경우 탄약 처리 안하게 변경)
		if (FALSE == OnSecondaryAttack(1, pMsgAttack->AttackType))
		{
			return RES_BREAK;
		}
	}

	// 남은 현재 bullet 할당
	//////////////////////////////////////////////////////////////////////////
	// 2007-07-16 by dhjin, Tutorial 맵이면 전용 무기 할당.
	if(IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{
		pMsgAttackOK->RemainedBulletFuel = 100;
	}
	else
	{
		// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리( 팻일 경우 탄약 처리 안하게 변경)
		if(ATT_TYPE_PET_ATK == pMsgAttack->AttackType)
		{
			pMsgAttackOK->RemainedBulletFuel = 100;
		}
		else if(ATT_TYPE_PET_ATK != pMsgAttack->AttackType)
		{
		pMsgAttackOK->RemainedBulletFuel = pAttackItemGeneral->CurrentCount;
	}
		// 2010-06-15 by shcho&hslee 펫시스템 - 펫 공격 처리( 팻일 경우 탄약 처리 안하게 변경)
	}
	
	igLock.auto_unlock_cancel();

	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 스킬 사용여부와 세력비에 따른 버프 효과 비율 계산
	float tmBuffPercent = 0.0f;
	if (TRUE == m_SkillManager.IsSkillActivatedByItemNum(TURN_AROUND_BUFF_SKILL_1ST) || TRUE == m_SkillManager.IsSkillActivatedByItemNum(TURN_AROUND_BUFF_SKILL_3RD))
	{
		// 2014-03-25 by jekim, 승리의 환호
		if(0 == ms_pFieldIOCP->m_InflWarManager.GetPVPBuffPercent(m_character.InfluenceType,&tmBuffPercent))
		{
			tmBuffPercent = 0.0f;
		}
		// end 2014-03-25 by jekim, 승리의 환호
	}
	// end 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - 스킬 사용여부와 세력비에 따른 버프 효과 비율 계산

	///////////////////////////////////////////////////////////////////////////
	// 1형 무기 공격인 경우 이거나 펫 공격일 경우 
	///////////////////////////////////////////////////////////////////////////
	if (IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType) || ATT_TYPE_PET_ATK == pMsgAttack->AttackType ) // 2010-06-15 by shcho&hslee 펫시스템 - 펫 무기일 경우(추가)
	{
		// ChagingSkill 처리
		CChargingSkillApplier tmpChargingSkillApplier(&pITEMforProcessSplashAttack, FALSE, pAttackItem, this);
		// 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
#ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
#else	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		ITEM_SKILL *pSkillItem	= m_ItemManager.GetFirstSkillBySkillBaseNum(pMsgAttack->SkillNum);	// 2006-12-01 by dhjin,	
// 		ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pMsgAttack->SkillNum);
// 		ITEM_SKILL *pSkillItem = NULL;
// 		if ( NULL != pItemInfo )
// 		{
// 			pSkillItem	= m_ItemManager.GetFirstSkillBySkillBaseNum(pItemInfo->NextSkill);	// 2006-12-01 by dhjin,	
// 		}
#endif	// #ifdef SC_SKILL_NUMBERING_RENEWAL_JHSEOL_BHSOHN
		// end 2013-03-12 by jhseol, 스킬 넘버링 시스템 수정
		
		// 보정값 적용된 공격 범위 계산
		fSkillAppliedRange = CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor);
		
		if(pITEMforProcessSplashAttack)
		{// 2006-12-01 by dhjin, Splash 처리 아래에서 한다
			
			SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
		}
		else
		{// 2006-12-01 by dhjin, Splash 처리가 필요하지 안은것만 처리, Splash 처리는 제일 아래에서 처리

			///////////////////////////////////////////////////////////////////////////////			
			// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
			SATTACK_PARAMETER attParam;
			MEMSET_ZERO(&attParam, sizeof(attParam));
			attParam.MultiTargetIndex = pMsgAttack->TargetInfo.MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
			// 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
			enumAttackToTarget	tempAttack2Target		= eAttack2Target;
			if(C2M == tempAttack2Target)
			{
				CFieldMonster *pFMon = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(m_character.MapChannelIndex.ChannelIndex, pMsgAttack->TargetInfo.TargetIndex, 110);
				if(pFMon && MS_PLAYING == pFMon->m_enMonsterState && COMPARE_MPOPTION_BIT(pFMon->MonsterInfoPtr->MPOption, MPOPTION_BIT_ADD_DAMAGE_UNAPPLIED))
				{
					tempAttack2Target = C2NULL;
				}
			}
			// end 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
			this->APCalcAttckParameter(&attParam, pAttackItem, pMsgAttackOK->WeaponIndex, tempAttack2Target/*eAttack2Target*/, tmBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가	// 2013-05-09 by hskim, 세력 포인트 개선
			
			///////////////////////////////////////////////////////////////////////
			// 공격자와 피공격자에 따라 데미지 계산
			///////////////////////////////////////////////////////////////////////
			if (eAttack2Target == C2C)
			{
				if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttack->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
				{
					pMsgAttackOK->TargetInfo.SetNullTarget();
					///////////////////////////////////////////////////////////////////////////////
					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
					return RES_BREAK;
				}

				BOOL bRet = CAtumSJ::CheckTargetErrorAngle(&m_character, m_character.PositionVector, pTargetCharacter->PositionVector, tmVecTargetPos, fDistance);
				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
				fDamage = CalcDamageOfAttackNew(&DamageKind, C2C, 1.0f, this, &m_character, &attParam, pTargetSocket, &pTargetSocket->m_character, fSkillAppliedRange, fDistance);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//				fDamage = CalcDamageOfAttack(C2C, 1.0f, this, &m_character, pTargetSocket, &pTargetSocket->m_character, pAttackItem,
//					&DamageKind, tmVecTargetPos, fSkillAppliedRange, fDistance);
				pTargetSocket->m_uidAttackerGuildUID = 0;

				pTargetSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0028, this->m_character.CharacterName, fDamage);
				this->SendString128(STRING_128_DEBUG_L3,  STRMSG_S_F2NOTIFY_0029, pTargetCharacter->CharacterName, fDamage);
			}
			else if (eAttack2Target == C2M)
			{
				if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgAttack->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pTargetMonster))
				{
					pMsgAttackOK->TargetInfo.SetNullTarget();
					///////////////////////////////////////////////////////////////////////////////
					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
					return RES_BREAK;
				}

				////////////////////////////////////////////////////////////////////////////////
				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 받지 않는다.
				if(BELL_INFINITY_DEFENSE_MONSTER == pTargetMonster->MonsterInfoPtr->Belligerence) {
					return RES_BREAK;
				}

				////////////////////////////////////////////////////////////////////////////////
				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 배리어 체크
				if(pTargetMonster->CheckBarrierHave()) {
					if(pTargetMonster->CheckBarrierUsing()) {
						INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USING, T_FC_BATTLE_MONSTER_BARRIER_USING, pSendMsg, SendBuf);
						pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
						this->SendAddData(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USING));
						SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
						return RES_BREAK;
					}
					if(pTargetMonster->BarrierUse()) {
						INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USE, T_FC_BATTLE_MONSTER_BARRIER_USE, pSendMsg, SendBuf);
						pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
						pSendMsg->SkillItemNum		= pTargetMonster->m_bBarrierInfo.SkillNum;
						m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USE));
						SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
						return RES_BREAK;
					}
				}
				
				// 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, this) )
						{
							return RES_BREAK;
						}
						// 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() )
							{
								m_nCrystalAttackCount++;
								if( 1 == m_nCrystalAttackCount )
								{
									SendString128(STRING_128_USER_NOTICE, STRMSG_121126_0001);
								}
								if( 50 <= m_nCrystalAttackCount )
								{
									m_nCrystalAttackCount = 0;
								}
								return RES_BREAK;
							}
							else
							{
								m_nCrystalAttackCount = 0;
							}
							// end 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장 : 50번 공격할때마다 메세지 출력
						}
						// end 2013-01-23 by jhseol, 전쟁 시 크리스탈만 공격 불가능 하도록 수정
					}
				}
				// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

				BOOL bRet = CAtumSJ::CheckTargetErrorAngle(&m_character, m_character.PositionVector, pTargetMonster->PositionVector, tmVecTargetPos, fDistance);
				fDamage = CalcDamageOfAttackNew(&DamageKind, C2M, 1.0f, this, &m_character, &attParam, pTargetSocket, pTargetMonster, fSkillAppliedRange, fDistance);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//				fDamage = CalcDamageOfAttack(C2M, 1.0f, this, &m_character, pTargetSocket, pTargetMonster, pAttackItem,
//						&DamageKind, tmVecTargetPos, fSkillAppliedRange, fDistance);

				///////////////////////////////////////////////////////////////////////
				// Attack 정보를 NPC에게 보냄
				INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, SendBuf);
				pSetAttackChar->ChannelIndex = m_character.MapChannelIndex.ChannelIndex;
				pSetAttackChar->AttackIndex = pMsgAttackOK->AttackIndex;
				pSetAttackChar->TargetIndex = pMsgAttackOK->TargetInfo.TargetIndex;
				pSetAttackChar->DamageAmount = fDamage;
				pSetAttackChar->ItemKind = pAttackItem->Kind;
				m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));

				////////////////////////////////////////////////////////////////////////////////
				// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류), 밑과 같이 수정.
				// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 추가 타격치 아이템
//				if(0 < this->GetParamAddAttack()) {
//					this->AddAttackDamage(this, &m_character, pTargetMonster, &attParam);
//				}
				// 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
				if ( NULL != pTargetMonster && NULL != pTargetMonster->MonsterInfoPtr && FALSE == COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_ADD_DAMAGE_UNAPPLIED))
				{
					if(0 < this->GetParamAddAttack()
						&& 0 < fDamage) {
						this->AddAttackDamage(this, &m_character, pTargetMonster, this->GetParamAddAttack(), &attParam);
					}
				}
				// end 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
			}
			else if (eAttack2Target == C2I)
			{
			}
			else if (eAttack2Target == C2CI)
			{
				// 피공격자가 Dummy를 달고 있을 때
				if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttack->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
				{
					pMsgAttackOK->TargetInfo.SetNullTarget();
					///////////////////////////////////////////////////////////////////////////////
					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
					return RES_BREAK;
				}
				// 2006-12-04 by dhjin
				DamageKind = DAMAGEKIND_NORMAL;
				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
				fDamage = CalcDamageOfAttackNew(&DamageKind, C2C, 1.0f, this, &m_character, &attParam, pTargetSocket, pTargetCharacter);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//				fDamage = CalcDamageOfAttack(C2C, 1.0f, this, &m_character, pTargetSocket, pTargetCharacter,
//						pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
				pTargetSocket->m_uidAttackerGuildUID = 0;
			}
			else if (eAttack2Target == C2NULL)
			{
				// set null target
				pMsgAttackOK->TargetInfo.SetNullTarget();
			}

			///////////////////////////////////////////////////////////////////////
			// ATTACK_OK 전송
			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
			SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
		}// END - 		if(FALSE == bProcessSplashAttack)
	}
	else // IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType)
	{

		///////////////////////////////////////////////////////////////////////////////
		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
		SATTACK_PARAMETER attParam;
		MEMSET_ZERO(&attParam, sizeof(attParam));
		attParam.MultiTargetIndex = pMsgAttack->TargetInfo.MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		// 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
		enumAttackToTarget	tempAttack2Target		= eAttack2Target;
		if(C2M == tempAttack2Target)
		{
			CFieldMonster *pFMon = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(m_character.MapChannelIndex.ChannelIndex, pMsgAttack->TargetInfo.TargetIndex, 110);
			if(pFMon && MS_PLAYING == pFMon->m_enMonsterState && COMPARE_MPOPTION_BIT(pFMon->MonsterInfoPtr->MPOption, MPOPTION_BIT_ADD_DAMAGE_UNAPPLIED))
			{
				tempAttack2Target = C2NULL;
			}
		}
		// end 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
		this->APCalcAttckParameter(&attParam, pAttackItem, pMsgAttackOK->WeaponIndex, tempAttack2Target/*eAttack2Target*/, tmBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가		// 2013-05-09 by hskim, 세력 포인트 개선

		this->APInsertAttackParameter(&attParam);
		
#ifdef S_B_GEAR_DAMAGE_PROBABILITY_INFO			// 2013-05-06 by bckim, B기어 타겟 데미지 확인
		if( IS_BGEAR( m_character.UnitKind) )
		{
			g_pFieldGlobal->WriteSystemLogEX(FALSE, "###### [AccountName(UID) : %s(%d)][CharacterName(UID) : %s(%d)][attParam->fAttack:%f]\r\n",m_character.AccountName,m_character.AccountUniqueNumber,m_character.CharacterName,m_character.CharacterUniqueNumber,attParam.fAttack);	// 2013-10-16 by jhseol, 서버 디버깅시 불필요 DBGOUT 출력 코드 제거
		}	
#endif

		if(C2M == eAttack2Target)
		{// 2006-11-07 by cmkwon, 2형 무기를 쏜 경우 바로 공격자가 설정되도록

			CFieldMonster *pFMon = m_pCurrentFieldMapChannel->GetFieldMonster(pMsgAttack->TargetInfo.TargetIndex, 30);
			if(pFMon
				&& pFMon->m_enMonsterState == MS_PLAYING)
			{
				pFMon->SetAttackerCliIdx(this->GetCharacter()->ClientIndex);
			}
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
		SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);		
	}

	if(pITEMforProcessSplashAttack)
	{// 2006-12-01 by dhjin, 

		// ChagingSkill 처리
		CChargingSkillApplier tmpChargingSkillApplier(&pITEMforProcessSplashAttack, TRUE, pAttackItem, this);

		///////////////////////////////////////////////////////////////////////////////		
		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정 - 하이퍼샷 스킬 적용 후 아래의 함수를 호출해야 함
		SATTACK_PARAMETER attParam;
		MEMSET_ZERO(&attParam, sizeof(attParam));
		attParam.MultiTargetIndex = pMsgAttack->TargetInfo.MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
		// 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
		enumAttackToTarget	tempAttack2Target		= eAttack2Target;
		if(C2M == tempAttack2Target)
		{
			CFieldMonster *pFMon = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(m_character.MapChannelIndex.ChannelIndex, pMsgAttack->TargetInfo.TargetIndex, 110);
			if(pFMon && MS_PLAYING == pFMon->m_enMonsterState && COMPARE_MPOPTION_BIT(pFMon->MonsterInfoPtr->MPOption, MPOPTION_BIT_ADD_DAMAGE_UNAPPLIED))
			{
				tempAttack2Target = C2NULL;
			}
		}
		// end 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
		this->APCalcAttckParameter(&attParam, pAttackItem, pMsgAttackOK->WeaponIndex, tempAttack2Target/*eAttack2Target*/, tmBuffPercent);	// 2013-08-01 by jhseol, 역전의 버프 리뉴얼 - tmBuffPercent 추가		// 2013-05-09 by hskim, 세력 포인트 개선

		fSkillAppliedRange = CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor);		// 2006-12-06 by dhjin, 
		if(pITEMforProcessSplashAttack)
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2006-12-13 by cmkwon, 거리에 따른 확률 적용
			float fActualDistance = D3DXVec3Length(&(m_character.PositionVector - tmVecTargetPos));
			if(fActualDistance <= fSkillAppliedRange*2)
			{
				float fTmpMultValue = 1.0f;
				if (fActualDistance > fSkillAppliedRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER)
				{
					fTmpMultValue = MIN_ATTACK_DECREASE_FACTOR;
				}
				else if(fActualDistance > fSkillAppliedRange)
				{
					fTmpMultValue = 2*(MIN_ATTACK_DECREASE_FACTOR-1)*fActualDistance/fSkillAppliedRange + 3 - 2*MIN_ATTACK_DECREASE_FACTOR;
				}
				
				// 2010-07-19 by dhjin, 확률 수식 변경
//				float fAttackSuccessProbability = PROB256_MAX_VALUE * fTmpMultValue;
//				int nRand = RAND256();
//				if (nRand <= (int)fAttackSuccessProbability)
				float fAttackSuccessProbability = PROB100_MAX_VALUE * fTmpMultValue;
				float fRand = RANDF2(0,100);
				if (fRand <= fAttackSuccessProbability)
				{
					ProcessSplashDamageC2All(this, &attParam, pITEMforProcessSplashAttack->Range, &tmVecTargetPos);
				}
			}
		}
	}

	return RES_RETURN_TRUE;
}

// 2007-02-06 by cmkwon, 처리 함수를 위와 같이 수정함, lock 범위 관련 수정
//{
//	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_ATTACK,
//									MSG_FC_BATTLE_ATTACK, pMsgAttack);
//
//	// 각종 변수 준비
//	ITEM				*pAttackItem		= NULL;
//	ITEM_GENERAL		*pAttackItemGeneral	= NULL;
//	enumAttackToTarget	eAttack2Target		= ERR2ERR;
//	CFieldIOCPSocket	*pTargetSocket		= NULL;
//	CHARACTER			*pTargetCharacter	= NULL;
//	CFieldMonster		*pTargetMonster		= NULL;
//
//	float				fDistance			= 0.0f;		// 공격자와 공격대상과의 거리를 저장
//	float				fSkillAppliedRange	= 0.0f;		// 보정값 적용된 공격 범위 저장
//	float				fDamage				= 0.0f;		// 최종 데미지
//	BYTE				DamageKind			= DAMAGEKIND_NORMAL;
//	
//	ITEM				*pITEMforProcessSplashAttack = NULL;	// 2006-12-01 by dhjin,
//	D3DXVECTOR3			tmVecTargetPos		= A2DX(pMsgAttack->TargetInfo.TargetPosition);
//		
//	// 공격자가  유효한지 체크
//	if (FALSE == this->IsValidCharacter()
//		|| COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
//	{
//		return RES_BREAK;
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-12-01 by dhjin
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//
//	// Attack Item 할당 및 확인
//	if (IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType)) { pAttackItem = &m_ItemProwOut; }
//	else if (IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType)) { pAttackItem = &m_ItemWingOut; }
//	if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
//	{
//		return RES_BREAK;
//	}
//	pAttackItemGeneral = (ITEM_GENERAL*)pAttackItem->ItemNum;
//
//	// MSG_FC_BATTLE_ATTACK_OK 준비
//	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_OK, T_FC_BATTLE_ATTACK_OK, pMsgAttackOK, pMsgAttackOKBuf);
//	pMsgAttackOK->AttackIndex		= m_character.ClientIndex;
//	pMsgAttackOK->TargetInfo		= pMsgAttack->TargetInfo;
//	pMsgAttackOK->FirePosition		= pMsgAttack->FirePosition;
//	pMsgAttackOK->WeaponIndex		= m_WeaponIndexGenerator.GetNext();
//	pMsgAttackOK->AttackType		= pMsgAttack->AttackType;
//	pMsgAttackOK->ItemNum			= pAttackItemGeneral->ItemNum;
//	pMsgAttackOK->SkillNum			= pMsgAttack->SkillNum;
////	pMsgAttackOK->RemainedBulletFuel= ;	// OnXXXAttack() 이후에 할당
//
//	// AttackToTarget 결정
//	eAttack2Target = CAtumSJ::GetAttackToTarget(m_character.ClientIndex, pMsgAttack->TargetInfo);
//	if (eAttack2Target == ERR2ERR)
//	{
//		return RES_BREAK;
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-01-20 by cmkwon, 세력전 보스 몬스터 공격 메시지 
//	if(C2M == eAttack2Target)
//	{
//		CFieldMonster *pFMon = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetFieldMonsterW(m_character.MapChannelIndex.ChannelIndex, pMsgAttack->TargetInfo.TargetIndex, 110);
//		if(pFMon
//			&& MS_PLAYING == pFMon->m_enMonsterState
//			&& COMPARE_MPOPTION_BIT(pFMon->MonsterInfoPtr->MPOption, MPOPTION_BIT_BOSS_MONSTER)
//			&& IS_INFLWAR_MONSTER(pFMon->MonsterInfoPtr->Belligerence)
//			&& FALSE == COMPARE_BODYCON_BIT(pFMon->BodyCondition, BODYCON_DEAD_MASK))
//		{
//			DWORD		dwCurTick = timeGetTime();
//			if(dwCurTick - pFMon->m_dwLastTickInfluenceBossAttackedMsg > TICKGAP_SEND_INVASION_MSG)
//			{
//				pFMon->m_dwLastTickInfluenceBossAttackedMsg = dwCurTick;
//
//				INIT_MSG_WITH_BUFFER(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION, T_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION, pSInvasion, Sendbuf);
//				pSInvasion->MonsterUnitkind		= pFMon->MonsterInfoPtr->MonsterUnitKind;
//				ms_pFieldIOCP->SendMessageToAllClients(Sendbuf, MSG_SIZE(MSG_FC_WAR_NOTIFY_INFLUENCE_MONSTER_INVASION), GET_SAME_CHARACTER_INFL_BY_MONSTER_BELL(pFMon->MonsterInfoPtr->Belligerence));
//			}
//		}			
//	}
//
//	///////////////////////////////////////////////////////////////////////////
//	// 1형 무기 공격인 경우
//	///////////////////////////////////////////////////////////////////////////
//	if (IS_PRIMARY_ATT_TYPE(pMsgAttack->AttackType))
//	{
//		// OnPrimaryAttack() 처리
//		if (!OnPrimaryAttack())
//		{
//			return RES_BREAK;
//		}
//
//		// ChagingSkill 처리
//		CChargingSkillApplier tmpChargingSkillApplier(&pITEMforProcessSplashAttack, FALSE, pAttackItem, this);
//
//		// 남은 현재 bullet 할당
//		if (IS_PRIMARY_WEAPON_1(pAttackItem->Kind))			// 1-1형 아이템
//		{
//			pMsgAttackOK->RemainedBulletFuel = pAttackItemGeneral->CurrentCount;
//		}
//		else if (IS_PRIMARY_WEAPON_2(pAttackItem->Kind))	// 1-2형(beam류) 아이템
//		{
//			pMsgAttackOK->RemainedBulletFuel = (USHORT)m_character.CurrentEP;
//		}
//
//		ITEM_SKILL *pSkillItem	= m_ItemManager.GetFirstSkillBySkillBaseNum(pMsgAttack->SkillNum);	// 2006-12-01 by dhjin, 
//		
//		// 보정값 적용된 공격 범위 계산
//		fSkillAppliedRange = CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor);
//
//		if(pITEMforProcessSplashAttack)
//		{// 2006-12-01 by dhjin, Splash 처리 아래에서 한다
//			
//			SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
//		}
//		else
//		{// 2006-12-01 by dhjin, Splash 처리가 필요하지 안은것만 처리, Splash 처리는 제일 아래에서 처리
//	#ifdef _DEBUG
//			SendString128(STRING_128_DEBUG_L3, "%5.2f vs %5.2f(%5.2f*%5.2f)"
//				, fDistance, fSkillAppliedRange, (float)pAttackItem->Range
//				, (1.0f + (IS_PRIMARY_WEAPON(pAttackItem->Kind)?m_ParamFactor.pfm_RANGE_01:m_ParamFactor.pfm_RANGE_02)));
//	#endif
//
//	#ifdef _DEBUG
//			SendString128(STRING_128_DEBUG_L1, "A: %3.1f~%3.1f",
//							CAtumSJ::GetMinAttackC(&m_character, pAttackItem, &m_ParamFactor, TRUE),
//							CAtumSJ::GetMaxAttackC(&m_character, pAttackItem, &m_ParamFactor, TRUE));
//	#endif
//			///////////////////////////////////////////////////////////////////////
//			// 공격자와 피공격자에 따라 데미지 계산
//			///////////////////////////////////////////////////////////////////////
//			if (eAttack2Target == C2C)
//			{
//				if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttack->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//				{
//					pMsgAttackOK->TargetInfo.SetNullTarget();
//					///////////////////////////////////////////////////////////////////////////////
//					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
//					return RES_BREAK;
//				}
//
//				BOOL bRet = CAtumSJ::CheckTargetErrorAngle(&m_character, m_character.PositionVector, pTargetCharacter->PositionVector,
//															tmVecTargetPos, fDistance);
//	// 2005-07-19 by cmkwon, CAtumSJ::CheckTargetErrorAngle함수내에서 fDistance를 계산한다. 공격시 클라이언트를 항상 신뢰한다. 거리, 각 차이를 체크하지 않는다
//	//			if (bRet)
//				{
//					pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//					fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK(), C2C
//						&m_character, pTargetSocket, &pTargetSocket->m_character, pAttackItem,
//						&DamageKind, tmVecTargetPos,
//						fSkillAppliedRange, fDistance);
//					pTargetSocket->m_uidAttackerGuildUID = 0;
//				}
//				
//				pTargetSocket->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0028, this->m_character.CharacterName, fDamage);
//				this->SendString128(STRING_128_DEBUG_L3,  STRMSG_S_F2NOTIFY_0029, pTargetCharacter->CharacterName, fDamage);
//			}
//			else if (eAttack2Target == C2M)
//			{
//				if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgAttack->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pTargetMonster))
//				{
//					pMsgAttackOK->TargetInfo.SetNullTarget();
//					///////////////////////////////////////////////////////////////////////////////
//					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
//					return RES_BREAK;
//				}
//
//				BOOL bRet = CAtumSJ::CheckTargetErrorAngle(&m_character, m_character.PositionVector, pTargetMonster->PositionVector,
//															tmVecTargetPos, fDistance);
//	// 2005-07-19 by cmkwon, CAtumSJ::CheckTargetErrorAngle함수내에서 fDistance를 계산한다. 공격시 클라이언트를 항상 신뢰한다. 거리, 각 차이를 체크하지 않는다
//	//			if (bRet)
//				{
//					fDamage = CalcDamageOfAttack(C2M, 1.0f, this,		// @Process_FC_BATTLE_ATTACK(), C2M
//						&m_character, pTargetSocket, pTargetMonster, pAttackItem,
//						&DamageKind, tmVecTargetPos,
//						fSkillAppliedRange, fDistance);
//				}
//
//				///////////////////////////////////////////////////////////////////////
//				// Attack 정보를 NPC에게 보냄
//				INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, SendBuf);
//				pSetAttackChar->ChannelIndex = m_character.MapChannelIndex.ChannelIndex;
//				pSetAttackChar->AttackIndex = pMsgAttackOK->AttackIndex;
//				pSetAttackChar->TargetIndex = pMsgAttackOK->TargetInfo.TargetIndex;
//				pSetAttackChar->DamageAmount = fDamage;
//				pSetAttackChar->ItemKind = pAttackItem->Kind;
//				m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
//			}
//			else if (eAttack2Target == C2I)
//			{
//			}
//			else if (eAttack2Target == C2CI)
//			{
//				// 피공격자가 Dummy를 달고 있을 때
//				if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttack->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//				{
//					pMsgAttackOK->TargetInfo.SetNullTarget();
//					///////////////////////////////////////////////////////////////////////////////
//					// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//					SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
//					return RES_BREAK;
//				}
//// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
////			// lock m_mapFieldDummy
////			mt_auto_lock dummyLock(&pTargetSocket->m_mapFieldDummy);
////
////			if (!pTargetSocket->m_mapFieldDummy.empty())
////				{
////				FIELD_DUMMY *pTargetDummy = pTargetSocket->m_mapFieldDummy.findLock(pMsgAttack->TargetInfo.TargetItemFieldIndex);
////					if (pTargetDummy == NULL)
////					{
////						DamageKind = DAMAGEKIND_NORMAL;
////						pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
////						fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK(), C2CI
////							&m_character, pTargetSocket, pTargetCharacter,
////							pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
////						pTargetSocket->m_uidAttackerGuildUID = 0;
////	#ifdef _DEBUG
////						SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0030, pTargetCharacter->CharacterName, fDamage);
////	#endif
////					}
////					else
////					{
////						DamageKind = DAMAGEKIND_NORMAL;
////						pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
////						fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK(), C2CI
////							&m_character, pTargetSocket, pTargetCharacter,
////							pAttackItem, &DamageKind, pTargetCharacter->PositionVector,
////							0.0f, 0.0f, pTargetDummy->ItemFieldIndex);
////						pTargetSocket->m_uidAttackerGuildUID = 0;
////	#ifdef _DEBUG
////						SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0031, pTargetCharacter->CharacterName, fDamage);
////	#endif
////					}				
////				}
//				// 2006-12-04 by dhjin
//				DamageKind = DAMAGEKIND_NORMAL;
//				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK(), C2CI
//						&m_character, pTargetSocket, pTargetCharacter,
//						pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
//				pTargetSocket->m_uidAttackerGuildUID = 0;
//			}
//			else if (eAttack2Target == C2NULL)
//			{
//	#ifdef _DEBUG
//				SendString128(STRING_128_DEBUG_L2, "NULL Target by Client");
//	#endif
//				// set null target
//				pMsgAttackOK->TargetInfo.SetNullTarget();
//			}
//
//			///////////////////////////////////////////////////////////////////////
//			// ATTACK_OK 전송
//			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//			SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);
//		}// END - 		if(FALSE == bProcessSplashAttack)
//
//	}
//	///////////////////////////////////////////////////////////////////////////
//	// 2형 무기 공격인 경우
//	///////////////////////////////////////////////////////////////////////////
//	else if (IS_SECONDARY_ATT_TYPE(pMsgAttack->AttackType))
//	{
//		// 공격 범위 확인
//		if (CAtumSJ::IsCharacterTarget(eAttack2Target) || CAtumSJ::IsMonsterTarget(eAttack2Target))
//		{
//			D3DXVECTOR3 tmpTargetPosition = tmVecTargetPos;
//			float fDist = D3DXVec3Length(&(tmpTargetPosition - m_character.PositionVector));
//			if (fDist > 1.5f * CAtumSJ::GetAttackRange(&m_ItemWingOut, &m_ParamFactor))
//			{
//				return RES_BREAK;
//			}
//		}
//
//		if (!OnSecondaryAttack(1))	// ATTACK_SECONDARY
//		{
//			return RES_BREAK;
//		}
//
//		if(C2M == eAttack2Target)
//		{// 2006-11-07 by cmkwon, 2형 무기를 쏜 경우 바로 공격자가 설정되도록
//
//			CFieldMonster *pFMon = m_pCurrentFieldMapChannel->GetFieldMonster(pMsgAttack->TargetInfo.TargetIndex, 30);
//			if(pFMon
//				&& pFMon->m_enMonsterState == MS_PLAYING)
//			{
//				pFMon->SetAttackerCliIdx(this->GetCharacter()->ClientIndex);
//			}
//		}
//
//		// 남은 총알 수 할당
//		pMsgAttackOK->RemainedBulletFuel = pAttackItemGeneral->CurrentCount;
//		
//		///////////////////////////////////////////////////////////////////////////////
//		// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//		SendInRangeMessageAroundMe(pMsgAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_OK), TRUE);		
//	}
//	///////////////////////////////////////////////////////////////////////////
//	// 처리 하지 않는 ATT_TYPE 인 경우
//	///////////////////////////////////////////////////////////////////////////
//	else
//	{
//		return RES_BREAK;
//	}
//	igLock.auto_unlock_cancel();
//
//	if(pITEMforProcessSplashAttack)
//	{// 2006-12-01 by dhjin, 
//
//		// ChagingSkill 처리
//		CChargingSkillApplier tmpChargingSkillApplier(&pITEMforProcessSplashAttack, TRUE, pAttackItem, this);
//		fSkillAppliedRange = CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor);		// 2006-12-06 by dhjin, 
//		if(pITEMforProcessSplashAttack)
//		{
//			///////////////////////////////////////////////////////////////////////////////
//			// 2006-12-13 by cmkwon, 거리에 따른 확률 적용
//			float fActualDistance = D3DXVec3Length(&(m_character.PositionVector - tmVecTargetPos));
//			if(fActualDistance <= fSkillAppliedRange*2)
//			{
//				float fTmpMultValue = 1.0f;
//				if (fActualDistance > fSkillAppliedRange*EFFECTIVE_ATTACK_RANGE_MULTIPLIER)
//				{
//					fTmpMultValue = MIN_ATTACK_DECREASE_FACTOR;
//				}
//				else if(fActualDistance > fSkillAppliedRange)
//				{
//					fTmpMultValue = 2*(MIN_ATTACK_DECREASE_FACTOR-1)*fActualDistance/fSkillAppliedRange + 3 - 2*MIN_ATTACK_DECREASE_FACTOR;
//				}
//				
//				float fAttackSuccessProbability = PROB256_MAX_VALUE * fTmpMultValue;
//				int nRand = RAND256();
//				if (nRand <= (int)fAttackSuccessProbability)
//				{
//					ProcessSplashDamageC2All(this, pAttackItem, pITEMforProcessSplashAttack->Range, &tmVecTargetPos);
//				}
//			}
//		}
//	}
//
//	return RES_RETURN_TRUE;
//}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ATTACK_FIND(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_ATTACK_FIND,
									MSG_FC_BATTLE_ATTACK_FIND, pMsgAttackFind);

	// 각종 변수 준비
	ITEM				*pAttackItem		= NULL;
	ITEM_GENERAL		*pAttackItemGeneral	= NULL;
	enumAttackToTarget	eAttack2Target		= ERR2ERR;
	CFieldIOCPSocket	*pTargetSocket		= NULL;
	CHARACTER			*pTargetCharacter	= NULL;
	CFieldMonster		*pTargetMonster		= NULL;
	CFieldMonster		*pAttackMonster		= NULL;

	float				fDistance			= 0.0f;		// 공격자와 공격대상과의 거리를 저장
	float				fDamage				= 0.0f;		// 최종 데미지
	BYTE				DamageKind			= DAMAGEKIND_NORMAL;
	float				fDamageWeight		= 0.0f;		// splash에 의한 weight
	
	// 2형 무기 공격만 해당, 1형은 무시
	if (FALSE == IS_SECONDARY_ATT_TYPE(pMsgAttackFind->AttackType))
	{
		return RES_BREAK;
	}

	// 자기 자신이 공격자이거나 혹은 몬스터의 타겟이 자신이어야 함!
	if (m_character.ClientIndex != pMsgAttackFind->AttackIndex
		&& !IS_MONSTER_CLIENT_INDEX(pMsgAttackFind->AttackIndex))
	{
		return RES_BREAK;
	}

	// AttackToTarget 결정
	eAttack2Target = CAtumSJ::GetAttackToTarget(pMsgAttackFind->AttackIndex, pMsgAttackFind->TargetInfo);
	if (eAttack2Target == ERR2ERR)
	{
		return RES_BREAK;
	}

	// 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		= pMsgAttackFind->AttackIndex;
	pMsgAttackFindOK->TargetIndex		= pMsgAttackFind->TargetInfo.TargetIndex;
	pMsgAttackFindOK->TargetItemFieldIndex	= pMsgAttackFind->TargetInfo.TargetItemFieldIndex;
	pMsgAttackFindOK->WeaponIndex		= pMsgAttackFind->WeaponIndex;
	pMsgAttackFindOK->AttackType		= pMsgAttackFind->AttackType;

	// start 2012-01-17 by hskim, EP4 [비분쟁 지역] - 유저간 공격 금지 구역
	if( C2C == eAttack2Target && TRUE == IS_MAP_INFLUENCE_NON_DISPUTE(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()) )
	{
		SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);

		return RES_BREAK;
	}
	// end 2012-01-17 by hskim, EP4 [비분쟁 지역] - 유저간 공격 금지 구역

	///////////////////////////////////////////////////////////////////////////////	
	// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가			
	SATTACK_PARAMETER attParam;	
	attParam.MultiTargetIndex = pMsgAttackFind->TargetInfo.MultiTargetIndex;		// 2011-03-21 by hskim, 인피니티 3차 - 몬스터 멀티 타겟팅 기능 추가
	MEMSET_ZERO(&attParam, sizeof(attParam));

	// 공격자에 따른 분류
	if (CAtumSJ::IsCharacterAttacker(eAttack2Target))
	{// 2007-02-06 by cmkwon, 자신이 공격자
		
		if (FALSE == this->IsValidCharacter()
			|| COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
		{// 공격자가 유효한지 체크
			return RES_BREAK;
		}

		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
		//////////////////////////////////////////////////////////////////////////
		// 2007-07-16 by dhjin, Tutorial 맵이면 전용 무기 할당.
		if(IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
		{
			pAttackItem = GetTutorialWeaponInfo(pMsgAttackFind->AttackType);
			if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
			{
				return RES_BREAK;
			}
		}	
		else
		{
			// Attack Item 할당 및 확인
			pAttackItem = &m_ItemWingOut;
			if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
			{
				return RES_BREAK;
			}
			pAttackItemGeneral	= (ITEM_GENERAL*)pAttackItem->ItemNum;
			pAttackItem			= pAttackItemGeneral->ItemInfo;				// 2007-02-06 by cmkwon, 장착 아이템의 포인터를 lock과 상관없는 포인터로 변경한다.

			if(pMsgAttackFind->ItemNum != pAttackItem->ItemNum)
			{// 2007-02-06 by cmkwon, 장착 무기와 공격 무기가 다르다
				return RES_BREAK;
			}		
		}

		///////////////////////////////////////////////////////////////////////////////	
		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가
		if(FALSE == this->APPopAttackParameter(&attParam, pMsgAttackFind->WeaponIndex))
		{
			SendErrorMessage(T_FC_BATTLE_ATTACK_FIND, ERR_INVALID_WEAPON_INDEX, pMsgAttackFind->WeaponIndex, 0, NULL, FALSE, TRUE);
			return RES_BREAK;
		}
	}
	else if (CAtumSJ::IsMonsterAttacker(eAttack2Target))
	{// 2007-02-06 by cmkwon, 몬스터가 공격함

		pAttackMonster = m_pCurrentFieldMapChannel->GetFieldMonster(pMsgAttackFind->AttackIndex, 8);
		if(NULL == pAttackMonster
			|| FALSE == pAttackMonster->IsValidMonster())
		{// 2007-02-06 by cmkwon, 몬스터 체크
			return RES_BREAK;
		}

		// Attack Item 할당 및 확인
		pAttackItem = pAttackMonster->FindItemPtrWithItemNum(pMsgAttackFind->ItemNum);
		if(NULL == pAttackItem)
		{
			// 공격무기가 유효 하지 않음
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////	
		// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 추가
		if(FALSE == pAttackMonster->APPopAttackParameter(&attParam, pMsgAttackFind->WeaponIndex))
		{
			SendErrorMessage(T_FC_BATTLE_ATTACK_FIND, ERR_INVALID_WEAPON_INDEX, pMsgAttackFind->WeaponIndex, 0, NULL, FALSE, TRUE);
			return RES_BREAK;
		}
	}
	else
	{
		return RES_BREAK;
	}

///////////////////////////////////////////////////////////////////////////////	
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정으로 아래와 같이 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-09-08 by cmkwon, 캐릭터공격 아이템 장착 변경을 체크한다.
//	UID16_t uid16Cur = m_WeaponIndexGenerator.GetCurrent();
//	if(IS_VALID_CLIENT_INDEX(pMsgAttackFind->AttackIndex)
//		&& pMsgAttackFind->WeaponIndex > uid16Cur)
//	{
//		SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//		return RES_BREAK;
//	}
	if(pAttackItem != attParam.pWeaponItemInfo)
	{
		SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////////////////////////////
	// 공격자와 피공격자에 따라 데미지 계산
	///////////////////////////////////////////////////////////////////////
	if (eAttack2Target == C2C)
	{
		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
		{
			pMsgAttackFindOK->TargetIndex			= 0;
			pMsgAttackFindOK->TargetItemFieldIndex	= 0;
			///////////////////////////////////////////////////////////////////////////////
			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
			return RES_BREAK;
		}
		fDamageWeight = 1.0f;
		pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
		fDamage = CalcDamageOfAttackNew(&DamageKind, C2C, fDamageWeight, this, &m_character, &attParam, pTargetSocket, &pTargetSocket->m_character);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//		fDamage = CalcDamageOfAttack(C2C, fDamageWeight, this, &m_character, pTargetSocket, &pTargetSocket->m_character, pAttackItem,
//			&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));
		pTargetSocket->m_uidAttackerGuildUID = 0;

#ifdef _DEBUG
		pTargetSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0032, this->m_character.CharacterName, fDamage);
		SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0033, pTargetCharacter->CharacterName, fDamage);
#endif
	}
	else if (eAttack2Target == C2M)
	{
		if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgAttackFind->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pTargetMonster))
		{
			pMsgAttackFindOK->TargetIndex = 0;
			pMsgAttackFindOK->TargetItemFieldIndex = 0;
			///////////////////////////////////////////////////////////////////////////////
			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
			return RES_BREAK;
		}

		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 데미지 받지 않는다.
		if(BELL_INFINITY_DEFENSE_MONSTER == pTargetMonster->MonsterInfoPtr->Belligerence) {
			return RES_BREAK;
		}

		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 배리어 체크
		if(pTargetMonster->CheckBarrierHave()) {
			if(pTargetMonster->CheckBarrierUsing()) {
				INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USING, T_FC_BATTLE_MONSTER_BARRIER_USING, pSendMsg, SendBuf);
				pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
				this->SendAddData(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USING));
				SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
				return RES_BREAK;
			}
			if(pTargetMonster->BarrierUse()) {
				INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USE, T_FC_BATTLE_MONSTER_BARRIER_USE, pSendMsg, SendBuf);
				pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
				pSendMsg->SkillItemNum		= pTargetMonster->m_bBarrierInfo.SkillNum;
				m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USE));
				SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
				return RES_BREAK;
			}
		}

		// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 몬스터 즉시 시전 배리어 스킬(고급무기만발동)
		if(TRUE == pTargetMonster->CheckImmediateBarrierUsing()) {
			return RES_BREAK;
		}

		// 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, this) )
				{
					return RES_BREAK;
				}
				// 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() )
					{
						m_nCrystalAttackCount++;
						if( 1 == m_nCrystalAttackCount )
						{
							SendString128(STRING_128_USER_NOTICE, STRMSG_121126_0001);
						}
						if( 50 <= m_nCrystalAttackCount )
						{
							m_nCrystalAttackCount = 0;
						}
						return RES_BREAK;
					}
					else
					{
						m_nCrystalAttackCount = 0;
					}
					// end 2012-12-15 by jhseol, 전쟁 시스템 리뉴얼 - 전쟁시 트리거 무적상태(일시정지) 크리스탈 공격횟수 저장 : 50번 공격할때마다 메세지 출력
				}
				// end 2013-01-23 by jhseol, 전쟁 시 크리스탈만 공격 불가능 하도록 수정
			}
		}
		// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

		fDamageWeight = 1.0f;
		fDamage = CalcDamageOfAttackNew(&DamageKind, C2M, fDamageWeight, this, &m_character, &attParam, pTargetSocket, pTargetMonster);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//		fDamage = CalcDamageOfAttack(C2M, fDamageWeight, this, &m_character, pTargetSocket, pTargetMonster, pAttackItem,
//				&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));

#ifdef _DEBUG
		this->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0034, pTargetMonster->MonsterIndex, fDamage, (int)fDamage);
#endif

		///////////////////////////////////////////////////////////////////////
		// Attack 정보를 NPC에게 보냄
		INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, SendBuf);
		pSetAttackChar->ChannelIndex = m_character.MapChannelIndex.ChannelIndex;
		pSetAttackChar->AttackIndex = pMsgAttackFindOK->AttackIndex;
		pSetAttackChar->TargetIndex = pMsgAttackFindOK->TargetIndex;
		pSetAttackChar->DamageAmount = fDamage;
		pSetAttackChar->ItemKind = pAttackItem->Kind;
		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));

		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 절대값 타격치 아이템 고급무기용(기무와 분류), 밑과 같이 수정.
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 절대값 추가 타격치 아이템
//		if(0 < this->GetParamAddAttackSec()) {
//			this->AddAttackDamage(this, &m_character, pTargetMonster, &attParam);
//		}
		// 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
		if ( NULL != pTargetMonster && NULL != pTargetMonster->MonsterInfoPtr && FALSE == COMPARE_MPOPTION_BIT(pTargetMonster->MonsterInfoPtr->MPOption, MPOPTION_BIT_ADD_DAMAGE_UNAPPLIED))
		{
			if(0 < this->GetParamAddAttackSec()
				&& 0 < fDamage) {
				this->AddAttackDamage(this, &m_character, pTargetMonster, this->GetParamAddAttackSec(), &attParam);
			}
		}
		// end 2013-07-23 by jhseol, 몬스터 추가대미지 미적용 옵션.
	}
	else if (eAttack2Target == C2I)
	{
	}
	else if (eAttack2Target == C2CI)
	{
		// 피공격자가 Dummy를 달고 있을 때
		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
		{
			pMsgAttackFindOK->TargetIndex			= 0;
			pMsgAttackFindOK->TargetItemFieldIndex	= 0;
			///////////////////////////////////////////////////////////////////////////////
			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
			return RES_BREAK;
		}
		// 2006-12-04 by dhjin, 아래와 같이 수정
		DamageKind = DAMAGEKIND_NORMAL;
		fDamageWeight = 1.0f;
		pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
		fDamage = CalcDamageOfAttackNew(&DamageKind, C2C, fDamageWeight, this, &m_character, &attParam, pTargetSocket, pTargetCharacter);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//		fDamage = CalcDamageOfAttack(C2C, fDamageWeight, this, &m_character, pTargetSocket, pTargetCharacter,
//			pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
		pTargetSocket->m_uidAttackerGuildUID = 0;
	}
	else if (eAttack2Target == C2NULL)
	{
		// set null target
		pMsgAttackFindOK->TargetIndex = 0;
		pMsgAttackFindOK->TargetItemFieldIndex = 0;
	}
	else if (eAttack2Target == M2C)
	{
		if(!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
		{
			pMsgAttackFindOK->TargetIndex = 0;
			pMsgAttackFindOK->TargetItemFieldIndex = 0;
			///////////////////////////////////////////////////////////////////////////////
			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
			return RES_BREAK;
		}
		fDamageWeight = 1.0f;
		fDamage = CalcDamageOfAttackNew(&DamageKind, M2C, fDamageWeight, NULL, pAttackMonster, &attParam, pTargetSocket, (void*)pTargetCharacter);
// 2007-06-08 by cmkwon, 2형 공격확률,피어스율,공격력 계산 시스템 수정
//		fDamage = CalcDamageOfAttack(M2C, fDamageWeight, NULL, pAttackMonster, pTargetSocket, (void*)pTargetCharacter, pAttackItem,
//				&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));
#ifdef _DEBUG
		pTargetSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0037, pAttackMonster->MonsterInfoPtr->MonsterUnitKind, fDamage);
#endif
	}
	else if (eAttack2Target == M2I)
	{
	}
	else if (eAttack2Target == M2CI)
	{
	}
	else if (eAttack2Target == M2NULL)
	{
	}
	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 몬스터간 공격 처리
	// 2010-03-16 by cmkwon, 인피2차 MtoM, MtoC 타겟 변경 관련 수정 - Crash 버그 수정
	else if(M2M == eAttack2Target)
	{
		pTargetMonster = m_pCurrentFieldMapChannel->GetFieldMonster(pMsgAttackFindOK->TargetIndex, 107);
		if(NULL == pTargetMonster
			|| FALSE == pTargetMonster->IsValidMonster())
		{
			return RES_BREAK;
		}

		float		fDamage;

		////////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 배리어 체크
		if(pTargetMonster->CheckBarrierHave())
		{
			if(pTargetMonster->CheckBarrierUsing()) {
				INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USING, T_FC_BATTLE_MONSTER_BARRIER_USING, pSendMsg, SendBuf);
				pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
				this->SendAddData(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USING));
				SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
				return RES_BREAK;
			}
			if(pTargetMonster->BarrierUse()) {
				INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MONSTER_BARRIER_USE, T_FC_BATTLE_MONSTER_BARRIER_USE, pSendMsg, SendBuf);
				pSendMsg->MonsterIndex		= pTargetMonster->MonsterIndex;
				pSendMsg->SkillItemNum		= pTargetMonster->m_bBarrierInfo.SkillNum;
				m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf,  MSG_SIZE(MSG_FC_BATTLE_MONSTER_BARRIER_USE));
				SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
				return RES_BREAK;
			}
		}
		// 2009-09-09 ~ 2010-01-15 by dhjin, 인피니티 - 몬스터 즉시 시전 배리어 스킬(고급무기만발동)
		if(TRUE == pTargetMonster->CheckImmediateBarrierUsing()) {
			return RES_BREAK;
		}

		fDamage = CFieldIOCPSocket::CalcDamageOfAttackMonsterToMonster(1.0f, this, pAttackMonster, &attParam, (void*)pTargetMonster);	

		///////////////////////////////////////////////////////////////////////
		// 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	= m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex;
		pSetAttackChar->AttackIndex		= pMsgAttackFindOK->AttackIndex;
		pSetAttackChar->TargetIndex		= pMsgAttackFindOK->TargetIndex;
		pSetAttackChar->DamageAmount	= fDamage;
		pSetAttackChar->ItemKind		= attParam.pWeaponItemInfo->Kind;
		m_pCurrentFieldMapChannel->Send2NPCServerW(Send2NPC, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));

		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 몬스터간 2형공격 처리는 채널 모든 유저에게 다 보낸다.
		this->m_pCurrentFieldMapChannel->SendMessageToAllInChannel(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK));
		return RES_RETURN_TRUE;
	}
	else
	{
		// cannot handle type
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-31 by dhjin, 인피니티(기지방어) - 
	this->ProcessingHitInvokeSkill(pAttackItem, pMsgAttackFindOK->AttackIndex);

	///////////////////////////////////////////////////////////////////////
	// ATTACK_FIND_OK 전송
	// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
	SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);	
	return RES_RETURN_TRUE;
}
// 2007-02-06 by cmkwon, 위와 같이 수정함, lock 범위 관련 수정
//{
//	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_ATTACK_FIND,
//									MSG_FC_BATTLE_ATTACK_FIND, pMsgAttackFind);
//
//	// 각종 변수 준비
//	ITEM				*pAttackItem		= NULL;
//	ITEM_GENERAL		*pAttackItemGeneral	= NULL;
//	enumAttackToTarget	eAttack2Target		= ERR2ERR;
//	CFieldIOCPSocket	*pTargetSocket		= NULL;
//	CHARACTER			*pTargetCharacter	= NULL;
//	CFieldMonster		*pTargetMonster		= NULL;
//	CFieldMonster		*pAttackMonster		= NULL;
//
//	float				fDistance			= 0.0f;		// 공격자와 공격대상과의 거리를 저장
//	float				fSkillAppliedRange	= 0.0f;		// 보정값 적용된 공격 범위 저장
//	float				fDamage				= 0.0f;		// 최종 데미지
//	BYTE				DamageKind			= DAMAGEKIND_NORMAL;
//	float				fDamageWeight		= 0.0f;		// splash에 의한 weight
//	
//	// 2형 무기 공격만 해당, 1형은 무시
//	if (IS_PRIMARY_ATT_TYPE(pMsgAttackFind->AttackType))
//	{
//		return RES_BREAK;
//	}
//
//	// 자기 자신의 공격이거나 몬스터의 공격이어야 함!
//	if (m_character.ClientIndex != pMsgAttackFind->AttackIndex
//		&& !IS_MONSTER_CLIENT_INDEX(pMsgAttackFind->AttackIndex))
//	{
//		return RES_BREAK;
//	}
//
//	// 공격자가 유효한지 체크
//	if (FALSE == this->IsValidCharacter()
//		|| COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
//	{
//		return RES_BREAK;
//	}
//
//	// AttackToTarget 결정
//	eAttack2Target = CAtumSJ::GetAttackToTarget(pMsgAttackFind->AttackIndex, pMsgAttackFind->TargetInfo);
//	if (eAttack2Target == ERR2ERR)
//	{
//		return RES_BREAK;
//	}
//
//	// 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		= pMsgAttackFind->AttackIndex;
//	pMsgAttackFindOK->TargetIndex		= pMsgAttackFind->TargetInfo.TargetIndex;
//	pMsgAttackFindOK->TargetItemFieldIndex	= pMsgAttackFind->TargetInfo.TargetItemFieldIndex;
//	pMsgAttackFindOK->WeaponIndex		= pMsgAttackFind->WeaponIndex;
//	pMsgAttackFindOK->AttackType		= pMsgAttackFind->AttackType;
//
//	// 공격자에 따른 분류
//	if (CAtumSJ::IsCharacterAttacker(eAttack2Target))
//	{
//		// Attack Item 할당 및 확인
//		pAttackItem = &m_ItemWingOut;
//		if (pAttackItem == NULL || pAttackItem->ItemNum == NULL)
//		{
//			return RES_BREAK;
//		}
//		pAttackItemGeneral = (ITEM_GENERAL*)pAttackItem->ItemNum;
//	}
//	else if (CAtumSJ::IsMonsterAttacker(eAttack2Target))
//	{
//		pAttackMonster = m_pCurrentFieldMapChannel->GetFieldMonster(pMsgAttackFind->AttackIndex, 8);
//		if(NULL == pAttackMonster
//			//|| MS_PLAYING != pMonster->m_enMonsterState	// 20030109 cmkwon 두번째 무기는 몬스터가 죽어도 계산처리
//			|| TRUE == COMPARE_BODYCON_BIT(pAttackMonster->BodyCondition, BODYCON_DEAD_MASK))
//		{
//			return RES_BREAK;
//		}
//
//		// Attack Item 할당 및 확인
//		pAttackItem = pAttackMonster->FindItemPtrWithItemNum(pMsgAttackFind->ItemNum);
//		if(NULL == pAttackItem)
//		{
//			// 공격무기가 유효 하지 않음
//			return RES_BREAK;
//		}
//	}
//	else
//	{
//		return RES_BREAK;
//	}
//
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-09-08 by cmkwon, 캐릭터공격 아이템 장착 변경을 체크한다.
//	UID16_t uid16Cur = m_WeaponIndexGenerator.GetCurrent();
//	if(IS_VALID_CLIENT_INDEX(pMsgAttackFind->AttackIndex)
//		&& pMsgAttackFind->WeaponIndex > uid16Cur)
//	{
//		SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//		return RES_BREAK;
//	}
//
//	// 보정값 적용된 공격 범위 계산
//	fSkillAppliedRange = CAtumSJ::GetAttackRange(pAttackItem, &m_ParamFactor);
//#ifdef _DEBUG
//	SendString128(STRING_128_DEBUG_L3, "%5.2f vs %5.2f(%5.2f*%5.2f)"
//		, fDistance, fSkillAppliedRange, (float)pAttackItem->Range
//		, (1.0f + (IS_PRIMARY_WEAPON(pAttackItem->Kind)?m_ParamFactor.pfm_RANGE_01:m_ParamFactor.pfm_RANGE_02)));
//#endif
//
//	///////////////////////////////////////////////////////////////////////
//	// 공격자와 피공격자에 따라 데미지 계산
//	///////////////////////////////////////////////////////////////////////
//	if (eAttack2Target == C2C)
//	{
//		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//		{
//			pMsgAttackFindOK->TargetIndex			= 0;
//			pMsgAttackFindOK->TargetItemFieldIndex	= 0;
//			///////////////////////////////////////////////////////////////////////////////
//			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//			return RES_BREAK;
//		}
//
//		fDamageWeight = 1.0f;		// 2005-12-13 by cmkwon
//// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
////		// 2형 무기는 오차각 계산 없음
////		fDistance = D3DXVec3Length(&(A2DX(pMsgAttackFind->TargetInfo.TargetPosition) - pTargetCharacter->PositionVector));
////
////		if (IS_SECONDARY_WEAPON(pAttackItem->Kind) && pAttackItem->ExplosionRange > 0)
////		{
////			fDamageWeight
////				= CalcSplashDamageWeightByExposionRange(C2C, pAttackItem, &this->m_ParamFactor, fDistance, 10);
//////			DBGOUT("	Distance(%5.1f) ExplosionRange(%d) ==> DamageWeight(%4.2f)\n",
//////				fDistance, pAttackItem->ExplosionRange, fDamageWeight);
////		}
////		else
////		{
////			fDamageWeight = 1.0f;
////		}
//
//		if (fDamageWeight > 0.0f)
//		{
//			pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//			fDamage = CalcDamageOfAttack(C2C, fDamageWeight, this,		// @Process_FC_BATTLE_ATTACK_FIND(), C2C
//				&m_character, pTargetSocket, &pTargetSocket->m_character, pAttackItem,
//				&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));
//			pTargetSocket->m_uidAttackerGuildUID = 0;
//		}
//
//#ifdef _DEBUG
//		pTargetSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0032, this->m_character.CharacterName, fDamage);
//		SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0033, pTargetCharacter->CharacterName, fDamage);
//#endif
//	}
//	else if (eAttack2Target == C2M)
//	{
//		if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgAttackFind->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pTargetMonster))
//		{
//			pMsgAttackFindOK->TargetIndex = 0;
//			pMsgAttackFindOK->TargetItemFieldIndex = 0;
//			///////////////////////////////////////////////////////////////////////////////
//			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//			return RES_BREAK;
//		}
//
//		fDamageWeight = 1.0f;		// 2005-12-13 by cmkwon
//// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
////		// 2형 무기는 오차각 계산 없음
////		fDistance = D3DXVec3Length(&(A2DX(pMsgAttackFind->TargetInfo.TargetPosition) - pTargetMonster->PositionVector));
////
////		if (IS_SECONDARY_WEAPON(pAttackItem->Kind) && pAttackItem->ExplosionRange > 0)
////		{
////			fDamageWeight
////				= CalcSplashDamageWeightByExposionRange(C2M, pAttackItem, &this->m_ParamFactor, fDistance, pTargetMonster->MonsterInfoPtr->Size);
////		}
////		else
////		{
////			fDamageWeight = 1.0f;
////		}
//
//		if (fDamageWeight > 0.0f)
//		{
//			fDamage = CalcDamageOfAttack(C2M, fDamageWeight, this,		// @Process_FC_BATTLE_ATTACK_FIND(), C2M
//				&m_character, pTargetSocket, pTargetMonster, pAttackItem,
//				&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));
//		}
//
//#ifdef _DEBUG
//		this->SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0034, pTargetMonster->MonsterIndex, fDamage, (int)fDamage);
//#endif
//
//		///////////////////////////////////////////////////////////////////////
//		// Attack 정보를 NPC에게 보냄
//		INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, SendBuf);
//		pSetAttackChar->ChannelIndex = m_character.MapChannelIndex.ChannelIndex;
//		pSetAttackChar->AttackIndex = pMsgAttackFindOK->AttackIndex;
//		pSetAttackChar->TargetIndex = pMsgAttackFindOK->TargetIndex;
//		pSetAttackChar->DamageAmount = fDamage;
//		pSetAttackChar->ItemKind = pAttackItem->Kind;
//		m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));
//
//// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
////		///////////////////////////////////////////////////////////////////////
////		// splash damage 적용
////		ProcessSplashDamage(C2M, this, &m_character, A2DX(pMsgAttackFind->TargetInfo.TargetPosition), pAttackItem, pMsgAttackFind->TargetInfo.TargetIndex);
//	}
//	else if (eAttack2Target == C2I)
//	{
//	}
//	else if (eAttack2Target == C2CI)
//	{
//		// 피공격자가 Dummy를 달고 있을 때
//		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//		{
//			pMsgAttackFindOK->TargetIndex			= 0;
//			pMsgAttackFindOK->TargetItemFieldIndex	= 0;
//			///////////////////////////////////////////////////////////////////////////////
//			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//			return RES_BREAK;
//		}
//// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
////		// lock m_mapFieldDummy
////		mt_auto_lock dummyLock(&pTargetSocket->m_mapFieldDummy);
////
////		if (!pTargetSocket->m_mapFieldDummy.empty())
////		{
////			FIELD_DUMMY *pTargetDummy = pTargetSocket->m_mapFieldDummy.findLock(pMsgAttackFind->TargetInfo.TargetItemFieldIndex);
////
////			if (pTargetDummy == NULL)
////			{
////				DamageKind = DAMAGEKIND_NORMAL;
////				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
////				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK_FIND(), C2CI
////					&m_character, pTargetSocket, pTargetCharacter,
////					pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
////				pTargetSocket->m_uidAttackerGuildUID = 0;
////#ifdef _DEBUG
////				SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0035, pTargetCharacter->CharacterName, fDamage);
////#endif
////			}
////			else
////			{
////				DamageKind = DAMAGEKIND_NORMAL;
////				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
////				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK_FIND(), C2CI
////					&m_character, pTargetSocket, pTargetCharacter,
////					pAttackItem, &DamageKind, pTargetCharacter->PositionVector,
////					0.0f, 0.0f, pTargetDummy->ItemFieldIndex);
////				pTargetSocket->m_uidAttackerGuildUID = 0;
////#ifdef _DEBUG
////				SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0036, pTargetCharacter->CharacterName, fDamage);
////#endif
////			}
////		}
//		// 2006-12-04 by dhjin, 아래와 같이 수정
//		DamageKind = DAMAGEKIND_NORMAL;
//		pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//		fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_ATTACK_FIND(), C2CI
//			&m_character, pTargetSocket, pTargetCharacter,
//			pAttackItem, &DamageKind, pTargetCharacter->PositionVector);
//		pTargetSocket->m_uidAttackerGuildUID = 0;
//
//	}
//	else if (eAttack2Target == C2NULL)
//	{
//#ifdef _DEBUG
//		SendString128(STRING_128_DEBUG_L2, "NULL Target by Client");
//#endif
//		// set null target
//		pMsgAttackFindOK->TargetIndex = 0;
//		pMsgAttackFindOK->TargetItemFieldIndex = 0;
//	}
//	else if (eAttack2Target == M2C)
//	{
//		if(!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//		{
//			pMsgAttackFindOK->TargetIndex = 0;
//			pMsgAttackFindOK->TargetItemFieldIndex = 0;
//			///////////////////////////////////////////////////////////////////////////////
//			// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//			SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);
//			return RES_BREAK;
//		}
//
//		fDamageWeight = 1.0f;		// 2005-12-13 by cmkwon
//// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
////		// 2형 무기는 오차각 계산 없음
////		fDistance = D3DXVec3Length(&(A2DX(pMsgAttackFind->TargetInfo.TargetPosition) - pTargetCharacter->PositionVector));
////
////		if (IS_SECONDARY_WEAPON(pAttackItem->Kind) && pAttackItem->ExplosionRange > 0)
////		{
////			fDamageWeight
////				= CalcSplashDamageWeightByExposionRange(M2C, pAttackItem, NULL, fDistance, 10);
////		}
////		else
////		{
////			fDamageWeight = 1.0f;
////		}
//
//		if (fDamageWeight > 0.0f)
//		{
//			fDamage = CalcDamageOfAttack(M2C, fDamageWeight, NULL,		// @Process_FC_BATTLE_ATTACK_FIND(), M2C
//				pAttackMonster, pTargetSocket, (void*)pTargetCharacter, pAttackItem,
//				&DamageKind, A2DX(pMsgAttackFind->TargetInfo.TargetPosition));
//		}
//
//#ifdef _DEBUG
//		pTargetSocket->SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0037, pAttackMonster->MonsterInfoPtr->MonsterUnitKind, fDamage);
//#endif
//	}
//	else if (eAttack2Target == M2I)
//	{
//	}
//	else if (eAttack2Target == M2CI)
//	{
//	}
//	else if (eAttack2Target == M2NULL)
//	{
//	}
//	else
//	{
//		// cannot handle type
//		return RES_BREAK;
//	}
//
//	///////////////////////////////////////////////////////////////////////
//	// ATTACK_FIND_OK 전송
//	// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
//	SendInRangeMessageAroundMe(pMsgAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_FIND_OK), TRUE);	
//	return RES_RETURN_TRUE;
//}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_DROP_MINE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_DROP_MINE,
									MSG_FC_BATTLE_DROP_MINE, pMsgDropMine);
	nBytesUsed += pMsgDropMine->NumOfMines * sizeof(AVECTOR3);

	// 마인이 장전되어있는지 확인
	if (m_ItemWingOut.ItemNum == NULL || m_ItemWingOut.Kind != ITEMKIND_MINE)
	{
		SendErrorMessage(T_FC_BATTLE_DROP_MINE, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	// lock m_setCharacDropMine
	mt_auto_lock mineLock(&m_setCharacDropMine);

	// 한 캐릭터당 뿌려질 수 있는 최대 마인의 개수 설정
	int nCountDropMineAtATime = CAtumSJ::GetCountMineAtATime(&m_ItemWingOut, &m_ParamFactor);

	int nTotalDropMine = m_setCharacDropMine.size();
	if (nTotalDropMine >= nCountDropMineAtATime)
	{
#ifdef _DEBUG
	SendString128(STRING_128_ADMIN_CMD, "Total Mine: %d + %d = %d", nTotalDropMine, 0, nTotalDropMine);
#endif
		return RES_BREAK;
	}

	ITEM_GENERAL *pItem = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
	int nNumDropMine = min(pMsgDropMine->NumOfMines, nCountDropMineAtATime-nTotalDropMine);
#ifdef _DEBUG
	assert(nCountDropMineAtATime >= nTotalDropMine);
	SendString128(STRING_128_ADMIN_CMD, "Total Mine: %d + %d = %d", nTotalDropMine, nNumDropMine, nTotalDropMine+nNumDropMine);
#endif

	if (!(nNumDropMine = OnSecondaryAttack(nNumDropMine)))	// DROP_MINE
	{
		return RES_BREAK;
	}

	AVECTOR3 *ArrMinePositions = (AVECTOR3*)(((char*)pMsgDropMine) + sizeof(MSG_FC_BATTLE_DROP_MINE));
	// 이 msg를 loop 안에서 재활용함
	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_DROP_MINE_OK, T_FC_BATTLE_DROP_MINE_OK, pMsgDropMineOK, pMsgDropMineOKBuf);
	pMsgDropMineOK->ItemNum = pItem->ItemNum;
	pMsgDropMineOK->AttackIndex = m_character.ClientIndex;
	pMsgDropMineOK->TargetIndex	= pMsgDropMine->TargetIndex;
	pMsgDropMineOK->RemainedBulletFuel = pItem->CurrentCount;
	for (int i = 0; i < nNumDropMine; i++)
	{
		D3DXVECTOR3 tmpMinePosition = A2DX(ArrMinePositions[i]);

		CMapBlock *pMapBlock = m_pCurrentFieldMapChannel->GetBlock(tmpMinePosition.x, tmpMinePosition.z);
		if (pMapBlock == NULL)
		{
			SendErrorMessage(T_FC_BATTLE_DROP_MINE, ERR_PROTOCOL_INVALID_POSITION, (int)tmpMinePosition.x, (int)tmpMinePosition.z, pItem->ItemInfo->ItemName);
			continue;
		}

		DROPMINE *pDropMine					= new DROPMINE;
		pDropMine->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pDropMine->ClientIndex				= m_character.ClientIndex;
		pDropMine->Position					= tmpMinePosition;
		pDropMine->dwStartTick				= GetTickCount();
		pDropMine->pItemInfo				= pItem->ItemInfo;

		// 캐릭터의 drop mine list에 삽입
		m_setCharacDropMine.insertLock(pDropMine);

		// Map Block에 삽입
		pMapBlock->m_setMapBlockDropMine.insertLock(pDropMine);

		pMsgDropMineOK->ItemFieldIndex = (UINT)pDropMine;
		pMsgDropMineOK->DropPosition = ArrMinePositions[i];

//#ifdef _DBUG
//DBGOUT("ShowMine(%d): %#x[%d][%d]\n", pItem->ItemNum, pMsgDropMineOK->ItemFieldIndex, pMapBlock->m_x, pMapBlock->m_z);
//#endif
		if(FALSE == IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
		{
			ms_pFieldIOCP->SendInRangeMessageAroundPosition(tmpMinePosition, pMsgDropMineOKBuf,
				MSG_SIZE(MSG_FC_BATTLE_DROP_MINE_OK), m_pCurrentFieldMapChannel);
		}
		else
		{
			SendAddData(pMsgDropMineOKBuf, MSG_SIZE(MSG_FC_BATTLE_DROP_MINE_OK));
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_MINE_ATTACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_MINE_ATTACK,
									MSG_FC_BATTLE_MINE_ATTACK, pMsgMineAttack);

	enumAttackToTarget	eAttack2Target		= ERR2ERR;
	CFieldIOCPSocket	*pTargetSocket		= NULL;
	CFieldMonster		*pTargetMonster		= NULL;

	// lock m_setCharacDropMine
	mt_auto_lock mineLock(&m_setCharacDropMine);

	// 마인의 존재 여부 확인
	DROPMINE *pDropMine = (DROPMINE*)pMsgMineAttack->ItemFieldIndex;
	CMapBlock *pMapBlock = NULL;
	if (!IsValidDropMine(pDropMine, pMapBlock) || pMapBlock == NULL)
	{
		SendErrorMessage(T_FC_BATTLE_MINE_ATTACK, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	// AttackToTarget 결정
	eAttack2Target = CAtumSJ::GetAttackToTarget(m_character.ClientIndex, pMsgMineAttack->TargetInfo);
	if (eAttack2Target == ERR2ERR)
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////
	// 공격자와 피공격자에 따라 데미지 계산
	///////////////////////////////////////////////////////////////////////
	if (CAtumSJ::IsCharacterTarget(eAttack2Target))
	{
		// 유효성 확인
		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgMineAttack->TargetInfo.TargetIndex, pTargetSocket))
		{
			SendErrorMessage(T_FC_BATTLE_MINE_ATTACK, ERR_PROTOCOL_INVALID_CLIENTINDEX, pMsgMineAttack->TargetInfo.TargetIndex);
			return RES_BREAK;
		}

		// 공격 거리 확인
		if (D3DXVec3Length(&(pTargetSocket->m_character.PositionVector - pDropMine->Position)) > pDropMine->pItemInfo->Range)
		{
			SendErrorMessage(T_FC_BATTLE_MINE_ATTACK, ERR_PROTOCOL_TOO_FAR_TO_DO,
				D3DXVec3Length(&(pTargetSocket->m_character.PositionVector - pDropMine->Position)),
				pDropMine->pItemInfo->Range);
			return RES_BREAK;
		}
	}
	else if (CAtumSJ::IsMonsterTarget(eAttack2Target))
	{
		// 유효성 확인
		if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgMineAttack->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pTargetMonster))
		{
			return RES_BREAK;
		}

		// 공격 거리 확인
		if (D3DXVec3Length(&(pTargetMonster->PositionVector - pDropMine->Position)) > pDropMine->pItemInfo->Range)
		{
			SendErrorMessage(T_FC_BATTLE_MINE_ATTACK, ERR_PROTOCOL_TOO_FAR_TO_DO,
				D3DXVec3Length(&(pTargetMonster->PositionVector - pDropMine->Position)),
				pDropMine->pItemInfo->Range);
			return RES_BREAK;
		}
	}
	else if (CAtumSJ::IsItemTarget(eAttack2Target))
	{
		// 아이템 유효성 확인
		ASSERT_NOT_IMPLEMENTED_YET();
	}
	else
	{
		// error
		SendErrorMessage(T_FC_BATTLE_MINE_ATTACK, ERR_PROTOCOL_INVALID_TARGET_INDEX, pMsgMineAttack->TargetInfo.TargetIndex, pMsgMineAttack->TargetInfo.TargetItemFieldIndex);
		return RES_BREAK;
	}

	// Send MSG
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MINE_ATTACK_OK, T_FC_BATTLE_MINE_ATTACK_OK, pMsgMineAttackOK, pMsgMineAttackOKBuf);
	pMsgMineAttackOK->ItemFieldIndex = pMsgMineAttack->ItemFieldIndex;
	pMsgMineAttackOK->TargetInfo = pMsgMineAttack->TargetInfo;
	if(FALSE == IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropMine->Position, pMsgMineAttackOKBuf,
					MSG_SIZE(MSG_FC_BATTLE_MINE_ATTACK_OK), m_pCurrentFieldMapChannel);
	}
	else
	{
		SendAddData(pMsgMineAttackOKBuf, MSG_SIZE(MSG_FC_BATTLE_MINE_ATTACK_OK));
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_MINE_ATTACK_FIND(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_MINE_ATTACK_FIND,
									MSG_FC_BATTLE_MINE_ATTACK_FIND, pMsgMineAttackFind);

// 2007-06-08 by cmkwon, 현재는 사용하지 않는 프로토콜임
//	// AttackToTarget 결정
//	enumAttackToTarget eAttack2Target = CAtumSJ::GetAttackToTarget(m_character.ClientIndex, pMsgMineAttackFind->TargetInfo);
//	if (eAttack2Target == ERR2ERR)
//	{
//		return RES_BREAK;
//	}
////#ifdef _DEBUG
////	SendString128(STRING_128_USER_NOTICE, "MAF: %#08x", pMsgMineAttackFind->ItemFieldIndex);
////#endif
//
//	// lock m_setCharacDropMine
//	mt_auto_lock mineLock(&m_setCharacDropMine);
//
//	// 마인의 존재 여부 확인
//	DROPMINE *pDropMine = (DROPMINE*)pMsgMineAttackFind->ItemFieldIndex;
//	CMapBlock *pMapBlock = NULL;
//	if (!IsValidDropMine(pDropMine, pMapBlock) || pMapBlock == NULL)
//	{
//		SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_NO_SUCH_ITEM);
//		return RES_BREAK;
//	}
//
//	// 캐릭터의 drop mine list에서 삭제
//	m_setCharacDropMine.deleteLock(pDropMine);
//
//	// 마인 제거
//	pMapBlock->m_setMapBlockDropMine.deleteLock(pDropMine);
//
//
//	// 자동 변수로 변환 후 삭제, 이후에는 tmpDropMine만 사용하기, pDropMine 사용하면 err!
//	DROPMINE tmpDropMine = *pDropMine;
//	SAFE_DELETE(pDropMine);
//
//	// 데미지 처리
//	if (CAtumSJ::IsCharacterTarget(eAttack2Target))
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 공격 대상이 Character인 경우
//		///////////////////////////////////////////////////////////////////////
//
//		// 유효성 확인
//		CFieldIOCPSocket	*pTargetSocket		= NULL;
//		CHARACTER			*pTargetCharacter	= NULL;
//		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgMineAttackFind->TargetInfo.TargetIndex, pTargetSocket, pTargetCharacter))
//		{
//			// 2004-11-17 by cmkwon, 클라이언트에서 에러가 전혀 필요 없다고함
//			//SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_INVALID_CLIENTINDEX, pMsgMineAttackFind->TargetInfo.TargetIndex);
//			return RES_BREAK;
//		}
//
//// 2005-03-08 by cmkwon, 
////		// P2P PK 모드 혹은 파티전 일때만 처리됨
////		if (m_peerP2PPKClientIndex != pMsgMineAttackFind->TargetInfo.TargetIndex
////			&& (m_pFieldParty == NULL || m_pFieldParty->m_PeerBattlePartyID == 0)
////		)
////		{
////			SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_NOT_ALLOWED_ATTACK);
////			return RES_BREAK;
////		}
//
//		BYTE DamageKind = DAMAGEKIND_NO_DAMAGE;
//		float fDamage = 0.0f;
//
//		if (eAttack2Target == C2C)
//		{
//			// 반응 반경 확인 - 그 동안 공격 대상이 이동할 가능성이 높으므로 1.5배 정도를 곱해서 ReactionRange를 늘인다
//			if (D3DXVec3Length(&(tmpDropMine.Position - pTargetCharacter->PositionVector))
//					> 1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor))
//			{
//// 2004-12-08 by cmkwon, 클라이언트에서 필요없는 에러 처리
////				SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_TOO_FAR_TO_DO,
////					(int)D3DXVec3Length(&(tmpDropMine.Position - pTargetCharacter->PositionVector)),
////					(int)1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor));
//				DamageKind = DAMAGEKIND_NO_DAMAGE;
//				fDamage = 0.0f;
//			}
//			else
//			{
//				DamageKind = DAMAGEKIND_NORMAL;
//				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,	// @Process_FC_BATTLE_MINE_ATTACK_FIND()
//					&m_character, pTargetSocket, pTargetCharacter,
//					tmpDropMine.pItemInfo, &DamageKind, pTargetCharacter->PositionVector);
//				pTargetSocket->m_uidAttackerGuildUID = 0;
////#ifdef _DEBUG
////				SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0038, pTargetCharacter->CharacterName, fDamage);
////#endif
//			}
//
//			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK, T_FC_BATTLE_MINE_ATTACK_FIND_OK, pMsgMineAttackFindOK, pMsgMineAttackFindOKBuf);
//			pMsgMineAttackFindOK->ItemFieldIndex = pMsgMineAttackFind->ItemFieldIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetIndex = pTargetCharacter->ClientIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetItemFieldIndex = 0;
//			pMsgMineAttackFindOK->TargetInfo.TargetPosition = pMsgMineAttackFind->TargetInfo.TargetPosition;
//
//			ms_pFieldIOCP->SendInRangeMessageAroundPosition(tmpDropMine.Position, pMsgMineAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK), m_pCurrentFieldMapChannel);
//		}
//		else if (eAttack2Target == C2CI)
//		{
//// 2006-12-04 by dhjin, 체프 사출로 인하여 기존에 더미 소스 변경.
////			// 피공격자가 Dummy를 달고 있을 때
////
////			// lock m_mapFieldDummy
////			mt_auto_lock dummyLock(&pTargetSocket->m_mapFieldDummy);
////			if(pTargetSocket->m_mapFieldDummy.empty())
////			{
////				return RES_BREAK;
////			}
////
////			FIELD_DUMMY *pTargetDummy = (pTargetSocket->m_mapFieldDummy.begin())->second;
////
////			// 반응 반경 확인 - 그 동안 공격 대상이 이동할 가능성이 높으므로 1.5배 정도를 곱해서 ReactionRange를 늘인다
////			if (D3DXVec3Length(&(tmpDropMine.Position - pTargetCharacter->PositionVector))
////					> 1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor))
////			{
////// 2004-12-08 by cmkwon, 클라이언트에서 필요없는 에러 처리
//////				SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_TOO_FAR_TO_DO,
//////					(int)D3DXVec3Length(&(tmpDropMine.Position - pTargetCharacter->PositionVector)),
//////					(int)1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor));
////				DamageKind = DAMAGEKIND_NO_DAMAGE;
////				fDamage = 0.0f;
////			}
////			else
////			{
////				DamageKind = DAMAGEKIND_NORMAL;
////				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
////				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_MINE_ATTACK_FIND()
////					&m_character, pTargetSocket, pTargetCharacter,
////					tmpDropMine.pItemInfo, &DamageKind, pTargetCharacter->PositionVector,
////					0.0f, 0.0f, (pTargetDummy==NULL?NULL:pTargetDummy->ItemFieldIndex));
////				pTargetSocket->m_uidAttackerGuildUID = 0;
//////#ifdef _DEBUG
//////				SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0039, pTargetCharacter->CharacterName, fDamage);
//////#endif
////			}
//
//			// 2006-12-04 by dhjin, 아래와 같이 수정
//			// 반응 반경 확인 - 그 동안 공격 대상이 이동할 가능성이 높으므로 1.5배 정도를 곱해서 ReactionRange를 늘인다
//			if (D3DXVec3Length(&(tmpDropMine.Position - pTargetCharacter->PositionVector))
//					> 1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor))
//			{
//				DamageKind = DAMAGEKIND_NO_DAMAGE;
//				fDamage = 0.0f;
//			}
//			else
//			{
//				DamageKind = DAMAGEKIND_NORMAL;
//				pTargetSocket->m_uidAttackerGuildUID = this->m_character.GuildUniqueNumber;
//				fDamage = CalcDamageOfAttack(C2C, 1.0f, this,		// @Process_FC_BATTLE_MINE_ATTACK_FIND()
//					&m_character, pTargetSocket, pTargetCharacter,
//					tmpDropMine.pItemInfo, &DamageKind, pTargetCharacter->PositionVector,
//					0.0f, 0.0f);
//				pTargetSocket->m_uidAttackerGuildUID = 0;
//			}
//
//			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK, T_FC_BATTLE_MINE_ATTACK_FIND_OK, pMsgMineAttackFindOK, pMsgMineAttackFindOKBuf);
//			pMsgMineAttackFindOK->ItemFieldIndex = pMsgMineAttackFind->ItemFieldIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetIndex = pTargetCharacter->ClientIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetItemFieldIndex = 0;
//			pMsgMineAttackFindOK->TargetInfo.TargetPosition = pMsgMineAttackFind->TargetInfo.TargetPosition;
//
//			ms_pFieldIOCP->SendInRangeMessageAroundPosition(tmpDropMine.Position, pMsgMineAttackFindOKBuf, MSG_SIZE(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK), m_pCurrentFieldMapChannel);
//		}
//		else
//		{
//			//ASSERT_NOT_IMPLEMENTED_YET();
//		}
//	}
//	else if (CAtumSJ::IsMonsterTarget(eAttack2Target))
//	{
//		///////////////////////////////////////////////////////////////////////
//		// 공격 대상이 MONSTER인 경우
//		///////////////////////////////////////////////////////////////////////
//
//		// 유효성 확인
//		CFieldIOCPSocket	*pTargetNPCSocket	= NULL;
//		CFieldMonster		*pMonster			= NULL;
//		if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgMineAttackFind->TargetInfo.TargetIndex, m_character.MapChannelIndex.ChannelIndex, pMonster))
//		{
//			// 2004-11-17 by cmkwon, 클라이언트에서 에러가 전혀 필요 없다고함
//			//SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_INVALID_CLIENTINDEX, pMsgMineAttackFind->TargetInfo.TargetIndex);
//			return RES_BREAK;
//		}
//
//		D3DXVECTOR3 tmpExplosionPosition = pMonster->PositionVector;	// 나중에 splash damage에 쓰기 위해 할당
//		float fDamage = 0.0f;
//		// 반응 반경 확인 - 그 동안 공격 대상이 이동할 가능성이 높으므로 1.5배 정도를 곱해서 ReactionRange를 늘인다
//		if (D3DXVec3Length(&(tmpDropMine.Position - pMonster->PositionVector))
//				> 1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor))
//		{
//// 2004-12-08 by cmkwon, 클라이언트에서 필요없는 에러 처리
////			SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_TOO_FAR_TO_DO,
////				(int)D3DXVec3Length(&(tmpDropMine.Position - pMonster->PositionVector)),
////				(int)1.5f*CAtumSJ::GetReactionRange(tmpDropMine.pItemInfo, &m_ParamFactor));
//			fDamage = 0;
//		}
//		else
//		{
//			// 공격!
//			BYTE DamageKind = DAMAGEKIND_NORMAL;
//			fDamage = CalcDamageOfAttack(C2M, 1.0f, this,		// @Process_FC_BATTLE_MINE_ATTACK_FIND()
//				&m_character, pTargetNPCSocket, pMonster, tmpDropMine.pItemInfo,
//				&DamageKind, pMonster->PositionVector);
////#ifdef _DEBUG
////			SendString128(STRING_128_DEBUG_L3, STRMSG_S_F2NOTIFY_0040, pMonster->MonsterName, fDamage);
////#endif
//		}
//
//		// 마인 공격을 몬스터에게 알림
//		INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_SET_ATTACK_CHARACTER, T_FN_BATTLE_SET_ATTACK_CHARACTER, pSetAttackChar, pSetAttackCharBuf);
//		pSetAttackChar->ChannelIndex	= m_pCurrentFieldMapChannel->m_MapChannelIndex.ChannelIndex;
//		pSetAttackChar->AttackIndex		= m_character.ClientIndex;
//		pSetAttackChar->TargetIndex		= pMonster->MonsterIndex;
//		pSetAttackChar->DamageAmount	= fDamage;
//		pSetAttackChar->ItemKind		= ITEMKIND_MINE;
//		m_pCurrentFieldMapChannel->Send2NPCServerW(pSetAttackCharBuf, MSG_SIZE(MSG_FN_BATTLE_SET_ATTACK_CHARACTER));	// Attack 정보를 NPC에게 보냄
//
//		if(FALSE == IS_TUTORIAL_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
//		{
//			// 마인 공격 결과를 보냄, 자신은 제외
//			INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK, T_FC_BATTLE_MINE_ATTACK_FIND_OK, pMsgMineAttackFindOK, pMsgMineAttackFindOKBuf);
//			pMsgMineAttackFindOK->ItemFieldIndex					= pMsgMineAttackFind->ItemFieldIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetIndex			= pMonster->MonsterIndex;
//			pMsgMineAttackFindOK->TargetInfo.TargetItemFieldIndex	= 0;
//			pMsgMineAttackFindOK->TargetInfo.TargetPosition			= pMsgMineAttackFind->TargetInfo.TargetPosition;
//			ms_pFieldIOCP->SendInRangeMessageAroundPosition(tmpDropMine.Position, pMsgMineAttackFindOKBuf,
//				MSG_SIZE(MSG_FC_BATTLE_MINE_ATTACK_FIND_OK), m_pCurrentFieldMapChannel,	m_character.ClientIndex);
//		}
//
//// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
////		///////////////////////////////////////////////////////////////////
////		// splash damage 적용
////		ProcessSplashDamage(C2M, this, &m_character, tmpExplosionPosition, tmpDropMine.pItemInfo, pMsgMineAttackFind->TargetInfo.TargetIndex);
//	}
//	else
//	{
//		// error
//		SendErrorMessage(T_FC_BATTLE_MINE_ATTACK_FIND, ERR_PROTOCOL_INVALID_CLIENTINDEX, pMsgMineAttackFind->TargetInfo.TargetIndex);
//		return RES_BREAK;
//	}

	return RES_RETURN_TRUE;
}

// 2005-12-13 by cmkwon, splash damage를 서버에서는 전체 공격만 적용한다.
//float CFieldIOCPSocket::CalcSplashDamageWeightByExposionRange(enumAttackToTarget attackType
//															  , ITEM *pAttackItem
//															  , CParamFactor *i_pParamFactor
//															  , float fDistance
//															  , int i_nAddExplosionRange)
//{
//	return 1.0f;
//
//// 2005-07-29 by hblee : 거리체크는 없음.
////	float fDamageWeight = 0.0f;
////	float fTmpExplosionRange
////		= (i_pParamFactor==NULL?pAttackItem->ExplosionRange:CAtumSJ::GetExplosionRange(pAttackItem, i_pParamFactor)) + i_nAddExplosionRange;
////
////	if (fDistance > fTmpExplosionRange)
////	{
////		fDamageWeight = 0;
//////		SendString128(STRING_128_ADMIN_CMD, "SPLASH: %5.2f > %d -> 0%%", fDistance, fTmpExplosionRange);
////	}
////	else
////	{
////		if (attackType == C2M
////			&& (pAttackItem->Kind == ITEMKIND_BUNDLE || pAttackItem->Kind == ITEMKIND_ROCKET)
////		)
////		{
////			// C2M이면서 로켓이나 번들은 100% 다 주기
////			fDamageWeight = 1.0f;
////		}
////		else
////		{
////			// 나머지는 계산
////			fDamageWeight = ((fTmpExplosionRange - fDistance)/fTmpExplosionRange)*0.5f + 0.5f;
////		}
//////		SendString128(STRING_128_ADMIN_CMD, "SPLASH: 0 < %5.2f < %d -> %5.2f%%", fDistance, fTmpExplosionRange, fDamageWeight*100);
////	}
////
////	return fDamageWeight;
//}
//
//float CFieldIOCPSocket::CalcSplashDamageWeightByExposionRange(enumAttackToTarget attackType
//															  , ITEM *pAttackItem
//															  , CParamFactor *i_pParamFactor
//															  , float fDistance
//															  , BYTE *pDamageKind
//															  , int i_nAddExplosionRange)
//{
//	float fDamageWeight = 0.0f;
//	float fTmpExplosionRange
//		= (i_pParamFactor==NULL?pAttackItem->ExplosionRange:CAtumSJ::GetExplosionRange(pAttackItem, i_pParamFactor)) + i_nAddExplosionRange;
//
//	if (fDistance > fTmpExplosionRange)
//	{
//		*pDamageKind = DAMAGEKIND_NO_DAMAGE;
//		fDamageWeight = 0;
////		SendString128(STRING_128_ADMIN_CMD, "SPLASH: %5.2f > %d -> 0%%", fDistance, fTmpExplosionRange);
//	}
//	else
//	{
//		*pDamageKind = DAMAGEKIND_NORMAL;
//
//		if (attackType == C2M
//			&& (pAttackItem->Kind == ITEMKIND_BUNDLE || pAttackItem->Kind == ITEMKIND_ROCKET)
//		)
//		{
//			// C2M이면서 로켓이나 번들은 100% 다 주기
//			fDamageWeight = 1.0f;
//		}
//		else
//		{
//			// 나머지는 계산
//			fDamageWeight = ((fTmpExplosionRange - fDistance)/fTmpExplosionRange)*0.5f + 0.5f;
//		}
////		SendString128(STRING_128_ADMIN_CMD, "SPLASH: 0 < %5.2f < %d -> %5.2f%%", fDistance, fTmpExplosionRange, fDamageWeight*100);
//	}
//
//	return fDamageWeight;
//
///*	if (fDistance <= fPerfectDamageDistance)
//	{
//		return DAMAGEKIND_PERFECT;
//	}
//	else if (fDistance > fExplosionDistance)
//	{
//		return DAMAGEKIND_NO_DAMAGE;
//	}
//	else // if (fDistance > fPerfectDamageDistance && fDistance <= fExplosionDistance)
//	{
//#ifdef _DEBUG
//		assert(fDistance > fPerfectDamageDistance && fDistance <= fExplosionDistance);
//#endif
//		return (DAMAGE_100 - (DAMAGE_100 - fMinDamage)*(fDistance - fPerfectDamageDistance)/(fExplosionDistance - fPerfectDamageDistance));
//	}
//*/
//}

int CFieldIOCPSocket::CalcSplashDamageKindByMonsterAllAttack(ITEM *i_pAttackItem, float i_fDistance, int i_nAddExplosionRange)
{
	float fTmpExplosionRange = i_pAttackItem->ExplosionRange + i_nAddExplosionRange;
	if (i_fDistance > fTmpExplosionRange)
	{
		return DAMAGEKIND_NO_DAMAGE;
	}

	return DAMAGEKIND_NORMAL;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_DROP_DUMMY(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_DROP_DUMMY,
									MSG_FC_BATTLE_DROP_DUMMY, pMsgDropDummy);
// 2006-12-04 by dhjin, 더미를 체크로 수정했음
//	// lock m_mapFieldDummy
//	mt_auto_lock dummyLock(&m_mapFieldDummy);
//
//	// 더미가 돌고 있으면 무시함
//	if (!m_mapFieldDummy.empty())
//	{
//		SendErrorMessage(T_FC_BATTLE_DROP_DUMMY, ERR_PROTOCOL_ALREADY_ITEM_ACTIVATED, m_mapFieldDummy.size());
//		return RES_BREAK;
//	}
//
//	// 더미가 장전되어있는지 확인
//	if (m_ItemWingOut.ItemNum == NULL || m_ItemWingOut.Kind != ITEMKIND_DUMMY)
//	{
//		SendErrorMessage(T_FC_BATTLE_DROP_DUMMY, ERR_PROTOCOL_NO_SUCH_ITEM);
//		return RES_BREAK;
//	}
//
//	ITEM_GENERAL *pItem = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
//
//	// 더미는 한번에 다 쏜다.
//	int nNumOfDummies = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);
//
//	if (!(nNumOfDummies = OnSecondaryAttack(nNumOfDummies)))	// DROP_DUMMY
//	{
//		return RES_BREAK;
//	}
//
//	if (nNumOfDummies > 0)
//	{
//		INIT_MSG_WITH_BUFFER(MSG_FC_STORE_UPDATE_ITEM_COUNT, T_FC_STORE_UPDATE_ITEM_COUNT, pUpdateCount, pUpdateCountBuf);
//		pUpdateCount->ItemUniqueNumber = pItem->UniqueNumber;
//		pUpdateCount->ItemUpdateType = IUT_BULLET;
//		pUpdateCount->NewCount = pItem->CurrentCount;
//		SendAddData(pUpdateCountBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_ITEM_COUNT));
//	}
//
//	// 이 msg를 loop 안에서 재활용함
//	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_DROP_DUMMY_OK, T_FC_BATTLE_DROP_DUMMY_OK, pMsgDropDummyOK, pMsgDropDummyOKBuf);
//	pMsgDropDummyOK->ItemNum = pItem->ItemNum;
//	pMsgDropDummyOK->AttackIndex = m_character.ClientIndex;
//	for (int i = 0; i < nNumOfDummies; i++)
//	{
//		FIELD_DUMMY *pFieldDummy = new FIELD_DUMMY(pItem->ItemInfo);
//
//		// m_mapFieldDummy에 삽입
//		m_mapFieldDummy.insertLock((UINT)pFieldDummy, pFieldDummy);
//
//		// 구조체 나머지부분 완성
//		pMsgDropDummyOK->ItemFieldIndex = (UINT)pFieldDummy;
//#ifdef _DEBUG
//		SendString128(STRING_128_ADMIN_CMD, "DropDummy[%#08x] == [%#08x]\r\n", pMsgDropDummyOK->ItemFieldIndex, pFieldDummy->ItemFieldIndex);
//#endif
//
//		ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, pMsgDropDummyOKBuf, MSG_SIZE(MSG_FC_BATTLE_DROP_DUMMY_OK)
//			, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
//
//		m_TimerManager.StartTimerField(TE_TYPE_DELETE_DUMMY, m_ItemWingOut.Time, (UINT)pFieldDummy);
//	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_DROP_FIXER(const char* pPacket, int nLength, int &nBytesUsed)
{
	MSG_FC_BATTLE_DROP_FIXER	*pMsgDropFixer;
	int							nRecvTypeSize;
	CFieldIOCPSocket			*pPeerFieldIOCPSocket = NULL;
	CHARACTER					*pCharacter = NULL;
	CFieldMonster				*pMonster = NULL;
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_DROP_FIXER_OK, T_FC_BATTLE_DROP_FIXER_OK, pMsgDropFixerOK, pMsgDropFixerOKBuf);

	pMsgDropFixer = (MSG_FC_BATTLE_DROP_FIXER*)(pPacket+nBytesUsed);
	nRecvTypeSize = sizeof(MSG_FC_BATTLE_DROP_FIXER);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_BATTLE_DROP_FIXER, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14030);
		return RES_RETURN_FALSE;
	}
	nBytesUsed += nRecvTypeSize;

	// 픽서가 장전되어있는지 확인
	if (m_ItemWingOut.ItemNum == NULL || m_ItemWingOut.Kind != ITEMKIND_FIXER)
	{
		SendErrorMessage(T_FC_BATTLE_DROP_FIXER, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItem = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;

	int nNumOfFixers = CAtumSJ::GetTotalSecondaryShotCountPerReattackTime(&m_ItemWingOut, &m_ParamFactor);

	if ((nNumOfFixers = OnSecondaryAttack(nNumOfFixers)) <= 0)	// DROP_FIXER
	{
		return RES_BREAK;
	}

	if (nNumOfFixers > 0)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_STORE_UPDATE_ITEM_COUNT, T_FC_STORE_UPDATE_ITEM_COUNT, pUpdateCount, pUpdateCountBuf);
		pUpdateCount->ItemUniqueNumber = pItem->UniqueNumber;
		pUpdateCount->ItemUpdateType = IUT_BULLET;
		pUpdateCount->NewCount = pItem->CurrentCount;
		SendAddData(pUpdateCountBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_ITEM_COUNT));
	}

	// 허공에 발사
	if (pMsgDropFixer->TargetIndex == 0)
	{
		for (int i = 0; i < nNumOfFixers; i++)
		{
			// 메시지 전송
			pMsgDropFixerOK->AttackIndex = m_character.ClientIndex;
			pMsgDropFixerOK->TargetIndex = 0;
			pMsgDropFixerOK->ItemNum = pItem->ItemNum;
			pMsgDropFixerOK->ItemFieldIndex = 0;

			SendAddData(pMsgDropFixerOKBuf, MSG_SIZE(MSG_FC_BATTLE_DROP_FIXER_OK));
		}

		return RES_RETURN_TRUE;
	}

	if (pMsgDropFixer->TargetIndex < MONSTER_CLIENT_INDEX_START_NUM)
	{
		///////////////////////////////////////////////////////////////////////
		// 피공격자가 캐릭터인 경우
		///////////////////////////////////////////////////////////////////////
		if (!CheckValidAttackTargetCharacter(m_pCurrentFieldMapChannel, pMsgDropFixer->TargetIndex, pPeerFieldIOCPSocket, pCharacter))
		{
			return RES_BREAK;
		}

		for (int i = 0; i < nNumOfFixers; i++)
		{
			// Timer 시작
			UID32_t TimerUID
				= pPeerFieldIOCPSocket->m_TimerManager.StartTimerField(TE_TYPE_DELETE_FIXER, m_ItemWingOut.Time, pMsgDropFixer->TargetIndex, pItem->Kind);

			// 메시지 전송
			pMsgDropFixerOK->AttackIndex = m_character.ClientIndex;
			pMsgDropFixerOK->TargetIndex = pMsgDropFixer->TargetIndex;
			pMsgDropFixerOK->ItemNum = pItem->ItemNum;
			pMsgDropFixerOK->ItemFieldIndex = (UINT)TimerUID;

			ms_pFieldIOCP->SendInRangeMessageAroundCharacter(pCharacter->ClientIndex, pMsgDropFixerOKBuf, MSG_SIZE(MSG_FC_BATTLE_DROP_FIXER_OK)
				, m_pCurrentFieldMapChannel, TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
		}
	}
	else
	{
		///////////////////////////////////////////////////////////////////////
		// 피공격자가 몬스터인 경우
		///////////////////////////////////////////////////////////////////////
		if (!CheckValidAttackTargetMonster(m_character.InfluenceType, pMsgDropFixer->TargetIndex, m_character.MapChannelIndex.ChannelIndex, pMonster))
		{
			return RES_BREAK;
		}

		for (int i = 0; i < nNumOfFixers; i++)
		{
			// 메시지 전송
			INIT_MSG_WITH_BUFFER(MSG_FN_BATTLE_DROP_FIXER, T_FN_BATTLE_DROP_FIXER, pFNDropFixer, pFNDropFixerBuf);
			pFNDropFixer->ChannelIndex = m_character.MapChannelIndex.ChannelIndex;
			pFNDropFixer->AttackIndex = m_character.ClientIndex;
			pFNDropFixer->TargetIndex = pMsgDropFixer->TargetIndex;
			pFNDropFixer->ItemNum = pItem->ItemNum;

			m_pCurrentFieldMapChannel->Send2NPCServerW(pFNDropFixerBuf, MSG_SIZE(MSG_FN_BATTLE_DROP_FIXER));
		}
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_TOGGLE_SHIELD(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 쉴드가 장전되어있는지 확인
	if (m_ItemWingOut.ItemNum == NULL || m_ItemWingOut.Kind != ITEMKIND_SHIELD)
	{
		SendErrorMessage(T_FC_BATTLE_TOGGLE_SHIELD, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if (!OnSecondaryAttack(1))	// TOGGLE_SHIELD
	{
		return RES_BREAK;
	}

	BOOL IsOn;
	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_SHIELD_MASK))
	{
		// 쉴드 작동 상태이면
		ClearBodyConditionBit(m_character.BodyCondition, BODYCON_SHIELD_MASK);
		IsOn = FALSE;
	}
	else
	{
		// 쉴드 작동 상태가 아니면
		SetBodyConditionBit(m_character.BodyCondition, BODYCON_SHIELD_MASK);
		IsOn = TRUE;
	}

	ITEM_GENERAL	*pItemShield = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;
	ITEM			*pItemInfo = pItemShield->ItemInfo;

	INIT_MSG_OF_SIZE(MSG_FC_BATTLE_TOGGLE_SHIELD_RESULT, T_FC_BATTLE_TOGGLE_SHIELD_RESULT, pToggleShieldResult, pToggleShieldResultBuf);
	pToggleShieldResult->AttackIndex = m_character.ClientIndex;
	pToggleShieldResult->IsOn = IsOn;
	pToggleShieldResult->ItemNum = pItemShield->ItemNum;
	SendInRangeMessageAroundMe(pToggleShieldResultBuf, MSG_SIZE(MSG_FC_BATTLE_TOGGLE_SHIELD_RESULT), TRUE);

	m_TimerManager.StartTimerField(TE_TYPE_GRADUAL_SHIELD_UP, TIMER_GRADUAL_UP_INTERVAL,
					HIDWORD(pItemShield->UniqueNumber), LODWORD(pItemShield->UniqueNumber), pItemShield->ItemNum);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_TOGGLE_DECOY(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 디코이가 장전되어있는지 확인
	if (m_ItemWingOut.ItemNum == NULL || m_ItemWingOut.Kind != ITEMKIND_DECOY)
	{
		SendErrorMessage(T_FC_BATTLE_TOGGLE_DECOY, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if (!OnSecondaryAttack(1))	// TOGGLE_DECOY
	{
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemDecoy = (ITEM_GENERAL*)m_ItemWingOut.ItemNum;

	BOOL IsOn;
	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DECOY_MASK))
	{
		// Decoy 작동 상태이면
		StopItemKindDecoy(pItemDecoy->ItemInfo);
		return RES_RETURN_TRUE;
	}
	else
	{
		// Decoy 작동 상태가 아니면
		SetBodyConditionBit(m_character.BodyCondition, BODYCON_DECOY_MASK);

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 		SetParamFactor(&m_ParamFactor, m_ItemWingOut.DestParameter1, m_ItemWingOut.ParameterValue1);
// 		SetParamFactor(&m_ParamFactor, m_ItemWingOut.DestParameter2, m_ItemWingOut.ParameterValue2);
// 		SetParamFactor(&m_ParamFactor, m_ItemWingOut.DestParameter3, m_ItemWingOut.ParameterValue3);
// 		SetParamFactor(&m_ParamFactor, m_ItemWingOut.DestParameter4, m_ItemWingOut.ParameterValue4);
		for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
		{
			SetParamFactor(&m_ParamFactor, m_ItemWingOut.ArrDestParameter[i], m_ItemWingOut.ArrParameterValue[i]);
		}

		IsOn = TRUE;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_TOGGLE_DECOY_OK, T_FC_BATTLE_TOGGLE_DECOY_OK, pToggleDecoyOK, pToggleDecoyOKBuf);
	pToggleDecoyOK->AttackIndex = m_character.ClientIndex;
	pToggleDecoyOK->IsOn = IsOn;
	pToggleDecoyOK->ItemNum = pItemDecoy->ItemNum;
	SendInRangeMessageAroundMe(pToggleDecoyOKBuf, MSG_SIZE(MSG_FC_BATTLE_TOGGLE_DECOY_OK), TRUE);

	m_TimerManager.StartTimerField(TE_TYPE_DELETE_DECOY, TIMER_DECOY_TIME_CHECK_INTERVAL, (UINT)pItemDecoy);

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ATTACK_EVASION(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-12 ~ 2005-12-12
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ATTACK_EVASION(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_BATTLE_ATTACK_EVASION,
		MSG_FC_BATTLE_ATTACK_EVASION, pREvasion);

	// 2형 무기 공격만 해당, 1형은 무시
	if (IS_PRIMARY_ATT_TYPE(pREvasion->AttackType))
	{
		return RES_BREAK;
	}

	if(FALSE == this->IsValidCharacter())
	{
		return RES_BREAK;
	}

	// AttackToTarget 결정
	enumAttackToTarget	eAttack2Target		= CAtumSJ::GetAttackToTarget(pREvasion->AttackIndex, pREvasion->TargetInfo);
	if (eAttack2Target == ERR2ERR)
	{
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-12-12 by cmkwon, 캐릭터가 공격하는 것만 처리
	switch(eAttack2Target)
	{
	case C2C:
	case C2M:
	case C2I:
	case C2CI:
	case M2C:		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 멀티 타겟 추가로 다른 유저 롤링으로 피한 미사일 정보가 보여야한다.
		break;
	default:
		{
			return RES_BREAK;
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_ATTACK_EVASION_OK, T_FC_BATTLE_ATTACK_EVASION_OK, pSEvasionOK, SendBuf);
	*pSEvasionOK		= *pREvasion;
	///////////////////////////////////////////////////////////////////////////////
	// 2005-04-18 by cmkwon, 튜토리얼맵관련 처리는 SendInRangeMessageAroundCharacter_()함수 내에서 처리되어 있음
	SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_BATTLE_ATTACK_EVASION_OK), FALSE);
	return RES_RETURN_TRUE;
}

// 2004-12-27 by cmkwon, 사용하지 않음
//ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_REQUEST_PK(const char* pPacket, int nLength, int &nBytesUsed)
//{
//	/////////////////
//	// NO BODY 임!
//
//	TILEINFO *pTileInfo = m_pCurrentFieldMapChannel->m_pFieldMapProject->GetTileInfo(m_character.PositionVector.x, m_character.PositionVector.z);
//	if (pTileInfo == NULL)
//	{
//		SendErrorMessage(T_FC_BATTLE_REQUEST_PK, ERR_PROTOCOL_INVALID_POSITION);
//		return RES_BREAK;
//	}
//
//	if (pTileInfo->m_bPKType == PK_TYPE_PK)
//	{
//		m_bPKMode = TRUE;
//
//		INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_REQUEST_PK_OK, T_FC_BATTLE_REQUEST_PK_OK, pMsgPKOK, pMsgPKOKBuf);
//		pMsgPKOK->ClientIndex = m_character.ClientIndex;
//		SendAddData(pMsgPKOKBuf, MSG_SIZE(MSG_FC_BATTLE_REQUEST_PK_OK));
//	}
//	else
//	{
//		// check: PK 지역이 아니면 무시한다.
//		return RES_RETURN_TRUE;
//	}
//
//	return RES_RETURN_TRUE;
//}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_REQUEST_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize;
	MSG_FC_BATTLE_REQUEST_P2P_PK	*pMsgRequestP2PPK;

	nRecvTypeSize = sizeof(MSG_FC_BATTLE_REQUEST_P2P_PK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14048);
		return RES_RETURN_FALSE;
	}
	pMsgRequestP2PPK = (MSG_FC_BATTLE_REQUEST_P2P_PK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// P2P PK의 자신의 Level 조건 확인
	if (FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_P2P_PK, m_character.Level)
		&& FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))	// 관리자는 허용
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED);
		return RES_BREAK;
	}

	// 자신이 이미 일대일 PK 중임
	if (IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_ALREADY_P2P_PK);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-11 by dhjin, 아레나 맵에서는 불가능하다.
	if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_ARENA_STATE);
		return RES_BREAK;
	}

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

	if(IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{// 2006-09-27 by cmkwon, 도시맵에서는 PvP 불가
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
		return RES_BREAK;
	}

	// 해당 캐릭터가 없음
	CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgRequestP2PPK->TargetClientIndex);
	if (NULL == pTargetSocket || !pTargetSocket->IsUsing())
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_COMMON_NO_SUCH_CHARACTER, pMsgRequestP2PPK->TargetClientIndex);
		return RES_BREAK;
	}

	// P2P PK의 상대방의 Level 조건 확인
	if (FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_P2P_PK, pTargetSocket->m_character.Level)
		&& FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))	// 관리자는 허용
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED);
		return RES_BREAK;
	}

//	// 상대방과의 Level 차이 확인
//	if (abs(m_character.Level - pTargetSocket->m_character.Level) > 5
//		&& !COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))	// 관리자는 허용
//	{
//		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_HIGH_LEVEL_GAP_TO_P2P_PK);
//		return RES_BREAK;
//	}

	// 상대방이 이미 PK 중임
	if (IS_VALID_CLIENT_INDEX(pTargetSocket->m_peerP2PPKClientIndex))
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_ALREADY_P2P_PK, pMsgRequestP2PPK->TargetClientIndex);
		return RES_BREAK;
	}
	
	if(BAZAAR_STATE_NONE != pTargetSocket->m_bazaarManager.GetBazaarState())
	{// 2006-07-31 by cmkwon, 개인 상점 체크 
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_USING_BAZAAR, 1);
		return RES_BREAK;
	}

	if(IS_CITY_MAP_INDEX(pTargetSocket->m_character.MapChannelIndex.MapIndex))
	{// 2006-09-27 by cmkwon, 도시맵에서는 PvP 불가
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
		return RES_BREAK;
	}

// 2008-04-28 by cmkwon, 버그 수정 - 다른 세력과는 1:1 전투 불가(G0009467) - 아래와 같이 수정
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2007-03-07 by cmkwon, 일반세력은 다른세력과 1:1 전투 불가
// 	if(COMPARE_INFLUENCE(this->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL) ^ COMPARE_INFLUENCE(pTargetSocket->GetCharacter()->InfluenceType, INFLUENCE_TYPE_NORMAL))
// 	{// 2007-03-07 by cmkwon, 둘중하나만 일반세력일때는 PvP 불가
// 		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED);
// 		return RES_BREAK;
// 	}
	if(this->GetCharacter()->InfluenceType != pTargetSocket->GetCharacter()->InfluenceType)
	{// 2008-04-28 by cmkwon, 버그 수정 - 다른 세력과는 1:1 전투 불가(G0009467)
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED);
		return RES_BREAK;
	}

	// 2014-04-15 by bckim, 버닝맵에서는 결투 불가
	if( ms_pFieldIOCP->IsBurningMap(m_character.MapChannelIndex.MapIndex))
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_NOT_WARP_BURNING_MAP);
		return RES_BREAK;
	}
	// End. 2014-04-15 by bckim, 버닝맵에서는 결투 불가

	// 거리가 멀어서 PK 불가
	if (D3DXVec3Length(&(m_character.PositionVector-pTargetSocket->m_character.PositionVector)) > REQUERED_P2P_PK_DISTANCE)
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_TOO_FAR_TO_P2P_PK);
		return RES_BREAK;
	}

	// 2005-11-03 by cmkwon, CharacterMode 체크
	if(GetCharacter()->CharacterMode != pTargetSocket->GetCharacter()->CharacterMode)
	{
		SendErrorMessage(T_FC_BATTLE_REQUEST_P2P_PK, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED);
		return RES_BREAK;
	}

	// 상대방을 setting (동시에 P2P PK인 상태로 바뀜)
	m_peerP2PPKClientIndex = pTargetSocket->m_character.ClientIndex;
	m_TimerManager.StartTimerField(TE_TYPE_REQUEST_TIMEOUT, FC_REQUEST_TIMEOUT_INTERVAL,
		REQUEST_TYPE_P2P_PK, m_character.ClientIndex, m_peerP2PPKClientIndex);
	
	pTargetSocket->m_peerP2PPKClientIndex = m_character.ClientIndex;
	pTargetSocket->m_TimerManager.StartTimerField(TE_TYPE_REQUEST_TIMEOUT, FC_REQUEST_TIMEOUT_INTERVAL,
		REQUEST_TYPE_P2P_PK, pTargetSocket->m_character.ClientIndex, pTargetSocket->m_peerP2PPKClientIndex);


	// MSG_FC_BATTLE_REQUEST_P2P_PK_OK 를 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_REQUEST_P2P_PK_OK, T_FC_BATTLE_REQUEST_P2P_PK_OK, pMsgRequestOK, pMsgRequestOKBuf);
	pMsgRequestOK->SourceClientIndex = m_character.ClientIndex;
	pTargetSocket->SendAddData(pMsgRequestOKBuf, MSG_SIZE(MSG_FC_BATTLE_REQUEST_P2P_PK_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ACCEPT_REQUEST_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize;
	MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK	*pMsgAcceptP2PPK;

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

	// PK를 요청한 사람이 다름
	if (pMsgAcceptP2PPK->SourceClientIndex != m_peerP2PPKClientIndex)
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}

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

	if(BAZAAR_STATE_NONE != pSourceSocket->m_bazaarManager.GetBazaarState())
	{// 2006-08-01 by cmkwon, 개인 상점 체크
		SendErrorMessage(T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK, ERR_USING_BAZAAR, 1);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}

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

	if(IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
	{// 2006-09-27 by cmkwon, 도시맵에서는 PvP 불가
		SendErrorMessage(T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
		return RES_BREAK;
	}

	// 2005-11-03 by cmkwon, MapChannelIndex 체크
	if(false == m_character.MapChannelIndex.IsSameMapChannelIndex(pSourceSocket->GetCharacter()->MapChannelIndex))
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
		SendP2PPKEndAndReset(pSourceSocket, TRUE);
		return RES_BREAK;
	}
	
	// 2005-11-03 by cmkwon, CharacterMode 체크
	if(GetCharacter()->CharacterMode != pSourceSocket->GetCharacter()->CharacterMode)
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED);
		SendP2PPKEndAndReset(pSourceSocket, TRUE);
		return RES_BREAK;
	}

	if(this->IsCityCurrentFieldMapChannel())
	{// 2005-11-03 by cmkwon, 도시맵일 경우
		// 2005-11-03 by cmkwon, 자신을 맵의 끝으로이동
		D3DXVECTOR3 tmVec3Pos(200, 0, 200);
		tmVec3Pos.y = GetCurrentFieldMapChannel()->GetMapHeightIncludeWaterW(&tmVec3Pos)+200;
		WarpToMap(GetCharacter()->MapChannelIndex.MapIndex, GetCharacter()->MapChannelIndex.ChannelIndex, &tmVec3Pos);
	
		// 2005-11-03 by cmkwon, 상대방을 맵의 반대편 끝으로 이동
		tmVec3Pos.x = GetCurrentFieldMapChannel()->GetSizeMapXW() - 200.0f;
		tmVec3Pos.y	= 0.0f;
		tmVec3Pos.z = GetCurrentFieldMapChannel()->GetSizeMapZW() - 200.0f;
		tmVec3Pos.y = GetCurrentFieldMapChannel()->GetMapHeightIncludeWaterW(&tmVec3Pos)+200;
		pSourceSocket->WarpToMap(GetCharacter()->MapChannelIndex.MapIndex, GetCharacter()->MapChannelIndex.ChannelIndex, &tmVec3Pos);
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_COUNTDOWN_START, T_FC_COUNTDOWN_START, pSMsg, pSendBuf);
	pSMsg->byCountdownType	= COUNTDOWN_TYPE_P2P_WAR;
	pSMsg->nWaitingSecond	= SECOND_COUNTDOWN_TIME_GAP;
	
	// 자신에게 전송
	this->SendAddData(pSendBuf, MSG_SIZE(MSG_FC_COUNTDOWN_START));
	this->m_countdownChecker.StartCountDown(pSMsg->byCountdownType, pSMsg->nWaitingSecond*1000, timeGetTime());

	// 상대방에게 전송
	pSourceSocket->SendAddData(pSendBuf, MSG_SIZE(MSG_FC_COUNTDOWN_START));
	pSourceSocket->m_countdownChecker.StartCountDown(pSMsg->byCountdownType, pSMsg->nWaitingSecond*1000, timeGetTime());

	// P2P PK 가 시작되었음!
	this->m_bP2PPKStarted			= TRUE;
	pSourceSocket->m_bP2PPKStarted	= TRUE;

// 2004-10-20 by cmkwon, 카운트 방식 수정
//	// Send MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK
//	INIT_MSG(MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK, T_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK, pMsgAcceptP2PPKOK, SendBuf);
//	// To Source
//	pMsgAcceptP2PPKOK->PeerClientIndex = m_character.ClientIndex;
//	pSourceSocket->SendAddData(SendBuf, MSG_SIZE(MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK));
//	// To Target
//	pMsgAcceptP2PPKOK->PeerClientIndex = m_peerP2PPKClientIndex;
//	SendAddData(SendBuf, MSG_SIZE(MSG_FC_BATTLE_ACCEPT_REQUEST_P2P_PK_OK));
//
//	// P2P PK 가 시작되었음!
//	m_bP2PPKStarted = TRUE;
//	pSourceSocket->m_bP2PPKStarted = TRUE;
//
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_REJECT_REQUEST_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize;
	MSG_FC_BATTLE_REJECT_REQUEST_P2P_PK	*pMsgRejectP2P;

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

	// PK 를 요청한 사람이 다름
	if (pMsgRejectP2P->SourceClientIndex != m_peerP2PPKClientIndex)
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_REQUEST_P2P_PK, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgRejectP2P->SourceClientIndex);
	if (NULL == pSourceSocket || !pSourceSocket->IsUsing())
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_REQUEST_P2P_PK, ERR_COMMON_NO_SUCH_CHARACTER);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_REJECT_REQUEST_P2P_PK_OK, T_FC_BATTLE_REJECT_REQUEST_P2P_PK_OK, pMsgRejectOK, pMsgRejectOKBuf);
	pMsgRejectOK->TargetClientIndex = m_character.ClientIndex;
	pSourceSocket->SendAddData(pMsgRejectOKBuf, MSG_SIZE(MSG_FC_BATTLE_REJECT_REQUEST_P2P_PK_OK));

	// PK reset
	m_peerP2PPKClientIndex = INVALID_CLIENT_INDEX;
	m_bP2PPKStarted = FALSE;
	pSourceSocket->m_peerP2PPKClientIndex = INVALID_CLIENT_INDEX;
	pSourceSocket->m_bP2PPKStarted = FALSE;

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_SURRENDER_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize;
	MSG_FC_BATTLE_SURRENDER_P2P_PK	*pMsgSurrender;

	nRecvTypeSize = sizeof(MSG_FC_BATTLE_SURRENDER_P2P_PK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_BATTLE_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14048);
		return RES_RETURN_FALSE;
	}
	pMsgSurrender = (MSG_FC_BATTLE_SURRENDER_P2P_PK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 일대일 PK 중이 아닌지 검사
	if (!IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		SendErrorMessage(T_FC_BATTLE_SURRENDER_P2P_PK, ERR_PROTOCOL_NOT_DOING_P2P_PK);
		return RES_BREAK;
	}

	// PK 대상자가 다름
	if (pMsgSurrender->TargetClientIndex != m_peerP2PPKClientIndex)
	{
		SendErrorMessage(T_FC_BATTLE_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	// 해당 캐릭터가 없음
	CFieldIOCPSocket *pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgSurrender->TargetClientIndex);
	if (NULL == pTargetSocket || FALSE == pTargetSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_BATTLE_SURRENDER_P2P_PK, ERR_COMMON_NO_SUCH_CHARACTER, pMsgSurrender->TargetClientIndex);
		return RES_BREAK;
	}

	// MSG_FC_BATTLE_SURRENDER_P2P_PK_OK 를 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_SURRENDER_P2P_PK_OK, T_FC_BATTLE_SURRENDER_P2P_PK_OK, pMsgSurrenderOK, pMsgSurrenderOKBuf);
	pMsgSurrenderOK->SourceClientIndex = m_character.ClientIndex;
	pTargetSocket->SendAddData(pMsgSurrenderOKBuf, MSG_SIZE(MSG_FC_BATTLE_SURRENDER_P2P_PK_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize;
	MSG_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK	*pMsgAcceptSurrender;

	nRecvTypeSize = sizeof(MSG_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14048);
		return RES_RETURN_FALSE;
	}
	pMsgAcceptSurrender = (MSG_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 일대일 PK 중이 아닌지 검사
	if (!IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK, ERR_PROTOCOL_NOT_DOING_P2P_PK);
		return RES_BREAK;
	}

	// PK 대상자가 다름
	if (pMsgAcceptSurrender->SourceClientIndex != m_peerP2PPKClientIndex)
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	// 해당 캐릭터가 없음
	CFieldIOCPSocket *pSourcetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgAcceptSurrender->SourceClientIndex);
	if (NULL == pSourcetSocket || FALSE == pSourcetSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_BATTLE_ACCEPT_SURRENDER_P2P_PK, ERR_COMMON_NO_SUCH_CHARACTER, pMsgAcceptSurrender->SourceClientIndex);
		return RES_BREAK;
	}

	// 일대일 대결 결과 처리
	OnP2PPKEnd(this, pSourcetSocket);

	return RES_RETURN_TRUE;
}


ProcessResult CFieldIOCPSocket::Process_FC_BATTLE_REJECT_SURRENDER_P2P_PK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize;
	MSG_FC_BATTLE_REJECT_SURRENDER_P2P_PK	*pMsgRejectSurrender;
	
	nRecvTypeSize = sizeof(MSG_FC_BATTLE_REJECT_SURRENDER_P2P_PK);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1404C);
		return RES_RETURN_FALSE;
	}
	pMsgRejectSurrender = (MSG_FC_BATTLE_REJECT_SURRENDER_P2P_PK*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;
	
	// 일대일 PK 중이 아닌지 검사
	if (!IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_SURRENDER_P2P_PK, ERR_PROTOCOL_NOT_DOING_P2P_PK);
		return RES_BREAK;
	}
	
	// PK 대상자가 다름
	if (pMsgRejectSurrender->SourceClientIndex != m_peerP2PPKClientIndex)
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_SURRENDER_P2P_PK, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}
	
	// 해당 캐릭터가 존재하지 않음, 게임에서 튕겼거나 접속이 끊길 경우 대비
	CFieldIOCPSocket *pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pMsgRejectSurrender->SourceClientIndex);
	if (NULL == pSourceSocket || FALSE == pSourceSocket->IsValidCharacter())
	{
		SendErrorMessage(T_FC_BATTLE_REJECT_SURRENDER_P2P_PK, ERR_COMMON_NO_SUCH_CHARACTER);
		SendP2PPKEndAndReset(NULL, FALSE);
		return RES_BREAK;
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_BATTLE_REJECT_SURRENDER_P2P_PK_OK, T_FC_BATTLE_REJECT_SURRENDER_P2P_PK_OK, pMsgRejectOK, pMsgRejectOKBuf);
	pMsgRejectOK->TargetClientIndex = m_character.ClientIndex;
	pSourceSocket->SendAddData(pMsgRejectOKBuf, MSG_SIZE(MSG_FC_BATTLE_REJECT_SURRENDER_P2P_PK_OK));
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_STORE_GET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_STORE_GET_ITEM,
		MSG_FC_STORE_GET_ITEM, pMsgGetStoreItem);
	
	if(m_character.AccountUniqueNumber != pMsgGetStoreItem->AccountUniqueNumber) 
	{ 
		SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER); 
		return RES_BREAK; 
	} 
	
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{// 2007-10-18 by cmkwon, 수정 함
		SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_STORE_GET_ITEM, 필드창고 사용 가능 여부 체크 
	if(m_ItemManager.GetUsingFieldStore())
	{
		if(ITEM_IN_GUILD_STORE == pMsgGetStoreItem->ItemStorage0)
		{
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_CANNOT_USE_GUILD_STORE, 10000);
			return RES_BREAK;
		}

		if(FALSE == m_ItemManager.IsUseableFieldStore())
		{
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_CANNOT_USE_FIELD_STORE, 11000);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-30 by cmkwon, 필드창고 비행중 이용 버그 수정(E0044710) - 캐릭터모드가 아니거나 정지상태가 아니면 필드창고 이용불가
		if(FALSE == GetCharacter()->CharacterMode
			&& FALSE == COMPARE_BODYCON_BIT(GetCharacter()->BodyCondition, BODYCON_STOP_MASK))
		{
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_CANNOT_USE_FIELD_STORE, 12000);
			return RES_BREAK;
		}
	}

	// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)
	if( TRUE == m_bProcessingStoreGetItem )
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Detected ItemCopyHack (%s) %s\r\n"
			, GetProtocolTypeString(T_FC_STORE_GET_ITEM), GetCharacterString(GetCharacter(), string()));

		SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_CANNOT_USE_STORE); 
		
		return RES_BREAK;
	}
	// end 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	if (ITEM_IN_GUILD_STORE == pMsgGetStoreItem->ItemStorage0)
	{// 2006-09-20 by dhjin, 여단 창고 사용시 
		UID32_t	GuildUID0 = m_character.GuildUniqueNumber;

		if (FALSE == IS_VALID_UNIQUE_NUMBER(GuildUID0))
		{// 2006-09-20 by dhjin, 여단 가입이 되어 있는지 체크
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_PROTOCOL_NOT_HAVE_GUILD);
			return RES_BREAK;
		}
		
		mt_auto_lock mtaGI(ms_pFieldIOCP->GetmtmapAllGuildItemPtrW());

		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// 2006-09-24 by cmkwon

// 2007-09-03 by cmkwon, 멤버쉼 서비스 수정 - 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
//		///////////////////////////////////////////////////////////////////////////////
//		// 2006-09-24 by cmkwon, 멤버십 서비스 체크
//		if (FALSE == m_ItemManager.IsExistPremiumCard())
//		{
//			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_NO_MEMBERSHIP_USER);
//			return RES_BREAK;
//		}

		if (LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType()
			&& FALSE == m_ItemManager.IsExistPremiumCard())
		{// 2007-10-15 by cmkwon, 베트남만 멤버쉽 유저만 여단창고 이용 가능, // 2007-10-10 by cmkwon, 멤버쉼 서비스 수정 - 예당만 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_NO_MEMBERSHIP_USER);
			return RES_BREAK;
		}

		DWORD dwCurTick = timeGetTime();
		CGuildItemManager *pGuildItemMan = ms_pFieldIOCP->GetGuildItemMangerNoLockW(GuildUID0);
		if(NULL == pGuildItemMan)
		{// 2006-09-20 by dhjin, 여단 창고가 m_pAllGuildItemManager에 있는지 체크

			pGuildItemMan	= new CGuildItemManager;
			pGuildItemMan->SetGuildUID(GuildUID0);
			pGuildItemMan->SetReqLoadLastTick(timeGetTime());
			ms_pFieldIOCP->InsertGuildItemManagerNoLockW(pGuildItemMan);

			igLock.auto_unlock_cancel();
			mtaGI.auto_unlock_cancel();

			m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

			QPARAM_GET_GUILDSTORE *pQParam = new QPARAM_GET_GUILDSTORE;
			pQParam->GuildUID			= GuildUID0;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetGuildStoreItem,this, m_character.AccountUniqueNumber, pQParam);
			return RES_RETURN_TRUE;
		}
		else if(FALSE == pGuildItemMan->GetIsLoaded())
		{
			DWORD dwCurTick = timeGetTime();

			if(dwCurTick - pGuildItemMan->GetReqLoadLastTick() < 5000)
			{
				SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_ALREADY_LOADING_GUILD_STORE);
				return RES_BREAK;
			}

			pGuildItemMan->SetReqLoadLastTick(dwCurTick);
			igLock.auto_unlock_cancel();
			mtaGI.auto_unlock_cancel();

			m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

			QPARAM_GET_GUILDSTORE *pQParam = new QPARAM_GET_GUILDSTORE;
			pQParam->GuildUID			= GuildUID0;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetGuildStoreItem,this, m_character.AccountUniqueNumber, pQParam);
			return RES_RETURN_TRUE;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2006-09-28 by dhjin, 로딩한지 10분이 경과 했다면 다시 로딩을 한다.
		if(dwCurTick - pGuildItemMan->GetReqLoadLastTick() > 600000)
		{
			pGuildItemMan->ResetGuildItemManager();
			pGuildItemMan->SetReqLoadLastTick(dwCurTick);
			igLock.auto_unlock_cancel();
			mtaGI.auto_unlock_cancel();

			m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

			QPARAM_GET_GUILDSTORE *pQParam = new QPARAM_GET_GUILDSTORE;
			pQParam->GuildUID			= GuildUID0;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetGuildStoreItem,this, m_character.AccountUniqueNumber, pQParam);
			return RES_RETURN_TRUE;
		}

		pGuildItemMan->SendGuildStoreItemList(this);
		return RES_RETURN_TRUE;
	}

	if (m_character.CharacterUniqueNumber != pMsgGetStoreItem->PossessCharacter)
	{// 2006-09-19 by dhjin, 계정에 케릭터가 존재하는지 체크

		// 2007-10-18 by cmkwon, 멤버쉽 유저만 타캐릭터 창고를 접근 할 수 있다
		if (FALSE == m_ItemManager.IsExistPremiumCard())
		{
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_NO_MEMBERSHIP_USER);
			return RES_BREAK;
		}

		if (FALSE == CheckCharacterUIDFormAccount(pMsgGetStoreItem->PossessCharacter))
		{
			SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_NO_SEARCH_CHARACTER, pMsgGetStoreItem->PossessCharacter);
			return RES_BREAK;
		}
	}
	
	m_bProcessingStoreGetItem = TRUE;		// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	MSG_FC_STORE_GET_ITEM *pQParam = new MSG_FC_STORE_GET_ITEM;
	*pQParam					= *pMsgGetStoreItem;
	pQParam->PossessCharacter	= pMsgGetStoreItem->PossessCharacter;
	pQParam->ItemStorage0		= ITEM_IN_STORE;		// 2005-12-07 by cmkwon
	pQParam->bMainGameStartFlag	= FALSE;				// 2012-11-21 by hskim, GLog 3차 빠진 부분 추가 작업
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetStoreItem, this, m_character.AccountUniqueNumber, pQParam);
	
	return RES_RETURN_TRUE;

//	if (pMsgGetStoreItem->PossessCharacter != this->GetCharacter()->CharacterUniqueNumber)
//	{
//		SendErrorMessage(T_FC_STORE_GET_ITEM, ERR_NO_MEMBERSHIP_USER);
//		return RES_BREAK;
//	}
//
//	//  처리
//	MSG_FC_STORE_GET_ITEM *pQParam = new MSG_FC_STORE_GET_ITEM;
//	*pQParam					= *pMsgGetStoreItem;
//	pQParam->PossessCharacter	= this->GetCharacter()->CharacterUniqueNumber;
//	pQParam->ItemStorage0		= ITEM_IN_STORE;		// 2005-12-07 by cmkwon
//	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetStoreItem, this, m_character.AccountUniqueNumber, pQParam);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_STORE_MOVE_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_STORE_MOVE_ITEM,
									MSG_FC_STORE_MOVE_ITEM, pMsgMoveItem);

	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_STORE)
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

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

	if (pMsgMoveItem->Count <= 0
		|| pMsgMoveItem->Count > MAX_ITEM_COUNTS)		// 2013-04-10 by hskim, 길드 창고에서 한번에 20억 꺼내지 못하는 버그 수정
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVALID_ITEM_COUNT);
		return RES_BREAK;
	}

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	if(INVALID_UNIQUE_NUMBER != m_peerTraderCharacterUniqueNumber
		&& 0 != m_peerTraderCharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_STORE_MOVE_ITEM
	if(m_ItemManager.GetUsingFieldStore())
	{
		if(ITEM_IN_GUILD_STORE == pMsgMoveItem->FromItemStorage	|| ITEM_IN_GUILD_STORE == pMsgMoveItem->ToItemStorage)
		{
 			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_CANNOT_USE_GUILD_STORE, 10000);
 			return RES_BREAK;			
		}

		if(FALSE == m_ItemManager.IsUseableFieldStore())
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_CANNOT_USE_FIELD_STORE, 11000);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-03-30 by cmkwon, 필드창고 비행중 이용 버그 수정(E0044710) - 캐릭터모드가 아니거나 정지상태가 아니면 필드창고 이용불가
		if(FALSE == GetCharacter()->CharacterMode
			&& FALSE == COMPARE_BODYCON_BIT(GetCharacter()->BodyCondition, BODYCON_STOP_MASK))
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_CANNOT_USE_FIELD_STORE, 12000);
			return RES_BREAK;
		}
	}

	// 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)
	if( TRUE == m_bProcessingStoreGetItem )
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Detected ItemCopyHack (%s) %s\r\n"
			, GetProtocolTypeString(T_FC_STORE_MOVE_ITEM), GetCharacterString(GetCharacter(), string()));

		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_CANNOT_USE_STORE); 	

		return RES_BREAK;
	}
	// end 2012-12-11 by hskim, 베트남 아이템 복사 버그 보안 (DB 처리가 끝날때까지 관련 패킷은 무시)

	// 2013-05-14 by bckim, 베트남 인피니티에서 아이템 창고이용 복사 버그 보완 
	if (  TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "HACKUSER!! Trying to use store in Arena server !! : HackingIP(%15s)\r\n", this->GetPeerIP());
		return RES_BREAK;
	}
	// End. 2013-05-14 by bckim, 베트남 인피니티에서 아이템 창고이용 복사 버그 보완 

	///////////////////////////////////////////////////////////////////////////////
	// 2006-09-25 by cmkwon, 여단창고<-->캐릭터인벤 이동 처리
	if(ITEM_IN_GUILD_STORE == pMsgMoveItem->FromItemStorage
		|| ITEM_IN_GUILD_STORE == pMsgMoveItem->ToItemStorage)
	{
		UID32_t GuildUID0	= m_character.GuildUniqueNumber;
		if(FALSE == IS_VALID_UNIQUE_NUMBER(GuildUID0))
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NOT_HAVE_GUILD);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2009-08-07 by cmkwon, 관리자, 운영자 여단창고 이용 막기 - 
		if(COMPARE_RACE(m_character.Race, RACE_ACCOUNT_TYPE_MASK)
			|| COMPARE_RACE(m_backupRace, RACE_ACCOUNT_TYPE_MASK))
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 11000, m_character.Race);
			return RES_BREAK;
		}

		if (ITEM_IN_GUILD_STORE == pMsgMoveItem->FromItemStorage
			&& GUILD_RANK_PRIVATE_NULL == m_GuildRank)
		{// 2006-09-25 by dhjin, 대원계급이면  여단 창고에서 찾는것 불가.
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NOT_RANK_DRAW_GUILD_STORE);
			return RES_BREAK;
		}

		mt_auto_lock mtaAGM(ms_pFieldIOCP->GetmtmapAllGuildItemPtrW());
		CGuildItemManager *pGuildItemMan = ms_pFieldIOCP->GetGuildItemMangerNoLockW(GuildUID0);
		if(NULL == pGuildItemMan)
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NO_SUCH_GUILD_STORE);
			return RES_BREAK;
		}

		mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral, MSG_FC_STORE_MOVE_ITEM
// 2007-09-03 by cmkwon, 멤버쉼 서비스 수정 - 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
//		if (FALSE == m_ItemManager.IsExistPremiumCard())
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NO_MEMBERSHIP_USER);
//			return RES_BREAK;
//		}
		if (LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType()
			&& FALSE == m_ItemManager.IsExistPremiumCard())
		{// 2007-10-15 by cmkwon, 베트남만 멤버쉽 유저만 여단창고 이용 가능, // 2007-10-10 by cmkwon, 멤버쉼 서비스 수정 - 예당만 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NO_MEMBERSHIP_USER);
			return RES_BREAK;
		}

		if(ITEM_IN_GUILD_STORE == pMsgMoveItem->ToItemStorage)
		{// 2006-09-21 by dhjin, 케릭터 인벤 --> 여단 창고
			
			
			ITEM_GENERAL *pItemGeneral				= m_ItemManager.GetItemGeneralByUID(pMsgMoveItem->ItemUniqueNumber, ITEM_IN_CHARACTER);
			ITEM_GENERAL *pItemGeneralInGuildStore	= NULL;
			
			if (NULL == pItemGeneral)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_STORE_MOVE_ITEM, 케릭터 인벤 --> 여단 창고
			if(FALSE == IS_VALID_UID64(pItemGeneral->UniqueNumber)
				|| pItemGeneral->UniqueNumber != pMsgMoveItem->ItemUniqueNumber
				|| pItemGeneral->Possess != GetCharacter()->CharacterUniqueNumber)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1002);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d, %d %d->%d, %d\r\n"
					, GetProtocolTypeString(T_FC_STORE_MOVE_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemGeneral, string()), pItemGeneral->Possess, pMsgMoveItem->ItemUniqueNumber, m_ItemManager.m_uid32StoreCharacterUID, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage, GuildUID0);
				return RES_BREAK;
			}
	
			if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM|ITEM_ATTR_ACCOUNT_POSSESSION|ITEM_ATTR_NOT_STORE_SAVE)) // 2011-06-07 by shcho, 베트남 요청 창고에만 저장 불가 속성 구현
			{// 2007-09-17 by cmkwon, 예당 캐쉬상점 캐쉬아이템 거래 불가 기능 추가 - 계정 소유 아이템 체크 추가, // 2006-11-07 by cmkwon, 이동 불가 아이템, 킬마크 아이템
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
				return RES_BREAK;
			}

			if(IS_COUNTABLE_ITEM(pItemGeneral->Kind))
			{// 2006-09-25 by cmkwon

				// 2007-10-05 by cmkwon, 카운터블 아이템만 체크 해야함
				if(pItemGeneral->CurrentCount < pMsgMoveItem->Count)
				{// 2007-09-05 by dhjin, 유저로 부터 전송 받은 아이템 개수 체크
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
					return RES_BREAK;
				}
				
				pItemGeneralInGuildStore = pGuildItemMan->GetItemGeneralByItemNum(pItemGeneral->ItemNum);
			}
			
			if(WEAR_NOT_ATTACHED != pItemGeneral->Wear)
			{// 2006-08-08 by cmkwon, 장착 아이템은 창고로 이동 불가
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
				return RES_BREAK;
			}

			if(MONEY_ITEM_NUMBER != pItemGeneral->ItemNum)
			{// 돈은 최대 개수 체크를 하지 않는다

				if(IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind))
				{// 카운터블일 경우 창고에 아이템이 없을때만 최대개수 확인

					if (NULL == pItemGeneralInGuildStore
						&& pGuildItemMan->GetGuildItemListSize() >= COUNT_IN_MEMBERSHIP_GUILDSTORE)
					{
						SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_GUILD_STORE_FULL_ITEM, pGuildItemMan->GetGuildItemListSize(), COUNT_IN_MEMBERSHIP_GUILDSTORE);
						return RES_BREAK;
					}
				}
				else if (pGuildItemMan->GetGuildItemListSize() >= COUNT_IN_MEMBERSHIP_GUILDSTORE)
				{// 카운터블이 아닐 경우 최대 개수 확인

					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_GUILD_STORE_FULL_ITEM, pGuildItemMan->GetGuildItemListSize(), COUNT_IN_MEMBERSHIP_GUILDSTORE);
					return RES_BREAK;
				}
			}

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

			if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind)
				&& pItemGeneralInGuildStore)
			{
				if(pItemGeneral->CurrentCount < pMsgMoveItem->Count + (pItemGeneralInGuildStore->ItemNum==MONEY_ITEM_NUMBER?STORE_KEEPING_COST:0))
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
					return RES_BREAK;
				}

				if ((INT64)pItemGeneralInGuildStore->CurrentCount + (INT64)pMsgMoveItem->Count > MAX_ITEM_COUNTS)
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
					return RES_BREAK;
				}
			}

			if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_NOT_STORE_SAVE) // 2011-06-07 by shcho, 베트남 요청 창고에만 저장 불가 속성 구현
				|| pItemGeneral->ItemInfo->Kind == ITEMKIND_QUEST)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
				return RES_BREAK;
			}

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

			// send log
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	//		CAtumLogSender::SendLogMessageITEMInsertToStore(this, pItemGeneral, pMsgMoveItem->Count);		// 2012-08-30 by jhseol, 풀로그 남기기 - 변경 전의 로그 함수 임으로 주석 해제 안함.
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기


			// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그 
			INT tempCurrentCount = pItemGeneral->CurrentCount;
			// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그. End


			if (IS_COUNTABLE_ITEM(pItemGeneral->Kind))
			{// countable item인 경우
				if (pItemGeneralInGuildStore)
				{// 2006-09-27 by dhjin, 여단 창고에 존재하는 카운터블 아이템이면 여단 창고 로그 업데이트

					ITEM_GENERAL tmLogItemG	= *pItemGeneralInGuildStore;
					tmLogItemG.CurrentCount	+= pMsgMoveItem->Count;
					CAtumLogSender::SendLogMessageITEMInsertToGuildStore(this, &tmLogItemG, pMsgMoveItem->Count);
					pGuildItemMan->InsertGuildStoreItemByItemNum(this, pItemGeneral->ItemNum, pMsgMoveItem->Count, IUT_GUILD_STORE, ITEM_IN_GUILD_STORE);
				}
				else
				{// 2006-09-27 by dhjin, 여단 창고에 존재하지 않는 카운터블 아이템이면 여단 창고 로그에 삽입 QP_InsertGuildStoreItem에서
					pGuildItemMan->InsertGuildStoreItemByItemNum(this, pItemGeneral->ItemNum, pMsgMoveItem->Count, IUT_GUILD_STORE, ITEM_IN_GUILD_STORE);
				}
				
				m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -pMsgMoveItem->Count, IUT_GUILD_STORE, ITEM_IN_CHARACTER);
			}
			else
			{// non-countable item인 경우

				pItemGeneral->AccountUniqueNumber	= GuildUID0;
				pItemGeneral->Possess				= GuildUID0;
				pItemGeneral->ItemStorage			= ITEM_IN_GUILD_STORE;
				m_ItemManager.UpdateItemStorage(pItemGeneral, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);
				pGuildItemMan->UpdateGuildStoreItemStorage(this, m_character.AccountUniqueNumber, 
							m_character.CharacterUniqueNumber, pItemGeneral, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);

				ITEM_GENERAL tmLogItemG	= *pItemGeneral;
				tmLogItemG.CurrentCount	= 1;
				CAtumLogSender::SendLogMessageITEMInsertToGuildStore(this, &tmLogItemG, 1);

				///////////////////////////////////////////////////////////////////////////////
				// 2006-09-25 by cmkwon, 인챈트 처리
				vectENCHANT tmEnchat;
				if(this->PopAllEnchantByItemUID(&tmEnchat, pItemGeneral->UniqueNumber))
				{
					pGuildItemMan->InsertGuildEnchant(&tmEnchat);
				}
			}

			m_ItemManager.UpdateItemCountByPointer(pMoney, -STORE_KEEPING_COST, IUT_STORE_FEE);			// 돈 지우기

			// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그 
			if ( 0 == tempCurrentCount - (pMsgMoveItem->Count) )
			{
				pItemGeneral->CurrentCount = 0;
			}
			CAtumLogSender::SendLogMessageITEMCharacterToFromGuildstoreResult(this, pItemGeneral, -(pMsgMoveItem->Count) );
			// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그. End


		}// if(ITEM_IN_GUILD_STORE == pMsgMoveItem->ToItemStorage)
		else
		{// 2006-09-23 by dhjin, 여단창고->캐릭터인벤
			
			ITEM_GENERAL *pItemGeneralInGuildStore	= pGuildItemMan->GetItemGeneralByUID(pMsgMoveItem->ItemUniqueNumber);
			ITEM_GENERAL *pItemGeneral				= NULL;
			if(NULL == pItemGeneralInGuildStore)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_STORE_MOVE_ITEM, 케릭터 인벤 --> 여단 창고
			if(FALSE == IS_VALID_UID64(pItemGeneralInGuildStore->UniqueNumber)
				|| pItemGeneralInGuildStore->UniqueNumber != pMsgMoveItem->ItemUniqueNumber
				|| pItemGeneralInGuildStore->Possess != GuildUID0)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1003);
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d, %d %d->%d, %d\r\n"
					, GetProtocolTypeString(T_FC_STORE_MOVE_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemGeneralInGuildStore, string()), pItemGeneralInGuildStore->Possess, pMsgMoveItem->ItemUniqueNumber, m_ItemManager.m_uid32StoreCharacterUID, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage, GuildUID0);
				return RES_BREAK;
			}
			
// 2007-10-05 by cmkwon, 아래에서 체크하고 있음
//			if(pItemGeneralInGuildStore->CurrentCount < pMsgMoveItem->Count)
//			{// 2007-09-05 by dhjin, 유저로 부터 전송 받은 아이템 개수 체크
//				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
//				return RES_BREAK;
//			}
			
			if(IS_COUNTABLE_ITEM(pItemGeneralInGuildStore->Kind))
			{
				pItemGeneral = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneralInGuildStore->ItemNum, ITEM_IN_CHARACTER);		// 2012-03-08 by hskim, 길드 창고 카운터블 아이템 못꺼내는 문제 수정
			}

			if(MONEY_ITEM_NUMBER != pItemGeneralInGuildStore->ItemNum)
			{// 돈은 최대 개수 체크를 하지 않는다

				///////////////////////////////////////////////////////////////////////////////
				// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - CFieldIOCPSocket::Process_FC_STORE_MOVE_ITEM#, 
				if(IS_COUNTABLE_ITEM(pItemGeneralInGuildStore->ItemInfo->Kind))
				{// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인
					
					if (NULL == pItemGeneral
						&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
					{
						SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
						return RES_BREAK;
					}
				}
				else if (m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
				{// 카운터블이 아닐 경우 최대 개수 확인

					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
					return RES_BREAK;
				}
			}

			if (IS_COUNTABLE_ITEM(pItemGeneralInGuildStore->ItemInfo->Kind))
			{
				if(pItemGeneralInGuildStore->CurrentCount < pMsgMoveItem->Count)
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
					return RES_BREAK;
				}

				if (pItemGeneral
					&& (INT64)pItemGeneral->CurrentCount + (INT64)pMsgMoveItem->Count > MAX_ITEM_COUNTS)
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
					return RES_BREAK;
				}
			}

			// send log
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	//		CAtumLogSender::SendLogMessageITEMDrawFromStore(this, pItemGeneral, pMsgMoveItem->Count);		// 2012-08-30 by jhseol, 풀로그 남기기 - 변경 전의 로그 함수 임으로 주석 해제 안함.
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
			ITEM_GENERAL tmLogItemG		= *pItemGeneralInGuildStore;
			if (IS_COUNTABLE_ITEM(pItemGeneralInGuildStore->Kind))
			{// countable item인 경우
				tmLogItemG.CurrentCount	-=pMsgMoveItem->Count;

				m_ItemManager.InsertItemGeneralByItemNum(pItemGeneralInGuildStore->ItemNum, pMsgMoveItem->Count, IUT_GUILD_STORE, ITEM_IN_CHARACTER);
				pGuildItemMan->UpdateGuildStoreItemCountByPointer(this, pItemGeneralInGuildStore, -pMsgMoveItem->Count, IUT_GUILD_STORE);
			}
			else
			{// non-countable item인 경우

				pItemGeneralInGuildStore->AccountUniqueNumber	= m_character.AccountUniqueNumber;
				pItemGeneralInGuildStore->Possess				= m_character.CharacterUniqueNumber;
				pItemGeneralInGuildStore->ItemStorage			= ITEM_IN_CHARACTER;
				m_ItemManager.UpdateItemStorage(pItemGeneralInGuildStore, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);
				pGuildItemMan->UpdateGuildStoreItemStorage(this, m_character.AccountUniqueNumber, 
							m_character.CharacterUniqueNumber, pItemGeneralInGuildStore, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);

				tmLogItemG				= *pItemGeneralInGuildStore;
				tmLogItemG.CurrentCount	= 0;
				///////////////////////////////////////////////////////////////////////////////
				// 2006-09-25 by cmkwon, 인챈트 처리
				vectENCHANT tmEnchat;
				if(pGuildItemMan->PopGuildEnchantByItemUID(&tmEnchat, pItemGeneralInGuildStore->UniqueNumber))
				{
					this->InsertEnchantToItem(pItemGeneralInGuildStore, &tmEnchat, FALSE);
				}

				// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그 
				ITEM_GENERAL tempItem = *pItemGeneralInGuildStore;
				tempItem.CurrentCount = 1;
				CAtumLogSender::SendLogMessageITEMCharacterToFromGuildstoreResult(this, &tempItem, pMsgMoveItem->Count );
				// 2012-12-17 by bckim, 길드창고 아이템 이동 관련 추가로그. End
			}
			CAtumLogSender::SendLogMessageITEMDrawFromGuildStore(this, &tmLogItemG, -pMsgMoveItem->Count);
		}

		return RES_RETURN_TRUE;
	}
	
	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	// 2006-09-25 by cmkwon	

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	// lock m_mapItemGeneral, MSG_FC_STORE_MOVE_ITEM
// 2005-12-07 by cmkwon, 아래와 같이 수정함
//	if (pMsgMoveItem->FromPossessCharacter == m_character.CharacterUniqueNumber
//			&& pMsgMoveItem->ToPossessCharacter == POSSESS_STORE_NUMBER)
//	{// Character -> 창고
//
//		ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pMsgMoveItem->ItemUniqueNumber);
//		if (NULL == pItemGeneral)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
//			return RES_BREAK;
//		}
//
//		if(MONEY_ITEM_NUMBER != pItemGeneral->ItemNum)
//		{// 돈은 최대 개수 체크를 하지 않는다
//
//			if(IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind))
//			{// 카운터블일 경우 창고에 아이템이 없을때만 최대개수 확인
//
//				ITEM_GENERAL *pItemGeneralInStore = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneral->ItemNum, ITEM_IN_STORE);
//				if (NULL == pItemGeneralInStore
//					&& m_ItemManager.m_mapItemInStore.size() >= SIZE_MAX_ITEM_GENERAL_IN_STORE)
//				{
//					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_STORE_FULL_ITEM, m_ItemManager.m_mapItemInStore.size(), SIZE_MAX_ITEM_GENERAL_IN_STORE);
//					return RES_BREAK;
//				}
//			}
//			else if (m_ItemManager.m_mapItemInStore.size() >= SIZE_MAX_ITEM_GENERAL_IN_STORE)
//			{// 카운터블이 아닐 경우 최대 개수 확인
//
//				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_STORE_FULL_ITEM, m_ItemManager.m_mapItemInStore.size(), SIZE_MAX_ITEM_GENERAL_IN_STORE);
//				return RES_BREAK;
//			}
//		}
//
//		// 이용료 확인
//		ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
//		if (pMoney == NULL || pMoney->CurrentCount < STORE_KEEPING_COST)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
//			return RES_BREAK;
//		}
//
//		if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind)
//				&& pItemGeneral->CurrentCount < pMsgMoveItem->Count)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
//			return RES_BREAK;
//		}
//
//		if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER)
//			|| pItemGeneral->ItemInfo->Kind == ITEMKIND_QUEST)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
//			return RES_BREAK;
//		}
//
//		// send log
//		CAtumLogSender::SendLogMessageITEMInsertToStore(this, pItemGeneral, pMsgMoveItem->Count);
//		if (IS_COUNTABLE_ITEM(pItemGeneral->Kind))
//		{
//			// countable item인 경우
//			m_ItemManager.InsertItemGeneralByItemNum(pItemGeneral->ItemNum, pMsgMoveItem->Count, IUT_GENERAL, ITEM_IN_STORE);
//			m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -pMsgMoveItem->Count, IUT_GENERAL, ITEM_IN_CHARACTER);
//		}
//		else
//		{
//			// non-countable item인 경우
//			m_ItemManager.UpdateItemPossess(pItemGeneral, m_character.CharacterUniqueNumber, POSSESS_STORE_NUMBER);
//		}
//
//		// 돈 지우기
//		m_ItemManager.UpdateItemCountByPointer(pMoney, -STORE_KEEPING_COST, IUT_GENERAL);
//	}
//	else if (pMsgMoveItem->FromPossessCharacter == POSSESS_STORE_NUMBER
//			&& pMsgMoveItem->ToPossessCharacter == m_character.CharacterUniqueNumber)
//	{// 창고 -> Character
//
//		ITEM_GENERAL *pItemGeneralInStore = m_ItemManager.GetItemGeneralByUID(pMsgMoveItem->ItemUniqueNumber, ITEM_IN_STORE);
//		if (NULL == pItemGeneralInStore)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
//			return RES_BREAK;
//		}
//		
//		if(MONEY_ITEM_NUMBER != pItemGeneralInStore->ItemNum)
//		{// 돈은 최대 개수 체크를 하지 않는다
//
//			if(IS_COUNTABLE_ITEM(pItemGeneralInStore->ItemInfo->Kind))
//			{// 카운터블일 경우 인벤토리에 아이템이 없을때만 최대개수 확인
//
//				ITEM_GENERAL *pItemGeneral = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneralInStore->ItemNum);
//				if (NULL == pItemGeneral
//					&& m_ItemManager.GetInventoryItemCounts() >= SIZE_MAX_ITEM_GENERAL)
//				{
//					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, SIZE_MAX_ITEM_GENERAL);
//					return RES_BREAK;
//				}
//			}
//			else if (m_ItemManager.GetInventoryItemCounts() >= SIZE_MAX_ITEM_GENERAL)
//			{// 카운터블이 아닐 경우 최대 개수 확인
//
//				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, SIZE_MAX_ITEM_GENERAL);
//				return RES_BREAK;
//			}
//		}
//
//		if (IS_COUNTABLE_ITEM(pItemGeneralInStore->ItemInfo->Kind)
//				&& pItemGeneralInStore->CurrentCount < pMsgMoveItem->Count)
//		{
//			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
//			return RES_BREAK;
//		}
//
//		// send log
//		CAtumLogSender::SendLogMessageITEMDrawFromStore(this, pItemGeneralInStore, pMsgMoveItem->Count);
//		if (IS_COUNTABLE_ITEM(pItemGeneralInStore->Kind))
//		{
//			// countable item인 경우
//			m_ItemManager.InsertItemGeneralByItemNum(pItemGeneralInStore->ItemNum, pMsgMoveItem->Count, IUT_GENERAL, ITEM_IN_CHARACTER);
//			m_ItemManager.UpdateItemCountByPointer(pItemGeneralInStore, -pMsgMoveItem->Count, IUT_GENERAL, ITEM_IN_STORE);
//		}
//		else
//		{
//			// non-countable item인 경우
//			m_ItemManager.UpdateItemPossess(pItemGeneralInStore, POSSESS_STORE_NUMBER, m_character.CharacterUniqueNumber);
//		}
//	}

	if (m_character.CharacterUniqueNumber != m_ItemManager.m_uid32StoreCharacterUID)
	{// 2006-09-19 by dhjin, 계정에 케릭터가 존재하는지 체크
		if (FALSE == m_ItemManager.IsExistPremiumCard())
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NO_MEMBERSHIP_USER);
			return RES_BREAK;
		}

		mt_auto_lock AllCharLock(&m_mtvectAllCharacterInfo);
		FC_CONNECT_LOGIN_INFO * pLoginInfo = GetFC_CONNECT_LOGIN_INFONoLock(m_ItemManager.m_uid32StoreCharacterUID);

		if (NULL == pLoginInfo)
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_NO_SEARCH_CHARACTER);
			return RES_BREAK;
		}

		USHORT tmRace = m_character.Race^pLoginInfo->Race;		// 2006-10-18 by cmkwon, 두비트가 같은값이면 0, 두비트가 다른값이면 1
		if(COMPARE_RACE(tmRace, RACE_OPERATION)
			|| COMPARE_RACE(tmRace, RACE_GAMEMASTER)
			|| COMPARE_RACE(tmRace, RACE_DEMO))
		{// 2006-10-18 by cmkwon
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_REQ_RACE_NOT_MATCHED);
			return RES_BREAK;
		}
	}

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pMsgMoveItem->ItemUniqueNumber, pMsgMoveItem->FromItemStorage);
	if (NULL == pItemGeneral)
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if( pItemGeneral->ItemStorage == pMsgMoveItem->ToItemStorage
		|| (ITEM_IN_STORE != pMsgMoveItem->ToItemStorage && ITEM_IN_CHARACTER != pMsgMoveItem->ToItemStorage) )
	{
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_KILL_MARK_ITEM)
		&& m_character.CharacterUniqueNumber != m_ItemManager.m_uid32StoreCharacterUID)
	{// 2006-11-07 by cmkwon, 킬마크 아이템은 접속 캐릭터<-->창고 로만 이동 가능
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
	
	// 2012-01-14 by hskim, 파트너 시스템 2차 
	if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_WAREHOUSE_SHARE_BANNED)
		&& m_character.CharacterUniqueNumber != m_ItemManager.m_uid32StoreCharacterUID)
	{ // 2012-01-14 by hskim, 캐릭터에서 자신의 창고만으로 이동 가능 / 다른 캐릭터 창고로 이동 불가
		SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
	// 2012-01-14 by hskim, 파트너 시스템 2차
	
	if(ITEM_IN_STORE == pMsgMoveItem->ToItemStorage)
	{// 2005-12-07 by cmkwon, 캐릭터인벤->창고

		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_STORE_MOVE_ITEM, 캐릭터인벤->창고
		if(FALSE == IS_VALID_UID64(pItemGeneral->UniqueNumber)
			|| pItemGeneral->UniqueNumber != pMsgMoveItem->ItemUniqueNumber
			|| pItemGeneral->Possess != GetCharacter()->CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d, %d %d->%d\r\n"
				, GetProtocolTypeString(T_FC_STORE_MOVE_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemGeneral, string()), pItemGeneral->Possess, pMsgMoveItem->ItemUniqueNumber, m_ItemManager.m_uid32StoreCharacterUID, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);
			return RES_BREAK;
		}

		if(WEAR_NOT_ATTACHED != pItemGeneral->Wear)
		{// 2006-08-08 by cmkwon, 장착 아이템은 창고로 이동 불가
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
			return RES_BREAK;
		}

		if(MONEY_ITEM_NUMBER != pItemGeneral->ItemNum)
		{// 돈은 최대 개수 체크를 하지 않는다

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

				ITEM_GENERAL *pItemGeneralInStore = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneral->ItemNum, ITEM_IN_STORE);
				if (NULL == pItemGeneralInStore
					&& m_ItemManager.m_mapItemInStore.size() >= m_ItemManager.GetMaxInventoryCount(ITEM_IN_STORE))
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_STORE_FULL_ITEM, m_ItemManager.m_mapItemInStore.size(), m_ItemManager.GetMaxInventoryCount(ITEM_IN_STORE));
					return RES_BREAK;
				}
			}
			else if (m_ItemManager.m_mapItemInStore.size() >= m_ItemManager.GetMaxInventoryCount(ITEM_IN_STORE))
			{// 카운터블이 아닐 경우 최대 개수 확인

				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_STORE_FULL_ITEM, m_ItemManager.m_mapItemInStore.size(), m_ItemManager.GetMaxInventoryCount(ITEM_IN_STORE));
				return RES_BREAK;
			}
		}

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

		if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind))
		{
			if(pItemGeneral->CurrentCount < pMsgMoveItem->Count + (pItemGeneral->ItemNum==MONEY_ITEM_NUMBER?STORE_KEEPING_COST:0))
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
				return RES_BREAK;
			}

			ITEM_GENERAL *pItemGInStore = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneral->ItemNum, ITEM_IN_STORE);
			if (pItemGInStore
				&& (INT64)pItemGInStore->CurrentCount + (INT64)pMsgMoveItem->Count > MAX_ITEM_COUNTS)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
				return RES_BREAK;
			}
		}
// 2006-02-22 by cmkwon, 위와 같이 수정함, 최대 카운트 체크
// 		if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind)
// 				&& pItemGeneral->CurrentCount < pMsgMoveItem->Count)
// 		{
// 			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
// 			return RES_BREAK;
// 		}

		if (COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_NOT_STORE_SAVE) // 2011-06-07 by shcho, 베트남 요청 창고에만 저장 불가 속성 구현
			|| pItemGeneral->ItemInfo->Kind == ITEMKIND_QUEST)
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
			return RES_BREAK;
		}

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


		// send log
// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 아래와 같이 수정함
		// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			CAtumLogSender::SendLogMessageITEMInsertToStore(this, pItemGeneral, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);
#endif	//#ifdef S_FULL_LOG_JHSEOL
		// end 2012-08-30 by jhseol, 풀로그 남기기
		ITEM_GENERAL tmItemGForLog = *pItemGeneral;
		if (IS_COUNTABLE_ITEM(pItemGeneral->Kind))
		{
			// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 
			tmItemGForLog.CurrentCount		-= pMsgMoveItem->Count;		// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 
			CAtumLogSender::SendLogMessageITEMInsertToStore(this, &tmItemGForLog, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);

			// countable item인 경우
			m_ItemManager.InsertItemGeneralByItemNum(pItemGeneral->ItemNum, pMsgMoveItem->Count, IUT_STORE, ITEM_IN_STORE);
			m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -pMsgMoveItem->Count, IUT_STORE, ITEM_IN_CHARACTER);
		}
		else
		{
			// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 
			CAtumLogSender::SendLogMessageITEMInsertToStore(this, &tmItemGForLog, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);

			// non-countable item인 경우
// 2005-12-07 by cmkwon
//			m_ItemManager.UpdateItemPossess(pItemGeneral, m_character.CharacterUniqueNumber, POSSESS_STORE_NUMBER);
			m_ItemManager.UpdateItemStorage(pItemGeneral, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);

 			// 2012-12-27 by bckim, 동일계정, 각각의 케릭터간의 아이템 이동시 로그추가
			if ( pItemGeneral->Possess != this->m_character.CharacterUniqueNumber )
			{
				CFieldIOCPSocket tempCharacterSocket;
				tempCharacterSocket.m_character.CharacterUniqueNumber = pItemGeneral->Possess;
				tempCharacterSocket.m_character.MapChannelIndex.MapIndex =this->m_character.MapChannelIndex.MapIndex;
				ITEM_GENERAL tempItemGeneral;
				memcpy(&tempItemGeneral, pItemGeneral, sizeof(tempItemGeneral));		// 2013-03-22 by hskim, 창고에서 무기 아이템 찾을때 총알 수가 0 되는 문제 수정
				tempItemGeneral.CurrentCount = min( 1 , pItemGeneral->CurrentCount);
				CAtumLogSender::SendLogMessageITEMGetWithSameAccount(&tempCharacterSocket, &tempItemGeneral, 1, this->m_character.CharacterUniqueNumber);
			}
 			// 2012-12-27 by bckim, 동일계정, 각각의 케릭터간의 아이템 이동시 로그추가.End
		}

		// 돈 지우기
		m_ItemManager.UpdateItemCountByPointer(pMoney, -STORE_KEEPING_COST, IUT_STORE_FEE);
	}
	
	else
	{// 2005-12-07 by cmkwon, 창고->캐릭터인벤

		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_STORE_MOVE_ITEM, 창고->캐릭터인벤
		if(FALSE == IS_VALID_UID64(pItemGeneral->UniqueNumber)
			|| pItemGeneral->UniqueNumber != pMsgMoveItem->ItemUniqueNumber
			|| pItemGeneral->Possess != m_ItemManager.m_uid32StoreCharacterUID)
		{
			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1001);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d, %d %d->%d\r\n"
				, GetProtocolTypeString(T_FC_STORE_MOVE_ITEM), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemGeneral, string()), pItemGeneral->Possess, pMsgMoveItem->ItemUniqueNumber, m_ItemManager.m_uid32StoreCharacterUID, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);
			return RES_BREAK;
		}

		if(MONEY_ITEM_NUMBER != pItemGeneral->ItemNum)
		{// 돈은 최대 개수 체크를 하지 않는다

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

				ITEM_GENERAL *pItemGeneralInven = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneral->ItemNum);
				if (NULL == pItemGeneralInven
					&& m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
				{
					SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
					return RES_BREAK;
				}
			}
			else if (m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
			{// 카운터블이 아닐 경우 최대 개수 확인

				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
				return RES_BREAK;
			}
		}

		if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind))
		{
			if(pItemGeneral->CurrentCount < pMsgMoveItem->Count)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
				return RES_BREAK;
			}

			ITEM_GENERAL *pItemGInven = m_ItemManager.GetFirstItemGeneralByItemNum(pItemGeneral->ItemNum);
			if (pItemGInven
				&& (INT64)pItemGInven->CurrentCount + (INT64)pMsgMoveItem->Count > MAX_ITEM_COUNTS)
			{
				SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
				return RES_BREAK;
			}
		}
// 2006-02-22 by cmkwon, 위와 같이 수정함, 최대 카운트 체크
// 		if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind)
// 				&& pItemGeneral->CurrentCount < pMsgMoveItem->Count)
// 		{
// 			SendErrorMessage(T_FC_STORE_MOVE_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED);
// 			return RES_BREAK;
// 		}

		// send log
// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 아래와 같이 수정함
		// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
		CAtumLogSender::SendLogMessageITEMDrawFromStore(this, pItemGeneral, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);
#endif	//#ifdef S_FULL_LOG_JHSEOL
		// end 2012-08-30 by jhseol, 풀로그 남기기
		ITEM_GENERAL tmItemGForLog = *pItemGeneral;
		if (IS_COUNTABLE_ITEM(pItemGeneral->Kind))
		{
			// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 
			tmItemGForLog.CurrentCount		-= pMsgMoveItem->Count;
			CAtumLogSender::SendLogMessageITEMDrawFromStore(this, &tmItemGForLog, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);

			// countable item인 경우
			m_ItemManager.InsertItemGeneralByItemNum(pItemGeneral->ItemNum, pMsgMoveItem->Count, IUT_STORE, ITEM_IN_CHARACTER);
			m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -pMsgMoveItem->Count, IUT_STORE, ITEM_IN_STORE);
		}
		else
		{
			// 2008-02-15 by cmkwon, 인벤<->창고 이동 로그 수정 - 
			CAtumLogSender::SendLogMessageITEMDrawFromStore(this, &tmItemGForLog, pMsgMoveItem->Count, m_ItemManager.m_uid32StoreCharacterUID);

			// non-countable item인 경우
// 2005-12-07 by cmkwon
//			m_ItemManager.UpdateItemPossess(pItemGeneral, POSSESS_STORE_NUMBER, m_character.CharacterUniqueNumber);
			m_ItemManager.UpdateItemStorage(pItemGeneral, pMsgMoveItem->FromItemStorage, pMsgMoveItem->ToItemStorage);

			// 2012-12-27 by bckim, 동일계정, 각각의 케릭터간의 아이템 이동시 로그추가
			if ( pItemGeneral->Possess != this->m_ItemManager.m_uid32StoreCharacterUID )
			{
				CFieldIOCPSocket tempCharacterSocket;
				tempCharacterSocket.m_character.CharacterUniqueNumber = pItemGeneral->Possess;
				tempCharacterSocket.m_character.MapChannelIndex.MapIndex = this->m_character.MapChannelIndex.MapIndex;
				ITEM_GENERAL tempItemGeneral;
				memcpy(&tempItemGeneral, pItemGeneral, sizeof(tempItemGeneral));		// 2013-03-22 by hskim, 창고에서 무기 아이템 찾을때 총알 수가 0 되는 문제 수정
				tempItemGeneral.CurrentCount = min( 1 , pItemGeneral->CurrentCount);
				CAtumLogSender::SendLogMessageITEMGetWithSameAccount(&tempCharacterSocket, &tempItemGeneral, 1 ,this->m_ItemManager.m_uid32StoreCharacterUID);
			}
 			// 2012-12-27 by bckim, 동일계정, 각각의 케릭터간의 아이템 이동시 로그추가.End
		}
	}

// 2007-01-30 by cmkwon, CAtumFieldDBManager::QP_NewGetStoreItem()함수내에서 처리, 필요없는 쿼리임
//
//	// enchant reloading
//	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ReloadAllEnchant, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_STORE_EXPIRE_USINGITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-10-11 ~ 2006-10-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_STORE_EXPIRE_USINGITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_STORE_EXPIRE_USINGITEM,
									MSG_FC_STORE_EXPIRE_USINGITEM, pRMsg);

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);

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

//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ARENACHECK] T_FC_STORE_EXPIRE_USINGITEM ItemUniqueNumber = %d\r\n"
//		, pRMsg->ItemUID0);

	m_ItemManager.CheckExpireUsingTimeLimitedItemList(pRMsg->ItemUID0);		// 2006-10-11 by cmkwon
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_STORE_LOG_GUILD_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2006-09-27 ~ 2006-09-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_STORE_LOG_GUILD_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_STORE_LOG_GUILD_ITEM,
									MSG_FC_STORE_LOG_GUILD_ITEM, pMsgLogGuildStore);
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}	

	if(FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
	{// 2006-09-28 by cmkwon, 여단 UID 체크
		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_PROTOCOL_NO_SUCH_GUILD);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_STORE_LOG_GUILD_ITEM, 필드창고는 여단창고로그 이용 불가
	if(m_ItemManager.GetUsingFieldStore())
	{
 		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_CANNOT_USE_GUILD_STORE);
 		return RES_BREAK;
	}

// 2007-09-03 by cmkwon, 멤버쉼 서비스 수정 - 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
//	if (FALSE == m_ItemManager.IsExistPremiumCard())
//	{
//		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_NO_MEMBERSHIP_USER);
//		return RES_BREAK;
//	}
	if (LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType()
		&& FALSE == m_ItemManager.IsExistPremiumCard())
	{// 2007-10-15 by cmkwon, 베트남만 멤버쉽 유저만 여단창고 이용 가능, // 2007-10-10 by cmkwon, 멤버쉼 서비스 수정 - 예당만 여단 창고 이용을 여단 가입한 모든 유저가 사용 가능하게
		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_NO_MEMBERSHIP_USER);
		return RES_BREAK;
	}

	
	if (m_character.AccountUniqueNumber != pMsgLogGuildStore->AccountUID)
	{
		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_PROTOCOL_INVALID_ACCOUNT_UNIQUENUMBER);
		return RES_BREAK;
	}

	if (m_character.CharacterUniqueNumber != pMsgLogGuildStore->CharacterUID)
	{
		SendErrorMessage(T_FC_STORE_LOG_GUILD_ITEM, ERR_PROTOCOL_INVALID_CHARACTER_UNIQUENUMBER);
		return RES_BREAK;
	}
	
	QPARAM_GET_GUILDSTORE *pQParam	= new QPARAM_GET_GUILDSTORE;
	pQParam->GuildUID				= m_character.GuildUniqueNumber;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetLogGuildStoreItem,this, m_character.AccountUniqueNumber, pQParam);
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_STORE_REQUEST_QUICKSLOT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2006-09-04 ~ 2006-09-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_STORE_REQUEST_QUICKSLOT(const char* pPacket, int nLength, int &nBytesUsed)
{
	if (FALSE == IsValidCharacter(FALSE))	// 2007-10-23 by cmkwon, 체크 버그 수정
	{
		SendErrorMessage(T_FC_STORE_REQUEST_QUICKSLOT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	QPARAM_GET_QUICKSLOT *pQParam = new QPARAM_GET_QUICKSLOT;
	pQParam->AccountUID			= m_character.AccountUniqueNumber;
	pQParam->CharacterUID		= m_character.CharacterUniqueNumber;
	pQParam->SlotPurpose		= SLOT_PURPOSE_MAIN;		// 2012-06-21 by jhseol, 아레나 추가개발part2 - 아레나 전용 퀵슬롯 ( 0 = 메인, 1 = 아레나 )
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Get_QuickSlot,this, m_character.AccountUniqueNumber, pQParam);

	return RES_RETURN_TRUE;	
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_STORE_SAVE_QUICKSLOT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2006-09-04 ~ 2006-09-04
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_STORE_SAVE_QUICKSLOT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_STORE_SAVE_QUICKSLOT,
									MSG_FC_STORE_SAVE_QUICKSLOT, pMsgQuickSlot);

	for (int i=0; i<QUICKTABCOUNT ; i++)
	{
		if (TRUE == pMsgQuickSlot->POS[i].Delete)
		{
			QPARAM_DELETE_QUICKSLOT *pQParam0 = new QPARAM_DELETE_QUICKSLOT;
			MEMSET_ZERO(pQParam0, sizeof(QPARAM_DELETE_QUICKSLOT));
			pQParam0->AccountUID		= m_character.AccountUniqueNumber;
			pQParam0->CharacterUID		= m_character.CharacterUniqueNumber;
			pQParam0->TabIdx			= i;
			pQParam0->SlotPurpose		= pMsgQuickSlot->SlotPurpose;	// 2012-06-21 by jhseol, 아레나 추가개발part2 - 아레나 전용 퀵슬롯
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Delete_QuickSlot,this, m_character.AccountUniqueNumber, pQParam0);
			continue;
		}

		for(int j=0; j < QUICKSLOTCOUNT; j++)
		{
			if(0 != pMsgQuickSlot->POS[i].arrItemNum_[j])
			{
				QPARAM_UPDATE_QUICKSLOT *pQParam = new QPARAM_UPDATE_QUICKSLOT;
				MEMSET_ZERO(pQParam, sizeof(QPARAM_UPDATE_QUICKSLOT));
				pQParam->AccountUID			= m_character.AccountUniqueNumber;
				pQParam->CharacterUID		= m_character.CharacterUniqueNumber;
				pQParam->TabIdx				= i;
				memcpy(pQParam->arrItemNum_, pMsgQuickSlot->POS[i].arrItemNum_,  sizeof(pQParam->arrItemNum_[0])*QUICKSLOTCOUNT);
				pQParam->SlotPurpose		= pMsgQuickSlot->SlotPurpose;	// 2012-06-21 by jhseol, 아레나 추가개발part2 - 아레나 전용 퀵슬롯
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Update_QuickSlot,this, m_character.AccountUniqueNumber, pQParam);
				break;
			}
		}
	}
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_DELETE_ITEM_ADMIN(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize	= 0;
	MSG_FC_ITEM_DELETE_ITEM_ADMIN	*pMsgDelItem	= NULL;

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

	if(!COMPARE_RACE(m_character.Race, RACE_GAMEMASTER|RACE_OPERATION))
	{
		SendErrorMessage(T_FC_ITEM_DELETE_ITEM_ADMIN, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	if (CS_PLAYING != GetClientState())
	{
		SendErrorMessage(T_FC_ITEM_DELETE_ITEM_ADMIN, ERR_PROTOCOL_INVALID_FIELDSERVER_CLIENT_STATE);
		return RES_BREAK;
	}

	// 처리
	D3DXVECTOR3 ItemPosition = A2DX(pMsgDelItem->DropPosition);
	CMapBlock *pTmpMapBlock	= m_pCurrentFieldMapChannel->GetBlock(ItemPosition.x, ItemPosition.z);
	if (pTmpMapBlock == NULL)
	{
		SendErrorMessage(T_FC_ITEM_DELETE_ITEM_ADMIN, ERR_PROTOCOL_INVALID_POSITION);
		return RES_BREAK;
	}

	DROPITEM *pDropItem	= pTmpMapBlock->GetDROPITEM_SetProcess((ITEM_GENERAL*)pMsgDelItem->ItemFieldIndex);
	if (NULL == pDropItem)
	{
		SendErrorMessage(T_FC_ITEM_DELETE_ITEM_ADMIN, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 주위 클라이언트에게 삭제 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_HIDE_ITEM, T_FC_ITEM_HIDE_ITEM, pMsgHideItem, pMsgHideItemBuf);
	pMsgHideItem->ClientIndex		= 0;
	pMsgHideItem->ItemFieldIndex	= pMsgDelItem->ItemFieldIndex;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropItem->Position, pMsgHideItemBuf,
		MSG_SIZE(MSG_FC_ITEM_HIDE_ITEM), (CFieldMapChannel*)pTmpMapBlock->m_pMapChannel);

	///////////////////////////////////////////////////////////////////////////////
	// Item을 삭제처리
	ITEM_GENERAL *pItemGeneralToDel = (ITEM_GENERAL*)pMsgDelItem->ItemFieldIndex;
	m_pCurrentFieldMapChannel->DeleteDropItem(pTmpMapBlock, pItemGeneralToDel);	
	SAFE_DELETE(pItemGeneralToDel);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_DELETE_DROP_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_DELETE_DROP_ITEM,
									MSG_FC_ITEM_DELETE_DROP_ITEM, pMsgDelDropItem);

	if (CS_PLAYING != GetClientState())
	{
		SendErrorMessage(T_FC_ITEM_DELETE_DROP_ITEM, ERR_PROTOCOL_INVALID_FIELDSERVER_CLIENT_STATE);
		return RES_BREAK;
	}

	// 처리
	D3DXVECTOR3 DropItemPosition = A2DX(pMsgDelDropItem->DropPosition);

	// lock m_setCharacDropMine
	mt_auto_lock mineLock(&m_setCharacDropMine);

	// 마인의 존재 여부 확인
	DROPMINE *pDropMine = (DROPMINE*)pMsgDelDropItem->ItemFieldIndex;
	CMapBlock *pMapBlock = NULL;
	if (!IsValidDropMine(pDropMine, pMapBlock) || pMapBlock == NULL)
	{
		SendErrorMessage(T_FC_ITEM_DELETE_DROP_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

//#ifdef _DEBUG
//	SendString128(STRING_128_ADMIN_CMD, "delete drop mine: %5.2f"
//		, D3DXVec3Length(&(pDropMine->Position-m_character.PositionVector)));
//#endif

	// 지우기, 자기 자신은 제외함
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_HIDE_ITEM, T_FC_ITEM_HIDE_ITEM, pMsgHideItem, pMsgHideItemBuf);
	pMsgHideItem->ClientIndex = 0;
	pMsgHideItem->ItemFieldIndex = pMsgDelDropItem->ItemFieldIndex;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropMine->Position, pMsgHideItemBuf,
		MSG_SIZE(MSG_FC_ITEM_HIDE_ITEM), m_pCurrentFieldMapChannel, m_character.ClientIndex);

	// 캐릭터의 drop mine list에서 삭제
	m_setCharacDropMine.deleteLock(pDropMine);


	// MapBlock에서 제거
	BOOL ret = pMapBlock->m_setMapBlockDropMine.deleteLock(pDropMine);

	// 삭제
	SAFE_DELETE(pDropMine);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_GET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 아이템을 얻는 경우
	int						nRecvTypeSize		= 0;
	MSG_FC_ITEM_GET_ITEM	*pMsgGetItem;
	BYTE					SendBuf[SIZE_MAX_PACKET];

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

//	DBGOUT("[%s, %d]GetItem %x[%d][%d]\n", m_character.CharacterName, m_character.ClientIndex, pMsgGetItem->ItemFieldIndex, pTmpMapBlock->m_x, pTmpMapBlock->m_z);

	if(m_character.ClientIndex != pMsgGetItem->ClientIndex )
	{
		SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVALID_FIELDSERVER_CLIENT_STATE, 0, 0, NULL, FALSE, FALSE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 드랍율이 0이면 습득불가
	float	fDropRateOfGameRestriction	= 1.0f;			// 2008-04-08 by cmkwon, 기본값
	if(this->GPGetApplyRateByGamePlayingTime(&fDropRateOfGameRestriction)
		&& fDropRateOfGameRestriction <= 0.0f)
	{
		return RES_BREAK;		// 2008-04-08 by cmkwon, 드랍 아이템 습득 불가
	}

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-07-10 by cmkwon
//	if(FALSE == IsValidGameUser())
//	{// 2006-07-10 by cmkwon, 베트남 정액제 적용, 차후 에러 메시지 전송
//		return RES_BREAK;
//	}

// 2005-01-06 by cmkwon, 아래 InsertItemGeneralByPointer() 함수 내에서 처리됨
//	// 최대 개수 확인
//	if (m_ItemManager.m_mapItemGeneral.size() >= SIZE_MAX_ITEM_GENERAL)
//	{
//		SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM, m_ItemManager.m_mapItemGeneral.size(), SIZE_MAX_ITEM_GENERAL);
//		return RES_BREAK;
//	}

	CMapBlock *pTmpMapBlock	= m_pCurrentFieldMapChannel->GetBlock(m_character.PositionVector.x, m_character.PositionVector.z);
	if (pTmpMapBlock == NULL)
	{
		SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVALID_POSITION);
		return RES_BREAK;
	}
	DROPITEM *pDropItem		= pTmpMapBlock->GetDROPITEM_SetProcess((ITEM_GENERAL*)pMsgGetItem->ItemFieldIndex);
	if (NULL == pDropItem)
	{
		TWO_BLOCK_INDEXES blockIdx;

		///////////////////////////////////////////////////////////////////////////////
		// 몬스터 시야에서 아이템을 검색한다
		m_pCurrentFieldMapChannel->m_pMapProject->GetBlockAdjacentToPositionHalfDistance(m_character.PositionVector.x
			, m_character.PositionVector.z, m_pCurrentFieldMapChannel->GetMonsterVisibleDiameterW(), blockIdx);

		BOOL bFound = FALSE;		
		for (int i = blockIdx.sMinX; i < blockIdx.sMaxX; i++)
		{
			for (int j = blockIdx.sMinZ; j < blockIdx.sMaxZ; j++)
			{
				CMapBlock *pTmpBlock = m_pCurrentFieldMapChannel->GetBlockByIndex(i, j);
				pDropItem = pTmpBlock->GetDROPITEM_SetProcess((ITEM_GENERAL*)pMsgGetItem->ItemFieldIndex);
				if (pDropItem)
				{
					bFound = TRUE;
					break;
				}
			}
			if (pDropItem)
			{				
				break;
			}
		}

		if (FALSE == bFound)
		{
			return RES_BREAK;
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - Tender
	if(TRUE == pDropItem->bTendering)
	{
		pDropItem->bProcessing = FALSE;		// 2010-04-09 by cmkwon, 인피2차 추가 수정(단계별 보상 추가) - 수정
		SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_INFINITY_TENDER_PROCESSING);
		return RES_BREAK;		
	}

	// 거리 계산
	if ( D3DXVec3Length(&(m_character.PositionVector - pDropItem->Position)) > m_pCurrentFieldMapChannel->GetUserVisibleDiameterW()/2)
	{
		pDropItem->bProcessing = FALSE;
		return RES_BREAK;
	}

	// priority 계산
	// check: 시간 경과 후에는 아무나 먹을 수 있도록 수정하기... 20020121...
	BOOL bAllowGetDropItem = FALSE;
	DWORD dwCurrentDelay = ms_pFieldIOCP->GetCurrentServerTimeInMilliSeconds() - pDropItem->dwStartTick;

	// 2013-04-10 by hskim, 어드민 명령에 의한 드랍 아이템은 대기 시간 2초 적용
	DWORD dwDropItemDelay = MAX_DROPITEM_DELAY;		

	if( TRUE == pDropItem->bAdminCommand )
	{
		dwDropItemDelay = MAX_DROPITEM_DELAY_ADMIN_COMMAND;
	}
	// end 2013-04-10 by hskim, 어드민 명령에 의한 드랍 아이템은 대기 시간 2초 적용

	if (dwCurrentDelay > dwDropItemDelay)		// 2013-04-10 by hskim, 어드민 명령에 의한 드랍 아이템은 대기 시간 2초 적용
	{
		bAllowGetDropItem = TRUE;
	}
	else
	{
		for (int i = 0; i < pDropItem->priorityInfoCount; i++)
		{
			if(FALSE == IS_VALID_UNIQUE_NUMBER(pDropItem->priorityInfoArray[i].CharacterUniqueNumber))
			{
				break;
			}

			if (m_character.CharacterUniqueNumber == pDropItem->priorityInfoArray[i].CharacterUniqueNumber)
			{
				if ( dwCurrentDelay >= pDropItem->priorityInfoArray[i].dwDelay )
				{
					bAllowGetDropItem = TRUE;
				}
				break;
			}
		}
	}

//	DBGOUT("	CharInfo(%s:%d) GetItem %x[%d][%d] ==> GetItem(%d)\n", m_character.CharacterName, m_character.ClientIndex, pMsgGetItem->ItemFieldIndex, pTmpMapBlock->m_x, pTmpMapBlock->m_z, bAllowGetDropItem);

	if (FALSE == bAllowGetDropItem)
	{
		pDropItem->bProcessing = FALSE;
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-06-10 by dhjin, EP3 편대 수정 -	아이템 분배 방식 추가로 편대일때 밑과 같이 수정
	CFieldParty *pFParty = this->m_pFieldParty;
	if(NULL == pFParty)
	{
		// 아이템 먹기: 단 로그를 남겨야 함
		CFieldIOCPSocket *pCharacterToPickup = this;
	// 2006-07-14 by cmkwon, 파티 보상 시스템 수정 - 파티도 요청한 유저가 먹도록 처리
	// 	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	// 	if (pFParty)		
	// 	{
	// 		CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
	// 		MEMSET_ZERO(ArrayPartyMember, sizeof(CFieldIOCPSocket*));
	// 		int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel
	// 			, &m_character.PositionVector, SIZE_MAX_EXPERIENCE_DIVISION_RADIUS);
	// 		if(nMemCount < 1)
	// 		{
	// 			pDropItem->bProcessing = FALSE;
	// 			return RES_BREAK;
	// 		}
	// 		
	// 		if(1 == nMemCount)
	// 		{
	// 			pCharacterToPickup = ArrayPartyMember[0];
	// 		}
	// 		else
	// 		{// 먹을 파티원 선택
	// 			pCharacterToPickup = ArrayPartyMember[RANDI(0,nMemCount-1)];
	// 		}
	// 	}

		pDropItem->pItem->AccountUniqueNumber	= pCharacterToPickup->m_character.AccountUniqueNumber;
		pDropItem->pItem->Possess				= pCharacterToPickup->m_character.CharacterUniqueNumber;
// 2009-08-25 by cmkwon, 사용하지 않는 필드 제거(td_Store.ScarcityNumber) - 
//		pDropItem->pItem->ScarcityNumber		= 0;
		pDropItem->pItem->Wear					= WEAR_NOT_ATTACHED;
		pDropItem->pItem->ItemWindowIndex		= POS_INVALID_POSITION;	// 서버에서는 아이템 창의 첫 slot에 넣어두고, 정리는 client에서 한다.
		pDropItem->pItem->NumOfEnchants			= 0;
		
		if (FALSE == pCharacterToPickup->IsUsing() 
			|| CS_PLAYING != pCharacterToPickup->GetClientState())
		{
			pDropItem->bProcessing = FALSE;
			return RES_BREAK;
		}

		// lock m_mapItemGeneral, MSG_FC_ITEM_GET_ITEM
		mt_auto_lock igLock(&pCharacterToPickup->m_ItemManager.m_mapItemGeneral);
	// 2005-09-27 by cmkwon, 무게게이즈는 장착된 아이템만 적용하도록 수정함
	//	// 적재량 확인
	//	float fItemWeight = CAtumSJ::GetItemWeight(pDropItem->pItem->ItemInfo, pDropItem->pItem->CurrentCount);
	//	if (pCharacterToPickup->GetCurrentLoadagePercentage(fItemWeight) > 1.0f)
	//	{// 적재량 초과
	//		
	//		pDropItem->bProcessing = FALSE;
	//		pCharacterToPickup->SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_ITEM_OVER_WEIGHT
	//			, (INT)pCharacterToPickup->m_ItemManager.GetCurrentCarryingItemWeight()+fItemWeight
	//			, (INT)CAtumSJ::GetTransport(&pCharacterToPickup->m_character));		
	//		return RES_BREAK;
	//	}

	// 2008-03-28 by cmkwon, 이제 필요 없는 로그임(문제 해결된 상태)
	// 	///////////////////////////////////////////////////////////////////////////////
	// 	// 2008-02-14 by cmkwon, 베트남 문제 체크 - 킬마크 드랍 습득, 퀘스트 아이템 드랍 습득 로그 남기기
	// 	if(ITEMKIND_QUEST == pDropItem->pItem->Kind
	// 		|| COMPARE_BIT_FLAG(pDropItem->pItem->ItemInfo->ItemAttribute, ITEM_ATTR_KILL_MARK_ITEM|ITEM_ATTR_CASH_ITEM))
	// 	{
	// 		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ::Process_FC_ITEM_GET_ITEM Error100, %s %s ItemKind(%s)\r\n"
	// 			, GetCharacterString(this->GetCharacter(), string()), GetItemGeneralString(pDropItem->pItem, string())
	// 			, CAtumSJ::GetItemKindName(pDropItem->pItem->Kind));
	// 	}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - m_ItemManager.InsertItemGeneralByPointer() 이후에 pDropItem->pItem 의 메모리가 삭제될 수 있다
		// 2008-02-18 by cmkwon, 카운터블 아이템일 경우 발생 할 수 있다, 그래서 아래와 같이 임시 변수를 만들어서 처리한다.
		ITEM_GENERAL tmItemG = *(pDropItem->pItem);

		// 적재량 초과 안 됨, 캐릭터에게 삽입 시도
		if(FALSE == pCharacterToPickup->m_ItemManager.InsertItemGeneralByPointer(pDropItem->pItem, IUT_DROP_ITEM, TRUE))
		{// 인벤토리 용량 초과
			
			pDropItem->bProcessing = FALSE;
			pCharacterToPickup->SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM
				, 0, m_ItemManager.GetMaxInventoryCount(), NULL, FALSE, FALSE);		// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
			return RES_BREAK;
		}

		//////////////////////////////////////////////////////////////////////////
		// 2008-06-10 by dhjin, EP3 편대 수정 - 편대는 따로 처리한다.
//		CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-14 by cmkwon
//		if(pFParty)
//		{// 파티원에게 습득 정보 전송
//
//			INIT_MSG(MSG_FC_PARTY_PUT_ITEM_OTHER, T_FC_PARTY_PUT_ITEM_OTHER, pPartyPutItem, SendBuf);
//			pPartyPutItem->ClientIndex	= pCharacterToPickup->m_character.ClientIndex;
//			// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - 
//			//pPartyPutItem->ItemNum		= pDropItem->pItem->ItemNum;
//			//pPartyPutItem->Amount		= pDropItem->pItem->CurrentCount;
//			pPartyPutItem->ItemNum		= tmItemG.ItemNum;
//			pPartyPutItem->Amount		= tmItemG.CurrentCount;
//			pFParty->SendMsgToMembersMap(SendBuf, MSG_SIZE(MSG_FC_PARTY_PUT_ITEM_OTHER),
//				m_pCurrentFieldMapChannel, pCharacterToPickup->m_character.CharacterUniqueNumber);
//		}

		// send in range hide item
		INIT_MSG(MSG_FC_ITEM_HIDE_ITEM, T_FC_ITEM_HIDE_ITEM, pHideItem, SendBuf);
		pHideItem->ItemFieldIndex = (UINT)pDropItem->pItem;		// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - 메모리 주소만 참조 하므로 메모리가 삭제되도 상관없으므로 수정 필요 없다.
		pHideItem->ClientIndex = m_character.ClientIndex;
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropItem->Position, SendBuf, MSG_SIZE(MSG_FC_ITEM_HIDE_ITEM), m_pCurrentFieldMapChannel);

	}
	else
	{
		// 아이템 먹기: 단 로그를 남겨야 함
		CFieldIOCPSocket *pCharacterToPickup = this;
		BOOL CheckItemDistributeTypeOrder = FALSE;	// 2008-06-10 by dhjin, EP3 편대 수정 - 다음 파티원 피봇 증가를 위해 체크 비트를 둔다.
		BYTE tmPivotPartyMember = 0;
		switch(pFParty->GetItemDistributeType())
		{
		case ITEM_DISTRIBUTE_TYPE_DAMAGE:
			{
			}
			break;
		case ITEM_DISTRIBUTE_TYPE_ORDER:
			{
				pCharacterToPickup = pFParty->GetItemByOrderDistributeType(m_pCurrentFieldMapChannel, &tmPivotPartyMember);
				if(NULL == pCharacterToPickup)
				{
					pDropItem->bProcessing = FALSE;
					return RES_BREAK;
				}
				CheckItemDistributeTypeOrder = TRUE;
			}
			break;
		case ITEM_DISTRIBUTE_TYPE_RANDOM:
			{
				pCharacterToPickup = pFParty->GetItemByRandomDistributeType(m_pCurrentFieldMapChannel);
				if(NULL == pCharacterToPickup)
				{
					pDropItem->bProcessing = FALSE;
					return RES_BREAK;	
				}
			}
			break;		
		}						

		pDropItem->pItem->AccountUniqueNumber	= pCharacterToPickup->m_character.AccountUniqueNumber;
		pDropItem->pItem->Possess				= pCharacterToPickup->m_character.CharacterUniqueNumber;
// 2009-08-25 by cmkwon, 사용하지 않는 필드 제거(td_Store.ScarcityNumber) - 
//		pDropItem->pItem->ScarcityNumber		= 0;
		pDropItem->pItem->Wear					= WEAR_NOT_ATTACHED;
		pDropItem->pItem->ItemWindowIndex		= POS_INVALID_POSITION;	// 서버에서는 아이템 창의 첫 slot에 넣어두고, 정리는 client에서 한다.
		pDropItem->pItem->NumOfEnchants			= 0;
		
		if (FALSE == pCharacterToPickup->IsUsing() 
			|| CS_PLAYING != pCharacterToPickup->GetClientState())
		{
			pDropItem->bProcessing = FALSE;
			return RES_BREAK;
		}

		// lock m_mapItemGeneral, MSG_FC_ITEM_GET_ITEM
		mt_auto_lock igLock(&pCharacterToPickup->m_ItemManager.m_mapItemGeneral);

		///////////////////////////////////////////////////////////////////////////////
		// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - m_ItemManager.InsertItemGeneralByPointer() 이후에 pDropItem->pItem 의 메모리가 삭제될 수 있다
		// 2008-02-18 by cmkwon, 카운터블 아이템일 경우 발생 할 수 있다, 그래서 아래와 같이 임시 변수를 만들어서 처리한다.
		ITEM_GENERAL tmItemG = *(pDropItem->pItem);

		// 적재량 초과 안 됨, 캐릭터에게 삽입 시도
		if(FALSE == pCharacterToPickup->m_ItemManager.InsertItemGeneralByPointer(pDropItem->pItem, IUT_DROP_ITEM, TRUE))
		{// 인벤토리 용량 초과
						
			pDropItem->bProcessing = FALSE;
			pCharacterToPickup->SendErrorMessage(T_FC_ITEM_GET_ITEM, ERR_PROTOCOL_INVENTORY_FULL_ITEM
				, 0, m_ItemManager.GetMaxInventoryCount(), NULL, FALSE, FALSE);			// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
			return RES_BREAK;
		}

		if(CheckItemDistributeTypeOrder)
		{// 2008-06-10 by dhjin, EP3 편대 수정 - 아이템 순차 습득 다음 유저 증가 
			pFParty->IncreasePivotPartyMember(tmPivotPartyMember);
		}

		INIT_MSG(MSG_FC_PARTY_PUT_ITEM_OTHER, T_FC_PARTY_PUT_ITEM_OTHER, pPartyPutItem, SendBuf);
		pPartyPutItem->ClientIndex	= pCharacterToPickup->m_character.ClientIndex;
		pPartyPutItem->ItemNum		= tmItemG.ItemNum;
		pPartyPutItem->Amount		= tmItemG.CurrentCount;
		pFParty->SendMsgToMembersMap(SendBuf, MSG_SIZE(MSG_FC_PARTY_PUT_ITEM_OTHER),
			m_pCurrentFieldMapChannel, pCharacterToPickup->m_character.CharacterUniqueNumber);

		// send in range hide item
		INIT_MSG(MSG_FC_ITEM_HIDE_ITEM, T_FC_ITEM_HIDE_ITEM, pHideItem, SendBuf);
		pHideItem->ItemFieldIndex = (UINT)pDropItem->pItem;		// 2008-02-18 by cmkwon, ITEM_GENERAL 메모리 버그 수정 - 메모리 주소만 참조 하므로 메모리가 삭제되도 상관없으므로 수정 필요 없다.
		pHideItem->ClientIndex = this->m_character.ClientIndex;
		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pDropItem->Position, SendBuf, MSG_SIZE(MSG_FC_ITEM_HIDE_ITEM), m_pCurrentFieldMapChannel);
	}

	// mapProject에서 삭제
	m_pCurrentFieldMapChannel->DeleteDropItem(pDropItem->Position, (ITEM_GENERAL*)pMsgGetItem->ItemFieldIndex);
	return RES_RETURN_TRUE;
}

BOOL CFieldIOCPSocket::ChangeStat(BYTE i_nStatKind, Stat_t i_nChangeValue)
{
	///////////////////////////////////////////////////////////////////////////////
	// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - CFieldIOCPSocket::ChangeStat#
	// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
	//int nMaxStatPoint = (m_character.Level <= CHARACTER_LEVEL_100) ? CHARACTER_LEVEL_100_MAX_STAT_POINT : COUNT_MAX_STAT_POINT;
	int nMaxStatPoint = GET_MAX_STAT_POINT(m_character.Level);

	switch(i_nStatKind)
	{
	case STAT_ATTACK_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.AttackPart)	// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}
			m_character.GearStat.AttackPart += i_nChangeValue;
		}
		break;
	case STAT_DEFENSE_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.DefensePart)	// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}
			m_character.GearStat.DefensePart += i_nChangeValue;
		}
		break;
	case STAT_FUEL_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.FuelPart)		// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}			
			m_character.GearStat.FuelPart += i_nChangeValue;
		}
		break;
	case STAT_SOUL_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.SoulPart)		// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}
			m_character.GearStat.SoulPart += i_nChangeValue;
		}
		break;
	case STAT_SHIELD_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.ShieldPart)	// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}
			m_character.GearStat.ShieldPart += i_nChangeValue;
		}
		break;
	case STAT_DODGE_PART:
		{
			if(i_nChangeValue > 0
				&& nMaxStatPoint <= m_character.GearStat.DodgePart)		// 2009-12-29 by cmkwon, 캐릭터 최대 레벨 상향(110으로) - 
			{
				return FALSE;
			}
			m_character.GearStat.DodgePart += i_nChangeValue;
		}
		break;
	}

	return TRUE;
}

Err_t CFieldIOCPSocket::ResetStat(int i_nStat)
{
// 2005-11-15 by cmkwon, 아래 코드로 대체함
//	// 격납고에서만 가능
//	if (!IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
//	{
//		return ERR_PROTOCOL_REQ_NOT_CITY_MAP_CHANNEL;
//	}

	if(FALSE == this->IsCityCurrentFieldMapChannel()
		|| FALSE == m_character.CharacterMode)
	{// 2005-11-15 by cmkwon, 세력별 도시맵, 캐릭터 모드 체크
		return ERR_PROTOCOL_REQ_NOT_CITY_MAP_CHANNEL;
	}

	// 모든 무기 장착 해제 시 가능
	for (int i = 0; i < 9; i++)
	{
		if (m_arrAttachItems[i].ItemNum != 0)
		{
			return ERR_PROTOCOL_REQ_MUST_RELEASE_ALL_ITEM;
		}
	}

	GEAR_STAT tmChangeStat = CAtumSJ::GetGearStatChangeValueStruct(m_character.UnitKind)->GearStat1;

	switch(i_nStat)
	{
	case STAT_ALL_PART:
		{
// 2005-07-12 by cmkwon, 스탯 초기화시에 가지고 있는 스탯을 가지고 보너스 스탯을 계산한다.
//			this->m_character.BonusStat		= (m_character.Level-1)*BONUS_STAT_PER_A_LEVEL;
// 2005-11-15 by cmkwon, BonusStatPoint를 추가함
//			this->m_character.BonusStat		+= m_character.GearStat.AttackPart/tmChangeStat.AttackPart
//												+ m_character.GearStat.DefensePart/tmChangeStat.DefensePart
//												+ m_character.GearStat.FuelPart/tmChangeStat.FuelPart
//												+ m_character.GearStat.SoulPart/tmChangeStat.SoulPart
//												+ m_character.GearStat.ShieldPart/tmChangeStat.ShieldPart
//												+ m_character.GearStat.DodgePart/tmChangeStat.DodgePart
//												- 6;
			this->m_character.BonusStat		= (m_character.Level-1)*BONUS_STAT_PER_A_LEVEL + m_character.BonusStatPoint;   // 2005-11-15 by cmkwon
			this->m_character.GearStat		= tmChangeStat;
		}
		break;
//	case DES_CASH_STAT_HALF_INITIALIZE:
//		{
//		}
//		break;
	case STAT_ATTACK_PART:
		{
			if(0 != this->m_character.GearStat.AttackPart%tmChangeStat.AttackPart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.AttackPart == tmChangeStat.AttackPart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.AttackPart/tmChangeStat.AttackPart - 1;
			this->m_character.GearStat.AttackPart = tmChangeStat.AttackPart;
		}
		break;
	case STAT_DEFENSE_PART:
		{
			if(0 != this->m_character.GearStat.DefensePart%tmChangeStat.DefensePart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.DefensePart == tmChangeStat.DefensePart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.DefensePart/tmChangeStat.DefensePart - 1;
			this->m_character.GearStat.DefensePart = tmChangeStat.DefensePart;
		}
		break;
	case STAT_FUEL_PART:
		{
			if(0 != this->m_character.GearStat.FuelPart%tmChangeStat.FuelPart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.FuelPart == tmChangeStat.FuelPart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.FuelPart/tmChangeStat.FuelPart - 1;
			this->m_character.GearStat.FuelPart = tmChangeStat.FuelPart;
		}
		break;
	case STAT_SOUL_PART:
		{
			if(0 != this->m_character.GearStat.SoulPart%tmChangeStat.SoulPart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.SoulPart == tmChangeStat.SoulPart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.SoulPart/tmChangeStat.SoulPart - 1;
			this->m_character.GearStat.SoulPart = tmChangeStat.SoulPart;
		}
		break;
	case STAT_SHIELD_PART:
		{
			if(0 != this->m_character.GearStat.ShieldPart%tmChangeStat.ShieldPart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.ShieldPart == tmChangeStat.ShieldPart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.ShieldPart/tmChangeStat.ShieldPart - 1;
			this->m_character.GearStat.ShieldPart = tmChangeStat.ShieldPart;
		}
		break;
	case STAT_DODGE_PART:
		{
			if(0 != this->m_character.GearStat.DodgePart%tmChangeStat.DodgePart)
			{
				return ERR_PROTOCOL_STAT_ERROR_STATE;
			}
			if(this->m_character.GearStat.DodgePart == tmChangeStat.DodgePart)
			{
				return ERR_PROTOCOL_STAT_INITIALIZE_STATE;
			}
			this->m_character.BonusStat += this->m_character.GearStat.DodgePart/tmChangeStat.DodgePart - 1;
			this->m_character.GearStat.DodgePart = tmChangeStat.DodgePart;
		}
		break;
	default:
		{
			return ERR_PROTOCOL_INVALID_STAT_VALUE_OR_KIND;
		}
	}

	m_character.AutoStatType	= AUTOSTAT_TYPE_FREESTYLE;
// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
//	this->CheckArmor_SendTotalStat(TRUE);
//	this->SendStat_UpdateDB();
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
	this->RearrangeCharacterTatalStat(TRUE, TRUE, TRUE);		// called CFieldIOCPSocket::ResetStat#

	SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0041);
	return ERR_NO_ERROR;
}

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
void CFieldIOCPSocket::SendStat_UpdateDB(BOOL i_bSendGearStat/*=TRUE*/, BOOL i_bSendTotalGearStat/*=TRUE*/, BOOL i_bUpdateDB/*=FALSE*/)
{
	if(i_bSendGearStat)
	{
		// SendMSG
		INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_CHANGE_STAT, T_FC_CHARACTER_CHANGE_STAT, pMsgChangeStat, pMsgChangeStatBuf);
		pMsgChangeStat->ClientIndex	= m_character.ClientIndex;
		pMsgChangeStat->GearStat1	= m_character.GearStat;
		pMsgChangeStat->BonusStat	= m_character.BonusStat;
		SendAddData(pMsgChangeStatBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_STAT));
	}
	if(i_bSendTotalGearStat)
	{
		///////////////////////////////////////////////////////////////////////////////
		// TotalGearStat를 Client로 전송한다
		INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_CHANGE_TOTALGEAR_STAT, T_FC_CHARACTER_CHANGE_TOTALGEAR_STAT, pMsgChangeStat, pMsgChangeStatBuf);
		pMsgChangeStat->ClientIndex		= m_character.ClientIndex;
		pMsgChangeStat->byAutoStatType	= m_character.AutoStatType;
		pMsgChangeStat->GearStat1		= m_character.TotalGearStat;
		SendAddData(pMsgChangeStatBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_TOTALGEAR_STAT));
	}

	if(i_bUpdateDB)
	{
		// Update DB
		QPARAM_CHARACTER_CHANGE_STAT	*pQChangeStat = new QPARAM_CHARACTER_CHANGE_STAT;
		pQChangeStat->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQChangeStat->byAutoStatType		= m_character.AutoStatType;
		pQChangeStat->HP					= m_character.HP;
		pQChangeStat->DP					= m_character.DP;
		pQChangeStat->SP					= m_character.SP;
		pQChangeStat->EP					= m_character.EP;
		pQChangeStat->GearStat1				= m_character.GearStat;
		pQChangeStat->BonusStat				= m_character.BonusStat;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeStat, this, m_character.AccountUniqueNumber, pQChangeStat);
	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::UpdateDBtoBonusStatPoint(void)
/// \brief		
/// \author		cmkwon
/// \date		2005-11-15 ~ 2005-11-15
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::UpdateDBtoBonusStatPoint(void)
{
	QPARAM_CHARACTER_CHANGE_BONUSSTATPOINT	*pQBonusStatPoint = new QPARAM_CHARACTER_CHANGE_BONUSSTATPOINT;
	pQBonusStatPoint->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pQBonusStatPoint->BonusStatPoint		= m_character.BonusStatPoint;
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeBonusStatPoint, this, m_character.AccountUniqueNumber, pQBonusStatPoint);
}

// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
// ///////////////////////////////////////////////////////////////////////////////
// /// \fn			
// /// \brief		아머가 장착 여부를 체크하고 
// /// \author		cmkwon
// /// \date		2005-03-04 ~ 2005-03-04
// /// \warning	
// ///
// /// \param		
// /// \return		
// ///////////////////////////////////////////////////////////////////////////////
// void CFieldIOCPSocket::CheckArmor_SendTotalStat(BOOL i_bRecalculateComputerItem/*=FALSE*/)
// {
// 	if(i_bRecalculateComputerItem)
// 	{
// 		this->m_character.TotalGearStat = this->m_character.GearStat;
// 
// 		///////////////////////////////////////////////////////////////////////////////
// 		// 컴퓨터 아이템 장착 여부 체크
// 		if(0 != m_ItemProwIn.ItemNum)
// 		{
// 			ITEM_GENERAL *pItemG = (ITEM_GENERAL*)m_ItemProwIn.ItemNum;
// 			if(pItemG
// 				&& pItemG->Kind == ITEMKIND_COMPUTER)
// 			{
// // 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// // 				ApplyComputerGearStat(pItemG->ItemInfo->DestParameter1, pItemG->ItemInfo->ParameterValue1);
// // 				ApplyComputerGearStat(pItemG->ItemInfo->DestParameter2, pItemG->ItemInfo->ParameterValue2);
// // 				ApplyComputerGearStat(pItemG->ItemInfo->DestParameter3, pItemG->ItemInfo->ParameterValue3);
// // 				ApplyComputerGearStat(pItemG->ItemInfo->DestParameter4, pItemG->ItemInfo->ParameterValue4);
// 				for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
// 				{
// 					ApplyComputerGearStat(pItemG->ItemInfo->ArrDestParameter[i], pItemG->ItemInfo->ArrParameterValue[i]);
// 				}
// 			}
// 		}
// 
// 		this->ChangeEP(GetCharacterTotalEP());
// 
// 		// 2010-02-19 by cmkwon, 100이하 레벨 최대스탯 수치 버그 수정 - 인자추가(, BYTE i_byLevel)
// 		this->ChangeSP(CAtumSJ::GetCharacterSP(m_character.TotalGearStat.SoulPart, m_character.Level));	// SP 변경
// 	}
// 	
// 	CheckArmorState();				// 아머 장착 여부에 따른 HP, DP 계산
// 
// 	///////////////////////////////////////////////////////////////////////////////
// 	// TotalGearStat를 Client로 전송한다
// 	INIT_MSG_OF_SIZE(MSG_FC_CHARACTER_CHANGE_TOTALGEAR_STAT, T_FC_CHARACTER_CHANGE_TOTALGEAR_STAT, pMsgChangeStat, pMsgChangeStatBuf);
// 	pMsgChangeStat->ClientIndex		= m_character.ClientIndex;
// 	pMsgChangeStat->byAutoStatType	= m_character.AutoStatType;
// 	pMsgChangeStat->GearStat1		= m_character.TotalGearStat;
// 	SendAddData(pMsgChangeStatBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_TOTALGEAR_STAT));
// }
//
// void CFieldIOCPSocket::DistributeBonusStatByAutoStatType(void)
// {
// 	if(m_character.Level > 20
// 		|| AUTOSTAT_TYPE_FREESTYLE == m_character.AutoStatType
// 		|| AUTOSTAT_TYPE_MGEAR_SUPPORT < m_character.AutoStatType)
// 	{
// 		if(AUTOSTAT_TYPE_FREESTYLE != m_character.AutoStatType)
// 		{
// 			m_character.AutoStatType	= AUTOSTAT_TYPE_FREESTYLE;
// 			this->CheckArmor_SendTotalStat(TRUE);
// 			this->SendStat_UpdateDB();
// 		}
// 		return;
// 	}
// 	else if(m_character.BonusStat <= 0)
// 	{
// 		return;
// 	}
// 
// 	GEAR_AUTO_STAT_VALUE_PER_LEVEL tmLevelStat;
// 	if(FALSE == CAtumSJ::GetGearStatBYAutoStatTypeAndLevel(&tmLevelStat, m_character.AutoStatType, m_character.Level))
// 	{
// 		return;
// 	}
// 
// 	do 
// 	{
// 		BYTE byKindOfStat;
// 		if(tmLevelStat.GearStat1.AttackPart > m_character.GearStat.AttackPart)
// 		{
// 			byKindOfStat	= STAT_ATTACK_PART;
// 		}
// 		else if(tmLevelStat.GearStat1.DefensePart > m_character.GearStat.DefensePart)
// 		{
// 			byKindOfStat	= STAT_DEFENSE_PART;
// 		}
// 		else if(tmLevelStat.GearStat1.FuelPart > m_character.GearStat.FuelPart)
// 		{
// 			byKindOfStat	= STAT_FUEL_PART;
// 		}
// 		else if(tmLevelStat.GearStat1.SoulPart > m_character.GearStat.SoulPart)
// 		{
// 			byKindOfStat	= STAT_SOUL_PART;
// 		}
// 		else if(tmLevelStat.GearStat1.ShieldPart > m_character.GearStat.ShieldPart)
// 		{
// 			byKindOfStat	= STAT_SHIELD_PART;
// 		}
// 		else
// 		{
// 			byKindOfStat	= STAT_DODGE_PART;
// 		}
// 
// 		// 스탯 변경
// 		if( FALSE == ChangeStat(byKindOfStat, CAtumSJ::GetGearStatChangeValue(m_character.UnitKind, byKindOfStat)) )
// 		{
// 			break;
// 		}
// 		
// 		m_character.BonusStat--;
// 		CAtumLogSender::SendLogMessageSTAT(this, byKindOfStat, m_character.BonusStat);		// 로그 남기기 - 남은 스탯 저장
// 	} while(m_character.BonusStat > 0);
// 	
// 	this->CheckArmor_SendTotalStat(TRUE);
// 	this->SendStat_UpdateDB();
// }


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::ChangeCharacterInfluenceType(BYTE i_byInfluenceTy, BOOL i_bAdminCommand/*=FALSE*/)
/// \brief		
/// \author		cmkwon
/// \date		2005-12-03 ~ 2005-12-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::ChangeCharacterInfluenceType(BYTE i_byInfluenceTy, BOOL i_bAdminCommand/*=FALSE*/)
{
	if(FALSE == i_bAdminCommand
		&& FALSE == GIsValidInfuenceType(i_byInfluenceTy))
	{
		return FALSE;
	}

	// 2009-02-10 by cmkwon, 세력 유저 카운트 관련 수정 - 세력을 처음 선택 할 때만 증가시킨다.
	if(m_character.SelectableInfluenceMask != i_byInfluenceTy)
	{
		// 2006-02-08 by cmkwon, 세력 분포 계산을 위해 선택한 세력을 증가한다.
		ms_pFieldIOCP->AddInfluenceTypeCount(i_byInfluenceTy);

		///////////////////////////////////////////////////////////////////////////////
		// 2009-09-16 by cmkwon, 세력 초기화시 어뷰징 방지 구현 - 
		ms_pFieldIOCP->m_InflRateMan.OnChangeInfluence(i_byInfluenceTy, m_character.Level);
	}
	
	m_character.InfluenceType					= i_byInfluenceTy;	// m_character에 적용
	m_character.SelectableInfluenceMask			= m_character.InfluenceType;
	this->SetSelectableInfluenceMask(m_character.InfluenceType);	// 2005-12-07 by cmkwon

	// 2006-02-09 by cmkwon, 자신이 타세력에 의해 죽을 경우 줘야 할 킬마크 설정
	this->ResetGiveKillMarkItemPtr2Killer();

	// DB 수정
	QPARAM_CHARACTER_CHANGE_INFLUENCE_TYPE *pQChangeInfluence = new QPARAM_CHARACTER_CHANGE_INFLUENCE_TYPE;
	pQChangeInfluence->AccountUniqueNumber		= m_character.AccountUniqueNumber;
	pQChangeInfluence->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
	pQChangeInfluence->InfluenceType0			= m_character.InfluenceType;
	pQChangeInfluence->SelectableInfluenceMask0	= this->GetSelectableInfluenceMask();
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeInfluenceType, this, m_character.AccountUniqueNumber, pQChangeInfluence);

	// 자신과 주위에 변경정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_CHANGE_INFLUENCE_TYPE, T_FC_CHARACTER_CHANGE_INFLUENCE_TYPE, pSInfluence, SendBuf);
	pSInfluence->ClientIndex	= m_character.ClientIndex;
	pSInfluence->InfluenceType0	= m_character.InfluenceType;
	this->SendInRangeMessageAroundMe(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_CHANGE_INFLUENCE_TYPE), TRUE);

	// 2005-12-03 by cmkwon, IMServer로 전송
	INIT_MSG(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));

	// 2005-12-03 by cmkwon, NPCServer로 전송
	INIT_MSG(MSG_FN_CHARACTER_CHANGE_INFLUENCE_TYPE, T_FN_CHARACTER_CHANGE_INFLUENCE_TYPE, pS2NInfluence, SendBuf);
	pS2NInfluence->ChannelIndex		= GetCurrentFieldMapChannel()->m_MapChannelIndex.ChannelIndex;
	pS2NInfluence->ClientIndex		= m_character.ClientIndex;
	pS2NInfluence->InfluenceType0	= m_character.InfluenceType;
	GetCurrentFieldMapChannel()->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_CHARACTER_CHANGE_INFLUENCE_TYPE));

// 2009-03-31 by dhjin, 선전 포고 - 세력전 승리 시 지급 되는 이벤트 수정
//	///////////////////////////////////////////////////////////////////////////////
//	// 2006-04-26 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));
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-07-20 by dhjin, ITEM_EVENT_TYPE_ONLYSTART 이벤트 아이템 체크 
	if(FALSE == i_bAdminCommand)
	{
		vectItemEventInfo		vectItemEventInfo1;
// 2008-02-01 by cmkwon, ItemEvent 에 LastGameEndDate 체크 루틴 추가 - 
//		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemInflChange(&vectItemEventInfo1, &m_AccountRegisteredDate, m_character.UnitKind);
		ms_pFieldIOCP->m_pGiveItemManager->GetActEventItemInflChange(&vectItemEventInfo1, m_ItemManager.IsExistPremiumCard(), m_bIsPCBangClient, \
			m_character.InfluenceType, m_character.UnitKind, &m_AccountRegisteredDate, 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, 아이템 이벤트 - 서브타입 추가구조로 변경

			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	= m_character.CharacterUniqueNumber; // 2014-03-12 by jekim, 주민번호당 아이템 지급	// 2009-11-19 by cmkwon, 아이템 이벤트에 Account/Character 체크 기능 추가 - 
			pQParam->CheckWithCharacterUID = vectItemEventInfo1[i].CheckWithCharacterUID; // 2014-03-12 by jekim, 주민번호당 아이템 지급
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckEventItem, this, m_character.AccountUniqueNumber, pQParam);
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
	vectSQUEST_MATCH_CHANGE tmQuestMatchIndex;
	vectSITEM_MATCH_CHANGE	tmItemMatchIndex;
	if(ms_pFieldIOCP->m_QuestMatching.IsChangeInfluence(i_byInfluenceTy, this, &tmQuestMatchIndex, &tmItemMatchIndex))
	{
		// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
		g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s to %s \r\n", GetCharacterString(this->GetCharacter(), string()), CAtumSJ::GetInfluenceTypeString(i_byInfluenceTy));

		// 1. 퀘스트 처리
		vectINT		tmQuetIndexListToDelete;		// 퀘스트 처리 후 삭제 해야 할 퀘스트 리스트 
		vectSQUEST_MATCH_CHANGE::iterator itrQM(tmQuestMatchIndex.begin());
		for(; itrQM != tmQuestMatchIndex.end(); itrQM++)
		{
			SQUEST_MATCH_CHANGE *pMatchIndex = itrQM;
			if(0 == pMatchIndex->FromQuestIndex)
			{// 2009-04-01 by cmkwon, 소스 QuestIndex가 비어 있다면 해당 퀘스트 요구 레벨을 체크해서 추가 혹은 처리 없음.

				CQuest *pQuestNew = ms_pFieldIOCP->GetQuestInfo(pMatchIndex->ToQuestIndex);
				if(NULL == pQuestNew)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ChangeCharacterInfluenceType# 1 %s From %d to %d \r\n"
						,GetCharacterString(this->GetCharacter(), string()), pMatchIndex->FromQuestIndex, pMatchIndex->ToQuestIndex);
					continue;
				}

				if(pQuestNew->ReqLevel.Min > m_character.Level)
				{// 요구 레벨 미만이면 추가 필요 업다
					continue;
				}

				CharacterQuest *pQInsertQuest = new CharacterQuest;
				pQInsertQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
				pQInsertQuest->QuestIndex				= pQuestNew->QuestIndex;
				pQInsertQuest->QuestState				= QUEST_STATE_COMPLETED;
				pQInsertQuest->QuestParam1				= 0;
				pQInsertQuest->QuestTimeStamp.SetCurrentDateTime();
				pQInsertQuest->QuestPlayTimeStamp		= GetTotalPlayTimeInSeconds();
				
				m_mapQuest.insertNoLock(pQuestNew->QuestIndex, CFieldCharacterQuest(pQInsertQuest, pQuestNew));
				
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertQuest, this, m_character.AccountUniqueNumber, pQInsertQuest);

				///////////////////////////////////////////////////////////////////////////////
				// 클라이언트로 완료 상태의 퀘스트 추가 프로토콜 전송
				INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_INSERT_QUEST, T_FC_QUEST_INSERT_QUEST, pInsertQuest, SendBuf);
				pInsertQuest->QuestIndex	= pQuestNew->QuestIndex;
				pInsertQuest->QuestState	= QUEST_STATE_COMPLETED;
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_INSERT_QUEST));
			
				// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
				g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s insert quest(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pMatchIndex->ToQuestIndex);
			}
			else
			{
				CFieldCharacterQuest *pFCharQuest = this->GetFieldCharacterQuestPtrByQuestIndex(pMatchIndex->FromQuestIndex);
				if(NULL == pFCharQuest)
				{// 2009-04-01 by cmkwon, 해당 퀘스트가 없으면 다음 퀘스트
					continue;
				}
				else if(pFCharQuest->QuestState == QUEST_STATE_IN_PROGRESS)
				{
					g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s From %d to %d, QuestState(%d) \r\n"
						,GetCharacterString(this->GetCharacter(), string()), pMatchIndex->FromQuestIndex, pMatchIndex->ToQuestIndex, pFCharQuest->QuestState);
					continue;
				}

				if(0 == pMatchIndex->ToQuestIndex)
				{// 2009-04-01 by cmkwon, 타겟 QuestIndex가 없다면 해당 퀘스트는 삭제처리

					tmQuetIndexListToDelete.push_back(pMatchIndex->FromQuestIndex);
					
					// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
					g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s delete quest(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pMatchIndex->FromQuestIndex);
				}
				else
				{// 2009-04-01 by cmkwon, 소스 QuestIndex와 타겟 QuestIndex 둘다 있다면 변경 처리

					if(NULL != GetFieldCharacterQuestPtrByQuestIndex(pMatchIndex->ToQuestIndex))
					{// 2009-04-02 by cmkwon, 중복으로 처리를 해준다. 이미 추가 되어 있으므로 따로 처리 할 필요 없음
						continue;
					}

					CQuest *pQuestNew = ms_pFieldIOCP->GetQuestInfo(pMatchIndex->ToQuestIndex);
					if(NULL == pQuestNew)
					{
						g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::ChangeCharacterInfluenceType# 2 %s From %d to %d \r\n"
							,GetCharacterString(this->GetCharacter(), string()), pMatchIndex->FromQuestIndex, pMatchIndex->ToQuestIndex);
						continue;
					}

					// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
					g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s insert quest(%d), delete quest(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pMatchIndex->FromQuestIndex, pMatchIndex->ToQuestIndex);

					CharacterQuest *pQInsertQuest = new CharacterQuest;
					pQInsertQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
					pQInsertQuest->QuestIndex				= pMatchIndex->ToQuestIndex;
					pQInsertQuest->QuestState				= QUEST_STATE_COMPLETED;
					pQInsertQuest->QuestParam1				= 0;
					pQInsertQuest->QuestTimeStamp.SetCurrentDateTime();
					pQInsertQuest->QuestPlayTimeStamp		= GetTotalPlayTimeInSeconds();
					
					m_mapQuest.insertNoLock(pQuestNew->QuestIndex, CFieldCharacterQuest(pQInsertQuest, pQuestNew));					
					ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertQuest, this, m_character.AccountUniqueNumber, pQInsertQuest);

					///////////////////////////////////////////////////////////////////////////////
					// 클라이언트로 완료 상태의 퀘스트 추가 프로토콜 전송
					INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_INSERT_QUEST, T_FC_QUEST_INSERT_QUEST, pInsertQuest, SendBuf);
					pInsertQuest->QuestIndex	= pQuestNew->QuestIndex;
					pInsertQuest->QuestState	= QUEST_STATE_COMPLETED;
					this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_INSERT_QUEST));
					
					tmQuetIndexListToDelete.push_back(pMatchIndex->FromQuestIndex);					
				}
			}
		} // END - for(; itrQM != tmQuestMatchIndex.end(); itrQM++)
		vectINT::iterator	itrQID(tmQuetIndexListToDelete.begin());
		for(; itrQID != tmQuetIndexListToDelete.end(); itrQID++)
		{
			INT nDelQuestIndex = *itrQID;
			if(GetFieldCharacterQuestPtrByQuestIndex(nDelQuestIndex))
			{
				// 퀘스트 지우기 - DB
				QPARAM_DELETE_QUEST *pQDeleteQuest		= new QPARAM_DELETE_QUEST;
				pQDeleteQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
				pQDeleteQuest->QuestIndex				= nDelQuestIndex;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);
				
				m_mapQuest.deleteLock(nDelQuestIndex);
				
				///////////////////////////////////////////////////////////////////////////////
				// 클라이언트로 퀘스트 삭제 프로토콜 전송
				INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_DELETE_QUEST, T_FC_QUEST_DELETE_QUEST, pDelQuest, SendBuf);
				pDelQuest->QuestIndex	= nDelQuestIndex;
				this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_DELETE_QUEST));
			}
		}

		// 2. 인벤 아이템 처리
		vectSITEM_MATCH_CHANGE::iterator itrIM(tmItemMatchIndex.begin());
		for(; itrIM != tmItemMatchIndex.end(); itrIM++)
		{
			SITEM_MATCH_CHANGE *pItemChange = itrIM;

			// 2009-04-01 by cmkwon, 변경 해야 할 아이템 1개라도 있다면 변경 처리 진행
			ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pItemChange->FromItemNum);
			if(pItemG)
			{
				// 2013-11-21 by jhseol, 세력변경시 세력아이템 자동 장착 해제 - 고대의 화살, 거신의 석궁
				if ( WEAR_ATTACHED == pItemG->Wear )
				{
					MSG_FC_ITEM_CHANGE_WINDOW_POSITION tmItemChangePos;
					MEMSET_ZERO(&tmItemChangePos, sizeof(MSG_FC_ITEM_CHANGE_WINDOW_POSITION));
					tmItemChangePos.CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
					tmItemChangePos.FromItemUniqueNumber	= pItemG->UniqueNumber;
					tmItemChangePos.FromItemWindowIndex		= pItemG->ItemWindowIndex;
					tmItemChangePos.ToItemUniqueNumber		= 0;
					tmItemChangePos.ToItemWindowIndex		= POS_ITEMWINDOW_OFFSET;
					ProcessItemChangeWindowPosition(&tmItemChangePos, FALSE, FALSE);
				}
				// end 2013-11-21 by jhseol, 세력변경시 세력아이템 자동 장착 해제 - 고대의 화살, 거신의 석궁
				// 2009-03-31 by cmkwon, 세력초기화 시스템 구현 - 
				g_pGlobal->WriteSystemLogEX(TRUE, "  [Notify] CFieldIOCPSocket::ChangeCharacterInfluenceType# %s change ItemNum from %d to %d , ItemCount(%d) \r\n", GetCharacterString(this->GetCharacter(), string()), pItemChange->FromItemNum, pItemChange->ToItemNum, pItemG->CurrentCount);

				m_ItemManager.ChangeItemNum(pItemChange->FromItemNum, pItemChange->ToItemNum);
			}
		}

		// 3. 창고 아이템 처리 - DB만 변경하면된다.
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangeItemWithItemMatching, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber, i_byInfluenceTy);
	}
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ApplyParamFactorWithAccesoryTimeLimiteItem(ITEM *i_pItemInfo)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-24 ~ 2006-04-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyParamFactorWithAccesoryTimeLimiteItem(ITEM *i_pItemInfo)
{
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 	SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter1, i_pItemInfo->ParameterValue1);
// 	SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter2, i_pItemInfo->ParameterValue2);
// 	SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter3, i_pItemInfo->ParameterValue3);
// 	SetParamFactor(&m_ParamFactor, i_pItemInfo->DestParameter4, i_pItemInfo->ParameterValue4);
	for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
	{
		SetParamFactor(&m_ParamFactor, i_pItemInfo->ArrDestParameter[i], i_pItemInfo->ArrParameterValue[i]);
	}

}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ApplyParamFactorWithAllUsingTimeLimitedOnlyCardItemW(void)
/// \brief		사용중인 시간 제한 아이템중에 ITEMKIND_CARD의 Desparam 적용
/// \author		cmkwon
/// \date		2006-04-24 ~ 2006-04-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ApplyParamFactorWithAllUsingTimeLimitedOnlyCardItemW(void)
{
	m_ItemManager.ApplyParamFactorWithAllUsingTimeLimitedOnlyCardItem();
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ArenaWarpSetHPDPSPEP()
/// \brief		아레나 맵으로 이동시 처리 해야되는 HP,DP,SP,EP
/// \author		dhjin
/// \date		2007-05-11 ~ 2007-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ArenaWarpSetHPDPSPEP()
{
	//////////////////////////////////////////////////////////////////////////
	// 2007-05-11 by dhjin, 아레나 맵으로 이동하기 전에 현재 HP, DP, SP, EP를 저장하고 만피 시킨 후 워프
	this->m_ArenaInfo.SaveHP	= this->m_character.CurrentHP;
	this->m_ArenaInfo.SaveDP	= this->m_character.CurrentDP;
	this->m_ArenaInfo.SaveSP	= this->m_character.CurrentSP;
	this->m_ArenaInfo.SaveEP	= this->m_character.CurrentEP;
	this->m_ArenaInfo.SaveBodyCondition = this->m_character.BodyCondition;

	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);
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::ArenaWarpCitySetHPDPSPEP(BOOL i_bSendClient/*=TRUE*/)
/// \brief		아레나 맵에서 마을로 이동시 처리 해야되는 HP,DP,SP,EP
/// \author		dhjin
/// \date		2007-05-11 ~ 2007-05-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::ArenaWarpCitySetHPDPSPEP(BOOL i_bSendClient/*=TRUE*/)
{
	// 2007-05-11 by dhjin, 마을로 워프 시 아레나 맵으로 이동하기 전 HP, DP, SP, EP로 설정한다.
	this->m_character.CurrentHP  = this->m_ArenaInfo.SaveHP;
	this->m_character.CurrentDP  = this->m_ArenaInfo.SaveDP;
	this->m_character.CurrentSP  = this->m_ArenaInfo.SaveSP;
	this->m_character.CurrentEP  = this->m_ArenaInfo.SaveEP;
	this->m_character.BodyCondition = this->m_ArenaInfo.SaveBodyCondition;
	if(i_bSendClient)
	{
		this->SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTHPDPSPEP);
	}
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
/// \author		cmkwon
/// \date		2010-03-05 ~ 2010-03-05
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::RearrangeCharacterTatalStat(BOOL i_bSendGearStat/*=TRUE*/, BOOL i_bSendTotalGearStat/*=TRUE*/, BOOL i_bUpdateDB/*=FALSE*/)
{
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));

	this->m_character.TotalGearStat = this->m_character.GearStat;

	ITEM_GENERAL *pCPUItemG = GetAttachItemGeneralByPosition(POS_PROWIN);
	if(pCPUItemG)
	{
		this->CheckComputerState(pCPUItemG->ItemInfo, TRUE, FALSE);
	}

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 스텟적용
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 스텟적용
	ITEM_GENERAL *pArmorItem = GetAttachItemGeneralByPosition(POS_CENTER);
	if( NULL != pArmorItem )
	{
		if( SHAPE_STAT_INIT_LEVEL < pArmorItem->FixedTermShape.nStatLevel ) // 0 이상 이면 외변킷이 적용된 아머 
		{
			ITEM *pShapeKitItem = ms_pFieldIOCP->GetItemInfo(pArmorItem->FixedTermShape.nStatShapeItemNum);
			if ( NULL != pShapeKitItem )
			{
				if ( TRUE == pShapeKitItem->IsExistDesParam(DES_ALL_PART) )
				{
					CheckAllState(pShapeKitItem->GetParameterValue(DES_ALL_PART)*min(pArmorItem->FixedTermShape.nStatLevel, SHAPE_STAT_MAX_LEVEL), TRUE, FALSE);
				}
			}
		}
	}
#endif
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 스텟적용

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-17 by cmkwon, 인피1차 발동류 아이템 관련 버그 수정 - SP,EP는 스탯에 의해서만 변경, DP는 다른 아이템에 의해 변경 가능
	// 2010-03-11 by cmkwon, ResetAllSkillAndEnchant함수 호출 구조 변경(called OnAttach or OnDetach) - 스탯변경시 SP 계산 및 전달 처리
	this->ChangeSP(CAtumSJ::GetCharacterSP(m_character.TotalGearStat.SoulPart, m_character.Level), i_bUpdateDB);
	if(i_bSendGearStat)
	{
		this->ChangeEP(GetCharacterTotalEP(), i_bUpdateDB);		// 2010-03-31 by cmkwon, 연료 관련 버그 수정(K0002796) - DP와 같은 방식으로 변경
		this->ChangeDP(GetCharacterTotalDP());
	}

	this->SendStat_UpdateDB(i_bSendGearStat, i_bSendTotalGearStat, i_bUpdateDB);
}

ProcessResult CFieldIOCPSocket::Process_FC_CHARACTER_USE_BONUSSTAT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CHARACTER_USE_BONUSSTAT,
									MSG_FC_CHARACTER_USE_BONUSSTAT, pBonusStat);

	if(m_character.ClientIndex != pBonusStat->ClientIndex)
	{
		SendErrorMessage(T_FC_CHARACTER_USE_BONUSSTAT, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	if(AUTOSTAT_TYPE_FREESTYLE != m_character.AutoStatType
		&& m_character.Level <= 20)
	{
		SendErrorMessage(T_FC_CHARACTER_USE_BONUSSTAT, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

	if(m_character.BonusStat <= 0 || pBonusStat->KindOfStat > STAT_DODGE_PART)
	{
		// 보너스 포인트가 없거나 Stat의 종류가 유효하지 않다.
		SendErrorMessage(T_FC_CHARACTER_USE_BONUSSTAT, ERR_PROTOCOL_INVALID_STAT_VALUE_OR_KIND);
		return RES_BREAK;
	}

	// UnitKind와 KindOfStat에 의한 증가량 계산
	Stat_t cValue = CAtumSJ::GetGearStatChangeValue(m_character.UnitKind, pBonusStat->KindOfStat);

	// 스탯 변경
	BOOL bRet = ChangeStat(pBonusStat->KindOfStat, cValue);
	if(FALSE == bRet)
	{
		// 보너스 포인트가 없거나 Stat의 종류가 유효하지 않다.
		SendErrorMessage(T_FC_CHARACTER_USE_BONUSSTAT, ERR_PROTOCOL_LIMIT_STAT_POINT);
		return RES_BREAK;
	}
	
	this->m_character.BonusStat--;			// 보너스 스탯 1 감소

	///////////////////////////////////////////////////////////////////////////////
	// 2006-09-18 by cmkwon, 클라이언트<-->서버 동기화를 위해 프로토콜 추가
	INIT_MSG_WITH_BUFFER(MSG_FC_CHARACTER_USE_BONUSSTAT_OK, T_FC_CHARACTER_USE_BONUSSTAT_OK, pSMsg, SendBuf);
	pSMsg->byReaminBonusStat	= this->m_character.BonusStat;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_CHARACTER_USE_BONUSSTAT_OK));

	CAtumLogSender::SendLogMessageSTAT(this, pBonusStat->KindOfStat, m_character.BonusStat);	// 로그 남기기 - 남은 스탯 저장
// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
//	this->CheckArmor_SendTotalStat(TRUE);
	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-05 by cmkwon, 발동류 관련으로구조 변경 - 
	this->RearrangeCharacterTatalStat(TRUE, TRUE, TRUE);		// called CFieldIOCPSocket::Process_FC_CHARACTER_USE_BONUSSTAT#
	this->ResetAllSkillAndEnchant();		// called CFieldIOCPSocket::Process_FC_CHARACTER_USE_BONUSSTAT#
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_UPDATE_WINDOW_ITEM_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize = 0;
	
	MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST	*pRecvList = (MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST*)(pPacket+nBytesUsed);
	nRecvTypeSize = sizeof(MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST)
		+ pRecvList->NumOfItems * sizeof(ITEM_WINDOW_INFO);

	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		// Protocl Error 처리
		// - Client로 부터 받은 Data Size가 Field Type에 따른 Data Size보다 작다
		// Error Code : ERR_PROTOCOL_INVALID_FIELD_DATA
		SendErrorMessage(T_FC_ITEM_UPDATE_WINDOW_ITEM_LIST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14035);
		return RES_RETURN_FALSE;
	}

	ITEM_WINDOW_INFO *pRecvWindowInfo = (ITEM_WINDOW_INFO*)(pPacket+nBytesUsed+sizeof(MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST));	
	nBytesUsed += nRecvTypeSize;

	MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST	*pStoreList = (MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST*)(new char[nRecvTypeSize]);
	ITEM_WINDOW_INFO *pStoreWindowInfo = (ITEM_WINDOW_INFO*)((char*)pStoreList + sizeof(MSG_FC_ITEM_UPDATE_WINDOW_ITEM_LIST));

	pStoreList->NumOfItems = 0;
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);	
	{
		for(int i=0; i < pRecvList->NumOfItems; i++, pRecvWindowInfo++)
		{
			ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pRecvWindowInfo->ItemUniqueNumber);
			if(pItemGeneral
				&& POS_HIDDEN_ITEM != pItemGeneral->ItemWindowIndex		// 2011-09-30 by hskim, 파트너 시스템 2차 - 클라쪽의 실수 방지 (숨겨진 아이템은 옮길수 없다)
				&&(pRecvWindowInfo->Wear != pItemGeneral->Wear || pRecvWindowInfo->ItemWindowIndex != pItemGeneral->ItemWindowIndex))
			{
				*pStoreWindowInfo = *pRecvWindowInfo;
				pStoreWindowInfo++;
				pStoreList->NumOfItems++;
			}
		}
	}
	igLock.auto_unlock_cancel();

	if(0 < pStoreList->NumOfItems)
	{
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateWindowItemList, this, m_character.AccountUniqueNumber, pStoreList);
	}
	else
	{
		SAFE_DELETE(pStoreList);
	}
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_THROW_AWAY_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_THROW_AWAY_ITEM,
									MSG_FC_ITEM_THROW_AWAY_ITEM, pMsgThrowAwayItem);

	if(m_character.ClientIndex != pMsgThrowAwayItem->ClientIndex)
	{
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_INVALID_CLIENTINDEX);
		return RES_BREAK;
	}

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

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_THROW_AWAY_ITEM
	if(this->CheckTradingItem(pMsgThrowAwayItem->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_ITEM_TRADING, pMsgThrowAwayItem->ItemUniqueNumber);
		return RES_BREAK;
	}

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

	ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(pMsgThrowAwayItem->ItemUniqueNumber);
	if (pItemGeneral == NULL)
	{
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}

	// 2007-06-20 by cmkwon, 장착된 아이템은 삭제 불가 - 베트남에서의 버그 수정
	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - 
	//if(SIZE_MAX_POS > pItemGeneral->ItemWindowIndex)
	if(IS_ATTACHABLE_POSITION(pItemGeneral->ItemWindowIndex))
	{
		// 2008-01-31 by cmkwon, 시스템 로그 정보 추가
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_CANNOT_UNWEAR_ARMOR, pItemGeneral->ItemNum, pItemGeneral->ItemWindowIndex);
		return RES_BREAK;
	}

	if (!COMPARE_RACE(m_character.Race, RACE_OPERATION)
		&& COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_NOT_STORE_SAVE)) // 2011-06-07 by shcho, 베트남 요청 창고에만 저장 불가 속성 구현
		
	{
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}

	// 2008-07-23 by cmkwon, 아이템 버리기 관련 수정 - 여기에서 카운터블 아이템 개수를 체크
	if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind)
		&& pMsgThrowAwayItem->Amount > pItemGeneral->CurrentCount)
	{
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED, pItemGeneral->CurrentCount, pMsgThrowAwayItem->Amount);
		return RES_BREAK;
	}

	mt_auto_lock bmLock(m_bazaarManager.GetBazaarItemListPtr());
	if(BAZAAR_TYPE_SELL == m_bazaarManager.GetBazaarType()
		&& NULL != m_bazaarManager.FindBazaarItemByItemUIDNoLock(pItemGeneral->UniqueNumber))
	{// 2006-08-07 by cmkwon, 판매 상점 아이템 체크
		SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER);
		return RES_BREAK;
	}
	bmLock.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2007-06-05 by cmkwon, 삭제아이템의 인챈트 정보를 처리한다.
	vectENCHANT tmvectEnchant;
	this->PopAllEnchantByItemUID(&tmvectEnchant, pItemGeneral->UniqueNumber);

	// send log
	CAtumLogSender::SendLogMessageITEMThrowAwayITEM(this, pItemGeneral, -pMsgThrowAwayItem->Amount, &tmvectEnchant);
	
	// 아이템 버리기
	if (IS_COUNTABLE_ITEM(pItemGeneral->ItemInfo->Kind))
	{
// 2008-07-23 by cmkwon, 아이템 버리기 관련 수정 - 위에서 체크 
// 		// 개수 확인
// 		if (pMsgThrowAwayItem->Amount > pItemGeneral->CurrentCount)
// 		{
// 			// 2008-01-31 by cmkwon, 시스템 로그 정보 추가
// 			SendErrorMessage(T_FC_ITEM_THROW_AWAY_ITEM, ERR_PROTOCOL_ITEM_AMOUNT_EXCEED, pItemGeneral->CurrentCount, pMsgThrowAwayItem->Amount);
// 			return RES_BREAK;
// 		}

		m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -pMsgThrowAwayItem->Amount, IUT_GENERAL);
	}
	else
	{
		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 삭제
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 아이템 삭제
		if ( ITEMKIND_DEFENSE == pItemGeneral->Kind && SHAPE_STAT_INIT_LEVEL < pItemGeneral->FixedTermShape.nStatLevel )
		{
			m_ArmorCollection.ChangeActivedCount(pItemGeneral->ShapeItemNum, FALSE);
		}
#endif
		// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 아이템 삭제
		m_ItemManager.DeleteItemFromCharacterByPointer(pItemGeneral, IUT_GENERAL);
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_ENERGY(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_ENERGY,
									MSG_FC_ITEM_USE_ENERGY, pMsgUseEnergy);

	if (FALSE == IsValidCharacter())
	{
//		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-08-07 by cmkwon, 개인 상점 개설중에는 아이템 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_USING_BAZAAR);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_ENERGY
	if(this->CheckTradingItem(pMsgUseEnergy->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_ITEM_TRADING, pMsgUseEnergy->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_ENERGY
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemEnergy = m_ItemManager.GetItemGeneralByUID(pMsgUseEnergy->ItemUniqueNumber);
	if (pItemEnergy == NULL)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnergy->ItemUniqueNumber);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemEnergy->ItemInfo->ItemAttribute, ITEM_ATTR_CANNOT_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(FALSE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemEnergy->ItemInfo->ItemAttribute, ITEM_ATTR_ONLY_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵에서만 사용 가능
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_INFINITY_ONLY_USE_ITEM);
		return RES_BREAK;
	}

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

	// Item Kind 확인
	if (pItemEnergy->Kind != ITEMKIND_ENERGY)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_INVALID_ITEM_KIND, pItemEnergy->ItemNum, pItemEnergy->Kind);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemEnergy->ItemInfo;
	if (pItemInfo == NULL)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_NO_SUCH_ITEM_INFO, pItemEnergy->ItemNum);
		return RES_BREAK;
	}

	if (pItemEnergy->CurrentCount <= 0)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_INVALID_ITEM_COUNT, pItemEnergy->CurrentCount, 0, pItemEnergy->ItemInfo->ItemName);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_ENERGY
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pItemInfo);
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_ALREADY_USE_ITEMPARAM, pItemInfo->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-06-01 by dhjin, 아레나 맵에서는 아레나 전용 HP/DP/SP/EP키트만 사용가능하다.
	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
	//switch(pItemInfo->DestParameter1)
	switch(pItemInfo->ArrDestParameter[0])
	{
	case DES_GRADUAL_HP_UP:
	case DES_GRADUAL_DP_UP:
	case DES_GRADUAL_EP_UP:
	case DES_IMMEDIATE_HP_UP:
	case DES_IMMEDIATE_DP_UP:
	case DES_IMMEDIATE_SP_UP:
	case DES_IMMEDIATE_EP_UP:
		{
			if (IS_MAP_INFLUENCE_ARENA(this->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
			{
				// 2007-06-01 by dhjin, 
				if(!COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_ARENA_ITEM))
				{
					SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_USE_ITEM_IN_ARENA, 0, 0, NULL, FALSE, FALSE);
					return RES_BREAK;
				}
			}
		}
		break;
	}


	BOOL bWarpArenaMap2CityMap		= FALSE;	// 2007-05-14 by cmkwon, 아레나맵에서 도시맵으로 워프

	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
	//switch(pItemInfo->DestParameter1)
	switch(pItemInfo->ArrDestParameter[0])
	{
	case DES_GRADUAL_HP_UP:
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_HP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_DEBUFF_SKILL_APPLYING_NOT_HP_RECOVERY);
				return RES_BREAK;
			}

			if (NULL != m_TimerManager.m_TEIDGradualHPUP
				|| 0 < m_TimerManager.m_nRemainedTimeOfGradualHPUP
				|| m_TimerManager.m_bImmediateHPTimerRunning)
			{// 사용중이면 쓸 수 없다.
// 2005-04-07 by cmkwon, 필요없음
//				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_HP_UP_ITEM);
				return RES_BREAK;
			}
			if (m_character.CurrentHP >= m_character.HP)
			{// 이미 만땅임.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_HP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

			// 부스터가 켜져있으면 부스터를 취소하고 HP UP 시작한다.
			if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_BOOSTER3_MASK) == TRUE)
			{
				// 부스터를 끈다.
				SetBodyConditionBit(m_character.BodyCondition, BODYCON_BOOSTER1_MASK);
				SendCharacterInfo(T_FC_CHARACTER_CHANGE_BODYCONDITION);
			}

			// 남은 시간은 m_nRemainedTimeOfGradualHPUP 을 사용함
			m_TimerManager.m_nRemainedTimeOfGradualHPUP	= pItemEnergy->ItemInfo->ReAttacktime;
			m_TimerManager.m_TEIDGradualHPUP			= m_TimerManager.StartTimerField(TE_TYPE_GRADUAL_HP_UP, TIMER_GRADUAL_UP_INTERVAL, (UINT)pItemEnergy->ItemInfo);
		}
		break;
	case DES_GRADUAL_DP_UP:
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_DP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_DEBUFF_SKILL_APPLYING_NOT_DP_RECOVERY);
				return RES_BREAK;
			}
			
			if(FALSE == IsEnableRepairDP())
			{// 2006-12-18 by cmkwon, DP 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

			if (0 < m_TimerManager.m_nRemainedTimeOfGradualDPUP
				|| m_TimerManager.m_bImmediateDPTimerRunning)
			{// 사용중이면 쓸 수 없다.
// 2005-04-07 by cmkwon, 필요없음
//				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_DP_UP_ITEM);
				return RES_BREAK;
			}

			if (m_character.CurrentDP >= m_character.DP)
			{// 이미 만땅임.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_DP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

			// 남은 시간은 m_nRemainedTimeOfGradualDPUP 을 사용함
			m_TimerManager.m_nRemainedTimeOfGradualDPUP		= pItemEnergy->ItemInfo->ReAttacktime;
			m_TimerManager.StartTimerField(TE_TYPE_GRADUAL_DP_UP, TIMER_GRADUAL_UP_INTERVAL, (UINT)pItemEnergy->ItemInfo);
		}
		break;
	case DES_GRADUAL_EP_UP:
		{
			if (0 < m_TimerManager.m_nRemainedTimeOfGradualEPUP
				|| m_TimerManager.m_bImmediateEPTimerRunning)
			{// 사용중이면 쓸 수 없다.
// 2005-04-07 by cmkwon, 필요없음
//				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_EP_UP_ITEM);
				return RES_BREAK;
			}
			if (m_character.CurrentEP >= m_character.EP)
			{// 이미 만땅임.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_EP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

			// 남은 시간은 m_nRemainedTimeOfGradualEPUP 을 사용함
			m_TimerManager.m_nRemainedTimeOfGradualEPUP		= pItemEnergy->ItemInfo->ReAttacktime;
			m_TimerManager.StartTimerField(TE_TYPE_GRADUAL_EP_UP, TIMER_GRADUAL_UP_INTERVAL, (UINT)pItemEnergy->ItemInfo);
		}
		break;
// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - 기존 소스 주석 처리
// 	case DES_IMMEDIATE_HP_UP:
// 		{
// 			if (NULL != m_TimerManager.m_TEIDGradualHPUP
// 				|| 0 < m_TimerManager.m_nRemainedTimeOfGradualHPUP
// 				|| m_TimerManager.m_bImmediateHPTimerRunning)
// 			{// 사용중이면 쓸 수 없다.
// // 2005-04-07 by cmkwon, 필요없음
// //				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_HP_UP_ITEM);
// 				return RES_BREAK;
// 			}
// 
// 			if(0.0f >= m_character.CurrentHP)
// 			{// 2005-12-30 by cmkwon
// 				return RES_BREAK;
// 			}
// 			
// 			if (m_character.CurrentHP >= m_character.HP)
// 			{// 이미 만땅임.
// 
// 				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_HP, 0, 0, NULL, FALSE, FALSE);
// 				return RES_BREAK;
// 			}
// 
// 			this->ChangeCurrentHP(pItemInfo->ParameterValue1);
// 			m_TimerManager.m_bImmediateHPTimerRunning	= TRUE;
// 			m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_HP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
// 		}
// 		break;
// 	case DES_IMMEDIATE_DP_UP:
// 		{
// 			if(FALSE == IsEnableRepairDP())
// 			{// 2006-12-18 by cmkwon, DP 회복 불가
// 				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 0, NULL, FALSE, FALSE);
// 				return RES_BREAK;
// 			}
// 
// 			if (0 < m_TimerManager.m_nRemainedTimeOfGradualDPUP
// 				|| m_TimerManager.m_bImmediateDPTimerRunning)
// 			{// 사용중이면 쓸 수 없다.
// // 2005-04-07 by cmkwon, 필요없음
// //				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_DP_UP_ITEM);
// 				return RES_BREAK;
// 			}
// 			if (m_character.CurrentDP >= m_character.DP)
// 			{// 이미 만땅임.				
// 				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_DP, 0, 0, NULL, FALSE, FALSE);
// 				return RES_BREAK;
// 			}
// 			
// 			this->ChangeCurrentDP(pItemInfo->ParameterValue1);
// 			m_TimerManager.m_bImmediateDPTimerRunning	= TRUE;
// 			m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_DP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
// 		}
// 		break;

	///////////////////////////////////////////////////////////////////////////////
	// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - DestParameter1,DestParameter2에 DES_IMMEDIATE_HP_UP,DES_IMMEDIATE_DP_UP을 이용해서 설정 가능
	//																		 - 둘중에 하나가 쿨타임이 부족하면 아이템 사용이 안된다.
	//																		 - 쉴드마비 상태에서는 CurrentHP만 채워 진다.
	case DES_IMMEDIATE_HP_UP:
		{
			////////////////////////////////////////////////////////////////////////////////
			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
			if(this->m_SkillManager.m_FieldDebuff.CheckApplyingDebuff(DES_SKILL_MON_FREEZE_HP)) {
				// 프리즈 스킬 중엔 HP,DP,SP 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_DEBUFF_SKILL_APPLYING_NOT_HP_RECOVERY);
				return RES_BREAK;
			}
			
			BOOL bRefilledHP	= FALSE;
			BOOL bRefilledDP	= FALSE;
			BOOL bAlreadyFullHP	= FALSE;
			BOOL bAlreadyFullDP	= FALSE;

			// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - HP Refill 체크
			if(0.0f >= m_character.CurrentHP)
			{// 2008-08-27 by cmkwon, 폭파 상태
				return RES_BREAK;
			}
			if (NULL != m_TimerManager.m_TEIDGradualHPUP
				|| 0 < m_TimerManager.m_nRemainedTimeOfGradualHPUP
				|| m_TimerManager.m_bImmediateHPTimerRunning)
			{// 2008-08-27 by cmkwon, HP Refill 쿨타임 체크
 				return RES_BREAK;
			}
			if(m_character.CurrentHP >= m_character.HP)
			{
				bAlreadyFullHP	= TRUE;
			}
			else
			{
				bRefilledHP		= TRUE;
			}

			// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - DP Refill 체크
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			if(DES_IMMEDIATE_DP_UP == pItemInfo->DestParameter2				
			if(DES_IMMEDIATE_DP_UP == pItemInfo->ArrDestParameter[1]				
				&& IsEnableRepairDP())
			{
				if(0 < m_TimerManager.m_nRemainedTimeOfGradualDPUP
					|| m_TimerManager.m_bImmediateDPTimerRunning)
				{// 2008-08-27 by cmkwon, DP Refill 쿨타임 체크
					return RES_BREAK;
				}
				if(m_character.CurrentDP >= m_character.DP)
				{
					bAlreadyFullDP	= TRUE;
				}
				else
				{
					bRefilledDP		= TRUE;
				}
			}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			if( (0 == pItemInfo->DestParameter2 && bAlreadyFullHP)
			if( (0 == pItemInfo->ArrDestParameter[1] && bAlreadyFullHP)
				|| (bAlreadyFullHP && bAlreadyFullDP) )
			{// 2008-08-27 by cmkwon, 만땅 체크
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_HP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

			if(FALSE == bRefilledHP && FALSE == bRefilledDP)
			{// 2008-08-27 by cmkwon, 
				return RES_BREAK;
			}

			if(bRefilledHP)
			{// 2008-08-27 by cmkwon, CurrentHP Refill
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//				this->ChangeCurrentHP(pItemInfo->ParameterValue1);
				this->ChangeCurrentHP(pItemInfo->ArrParameterValue[0]);

				m_TimerManager.m_bImmediateHPTimerRunning	= TRUE;
				m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_HP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
			}
			if(bRefilledDP)
			{// 2008-08-27 by cmkwon, CurrentDP Refill
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//				this->ChangeCurrentDP(pItemInfo->ParameterValue2);
				this->ChangeCurrentDP(pItemInfo->ArrParameterValue[1]);

				m_TimerManager.m_bImmediateDPTimerRunning	= TRUE;
				m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_DP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
			}
		}
		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 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_DEBUFF_SKILL_APPLYING_NOT_DP_RECOVERY);
				return RES_BREAK;
			}
			
			BOOL bRefilledHP	= FALSE;
			BOOL bRefilledDP	= FALSE;
			BOOL bAlreadyFullHP	= FALSE;
			BOOL bAlreadyFullDP	= FALSE;
			
			// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - HP Refill 체크
			if(0.0f >= m_character.CurrentHP)
			{// 2008-08-27 by cmkwon, 폭파 상태
				return RES_BREAK;
			}
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			if (DES_IMMEDIATE_HP_UP == pItemInfo->DestParameter2)
			if (DES_IMMEDIATE_HP_UP == pItemInfo->ArrDestParameter[1])
			{
				if(NULL != m_TimerManager.m_TEIDGradualHPUP
					|| 0 < m_TimerManager.m_nRemainedTimeOfGradualHPUP
					|| m_TimerManager.m_bImmediateHPTimerRunning)
				{// 2008-08-27 by cmkwon, HP Refill 쿨타임 체크
					return RES_BREAK;
				}
				if(m_character.CurrentHP >= m_character.HP)
				{
					bAlreadyFullHP	= TRUE;
				}
				else
				{
					bRefilledHP		= TRUE;
				}
			}			
			
			// 2008-08-27 by cmkwon, CurrentHP,CurrentDP 동시에 채우는 수리키트 구현 - DP Refill 체크
			if(IsEnableRepairDP())
			{
				if(0 < m_TimerManager.m_nRemainedTimeOfGradualDPUP
					|| m_TimerManager.m_bImmediateDPTimerRunning)
				{// 2008-08-27 by cmkwon, DP Refill 쿨타임 체크
					return RES_BREAK;
				}
				if(m_character.CurrentDP >= m_character.DP)
				{
					bAlreadyFullDP	= TRUE;
				}
				else
				{
					bRefilledDP		= TRUE;
				}
			}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			if( (0 == pItemInfo->DestParameter2 && bAlreadyFullDP)
			if( (0 == pItemInfo->ArrDestParameter[1] && bAlreadyFullDP)
				|| (bAlreadyFullHP && bAlreadyFullDP) )
			{// 2008-08-27 by cmkwon, 
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_DP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}
			
			if(FALSE == bRefilledHP && FALSE == bRefilledDP)
			{// 2008-08-27 by cmkwon, 				
				return RES_BREAK;
			}
			
			if(bRefilledDP)
			{// 2008-08-27 by cmkwon, CurrentDP Refill
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//				this->ChangeCurrentDP(pItemInfo->ParameterValue1);
				this->ChangeCurrentDP(pItemInfo->ArrParameterValue[0]);

				m_TimerManager.m_bImmediateDPTimerRunning	= TRUE;
				m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_DP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
			}
			if(bRefilledHP)
			{// 2008-08-27 by cmkwon, CurrentHP Refill
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//				this->ChangeCurrentHP(pItemInfo->ParameterValue2);
				this->ChangeCurrentHP(pItemInfo->ArrParameterValue[1]);

				m_TimerManager.m_bImmediateHPTimerRunning	= TRUE;
				m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_HP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
			}
		}
		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 회복 불가
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_DEBUFF_SKILL_APPLYING_NOT_SP_RECOVERY);
				return RES_BREAK;
			}
			
			if (m_TimerManager.m_bImmediateSPTimerRunning)
			{// 사용중이면 쓸 수 없다.
// 2005-04-07 by cmkwon, 필요없음
//				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_SP_UP_ITEM);
				return RES_BREAK;
			}
			if (m_character.CurrentSP >= m_character.SP)
			{// 이미 만땅임.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_SP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			this->ChangeCurrentSP(pItemInfo->ParameterValue1);
			this->ChangeCurrentSP(pItemInfo->ArrParameterValue[0]);

			m_TimerManager.m_bImmediateSPTimerRunning	= TRUE;
			m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_SP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
		}
		break;
	case DES_IMMEDIATE_EP_UP:
		{
			if (0 < m_TimerManager.m_nRemainedTimeOfGradualEPUP
				|| m_TimerManager.m_bImmediateEPTimerRunning)
			{// 사용중이면 쓸 수 없다.
// 2005-04-07 by cmkwon, 필요없음
//				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_USING_EP_UP_ITEM);
				return RES_BREAK;
			}

			if(0.0f >= m_character.CurrentEP)
			{// 2005-12-30 by cmkwon
				SendCharacterInfo(T_FC_CHARACTER_CHANGE_CURRENTEP);
				return RES_BREAK;
			}

			if (m_character.CurrentEP >= m_character.EP)
			{// 이미 만땅임.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_AREADY_FULL_EP, 0, 0, NULL, FALSE, FALSE);
				return RES_BREAK;
			}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//			this->ChangeCurrentEP(pItemInfo->ParameterValue1);
			this->ChangeCurrentEP(pItemInfo->ArrParameterValue[0]);

			m_TimerManager.m_bImmediateEPTimerRunning	= TRUE;
			m_TimerManager.StartTimerField(TE_TYPE_IMMEDIATE_EP_UP, pItemInfo->ReAttacktime, (UINT)pItemInfo);
		}
		break;
	case DES_WARP:
		{
			CFieldMapProject *pFMapPro = this->GetCityFieldMapProjectPtr();
			if(NULL == pFMapPro)
			{
				return RES_BREAK;
			}
			
			//////////////////////////////////////////////////////////////////////////
			// 2008-03-10 by dhjin, 아레나 통합 - 도시귀환 포탈 사용 시 아레나 서버와 연결 종료
			if(g_pFieldGlobal->IsArenaServer())
			{
				this->SendAddMessageType(T_FC_ARENA_USE_CITYWARPITEM);
				return RES_BREAK;
			}		

			Err_t errCode = this->IsEnableWarp(pFMapPro->m_nMapInfluenceType, FALSE);
			if(ERR_NO_ERROR != errCode)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, errCode);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-07-11 by cmkwon, 도시맵의 유저는 도시귀환 포탈 사용 불가
			if(this->GetCurrentFieldMapChannel() == this->GetCityFieldMapChannelPtr())
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
				return RES_BREAK;
			}
			
			// 2007-07-11 by cmkwon, BigBoom이 PrepareUse 상태 여부 - 도시귀환포탈 사용시 체크
			if(m_SkillManager.GetPrepareUseBigBoom())
			{
				return RES_BREAK;
			}

			//////////////////////////////////////////////////////////////////////////
			// 2007-05-02 by dhjin, 아레나 맵에서
			if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
			{
				bWarpArenaMap2CityMap		= TRUE;
			}
			
			// 도시로 워프 시킴	
			WarpToCityMap();	// 2005-07-27 by cmkwon, 도시맵으로 이동			
		}
		break;
	case DES_CASH_STAT_ALL_INITIALIZE:
//	case DES_CASH_STAT_HALF_INITIALIZE:
	case DES_CASH_STAT_PART_INITIALIZE:
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//if(DES_CASH_STAT_ALL_INITIALIZE == pItemInfo->DestParameter1)
			if(DES_CASH_STAT_ALL_INITIALIZE == pItemInfo->ArrDestParameter[0])
			{
				pMsgUseEnergy->nParam1		= STAT_ALL_PART;
			}
			else
			{
				if(STAT_ALL_PART == pMsgUseEnergy->nParam1)
				{
					// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
					//SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_INVALID_STAT_VALUE_OR_KIND, pItemInfo->ItemNum, pItemInfo->DestParameter1);
					SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_INVALID_STAT_VALUE_OR_KIND, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
					return RES_BREAK;
				}
			}

			if(0 != pItemInfo->ReqMinLevel
				&& pItemInfo->ReqMinLevel > m_character.Level)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
				return RES_BREAK;
			}

			if(0 != pItemInfo->ReqMaxLevel
				&& pItemInfo->ReqMaxLevel < m_character.Level)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
				return RES_BREAK;
			}

			Err_t nErrCode = this->ResetStat(pMsgUseEnergy->nParam1);
			if(ERR_NO_ERROR != nErrCode)
			{
				// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
				//SendErrorMessage(T_FC_ITEM_USE_ENERGY, nErrCode, pItemInfo->ItemNum, pItemInfo->DestParameter1);
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, nErrCode, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
				return RES_BREAK;
			}
		}
		break;
	case DES_CASH_CRACKER_CARD:
		{// 처리 필요없음 - 이펙트는 클라이언트에서 처리함
		}
		break;
	case DES_WARP_OUTPOST:
		{// 2007-09-05 by dhjin, 전진기지 전용 도시 귀환 포탈
			if(FALSE == IS_VALID_UNIQUE_NUMBER(this->m_character.GuildUniqueNumber))
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_NOT_HAVE_GUILD);
				return RES_BREAK;
			}

			int tmOutPostCityMapIndex = ms_pFieldIOCP->m_OutPostManager.GetOutPostCityMapIndexByGuildUID(this->m_character.GuildUniqueNumber);
			// 2007-09-05 by dhjin, 전진기지 소유 여단원인지 체크
			if(NULL == tmOutPostCityMapIndex)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_CANNOT_SEARCH_OUTPOST);
				return RES_BREAK;
			}

			int tmOutPostMapIndex = ms_pFieldIOCP->m_OutPostManager.GetOutPostMapIndexByGuildUID(this->m_character.GuildUniqueNumber);
			if(ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(tmOutPostMapIndex))
			{// 2007-09-15 by dhjin, 전진기지 전쟁 중이면 사용 불가하다.
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-27 by cmkwon, 워프 가능한지 체크 추가함
			CFieldMapProject *pFMapPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(tmOutPostCityMapIndex);
			if(NULL == pFMapPro)
			{
				return RES_BREAK;
			}
			Err_t errCode = this->IsEnableWarp(pFMapPro->m_nMapInfluenceType, FALSE);
			if(ERR_NO_ERROR != errCode)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, errCode);
				return RES_BREAK;
			}
			// 2007-09-27 by cmkwon, 같은맵인지 체크
			if(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex == tmOutPostCityMapIndex)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
				return RES_BREAK;
			}
			
			// 2007-09-05 by dhjin, BigBoom이 PrepareUse 상태 여부 - 전진기지 도시귀환포탈 사용시 체크
			if(m_SkillManager.GetPrepareUseBigBoom())
			{
				return RES_BREAK;
			}

			//////////////////////////////////////////////////////////////////////////
			// 2007-09-05 by dhjin, 아레나 맵에서
			if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
			{
				bWarpArenaMap2CityMap		= TRUE;
			}
			
			// 전진기지 도시로 워프 시킴
			CFieldMapChannel *pFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(tmOutPostCityMapIndex, 0));
			if(NULL == pFMChann)
			{
				return RES_BREAK;
			}
			WarpToMap(pFMChann->GetMapChannelIndex(), &pFMChann->GetCityWarpTargetPositionW(), TRUE);
		}
		break;		// 2007-09-27 by cmkwon, 수정함
	default:
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
			SendErrorMessage(T_FC_ITEM_USE_ENERGY, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
			return RES_BREAK;
		}
	}// end_switch(pItemInfo->DestParameter1)
	
	// send log
	ITEM_GENERAL tmpItemOnlyForLog = *pItemEnergy;	// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
	tmpItemOnlyForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseENERGY(this, &tmpItemOnlyForLog);

	// Item Count 수정하기
	m_ItemManager.UpdateItemCountByPointer(pItemEnergy, -1, IUT_USE_ENERGY);

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_ENERGY_OK, T_FC_ITEM_USE_ENERGY_OK, pSEnergyOK, SendBuf);
	pSEnergyOK->ClientIndex		= m_character.ClientIndex;
	pSEnergyOK->ItemNum			= pItemInfo->ItemNum;
	this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_ENERGY_OK));

	///////////////////////////////////////////////////////////////////////////////
	// 2007-05-14 by cmkwon
	if(bWarpArenaMap2CityMap
		&& 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);
		}
	}
	CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_ITEM,
									MSG_FC_ITEM_USE_ITEM, pMsgUseItem);

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-08-07 by cmkwon, 개인 상점 개설중에는 아이템 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_USING_BAZAAR);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_ITEM
	if(this->CheckTradingItem(pMsgUseItem->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_ITEM_TRADING, pMsgUseItem->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pMsgUseItem->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseItem->ItemUniqueNumber);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - ITEMKIND_CARD,ITEMKIND_BULLET 사용시 아이템 요구사항 체크 추가(UnitKind 체크를 위해 추가)
	Err_t errCode = CheckItemRequirements(pItemG->ItemInfo);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, errCode, pItemG->ItemInfo->ItemNum, 10000);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_CANNOT_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}
	
	if(COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_ONLY_USE_INFINITY)
		&& !IS_MAP_INFLUENCE_INFINITY(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW())) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵에서만 사용 가능
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_INFINITY_ONLY_USE_ITEM);
		return RES_BREAK;
	}

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

	ITEM *pItemInfo = pItemG->ItemInfo;
	ITEM_GENERAL tmpItemForLog = *pItemG;	// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_ITEM
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pItemInfo, pItemInfo->ItemNum);	// 2010-01-18 by cmkwon, 자신은 아래에서 체크
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_ALREADY_USE_ITEMPARAM, pItemInfo->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}
	
	switch(pItemInfo->Kind)
	{
	case ITEMKIND_CARD:
		{
// 2010-02-10 by cmkwon, 킬마크 사용시 렙제 체크 버그 수정 - 아래에서 체크
// 			///////////////////////////////////////////////////////////////////////////////
// 			// 2010-01-21 by cmkwon, 카드류(ITEMKIND_CARD) 사용시 아이템 요구사항 체크 추가 - 
// 			Err_t err = CheckGeneralItemRequirements(pItemG);
// 			if (err != ERR_NO_ERROR)
// 			{
// 				SendErrorMessage(T_FC_ITEM_USE_ITEM, err);
// 				return RES_BREAK;
// 			}

			///////////////////////////////////////////////////////////////////////////////
			// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_ITEM_USE_ITEM, 필드창고 아이템 사용 처리
			if(pItemInfo->IsExistDesParam(DES_FIELD_STORE))
			{
				if(FALSE == this->IsValidCharacter())
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_INVALID_CHARACTER, pItemInfo->ItemNum);
					return RES_BREAK;
				}

				if(m_ItemManager.GetUsingFieldStore() || m_ItemManager.GetUsingStore() )				// 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
				{
					char szErrTxt[1024];
					sprintf(szErrTxt, "Already using the Field Store!! UsingFlag(%d) UseableFlag(%d)", m_ItemManager.GetUsingFieldStore(), m_ItemManager.IsUseableFieldStore());
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_ITEM, m_ItemManager.GetUsingFieldStore(), m_ItemManager.IsUseableFieldStore(), szErrTxt);
					return RES_BREAK;
				}

				if(NULL != m_pCurrentBuildingNPC)
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_ALREADY_USING_BUILDING, m_pCurrentBuildingNPC->BuildingKind, m_pCurrentBuildingNPC->BuildingIndex);
					return RES_BREAK;
				}

				BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(FIELD_STORE_SHOP_BUILDING_INDEX);
				if(NULL == pBuildingNPC)
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM, pItemInfo->ItemNum, FIELD_STORE_SHOP_BUILDING_INDEX);
					return RES_BREAK;
				}

				// 2010-03-05 by cmkwon, 아레나/인피에서 필드창고 막기 - 
				if(g_pFieldGlobal->IsArenaServer())
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_CANNOT_USE_FIELD_STORE, pItemInfo->ItemNum);
					return RES_BREAK;
				}

				///////////////////////////////////////////////////////////////////////////////
				// 2010-03-30 by cmkwon, 필드창고 비행중 이용 버그 수정(E0044710) - 캐릭터모드가 아니거나 정지상태가 아니면 필드창고 이용불가
				if(FALSE == GetCharacter()->CharacterMode
					&& FALSE == COMPARE_BODYCON_BIT(GetCharacter()->BodyCondition, BODYCON_STOP_MASK))
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_CANNOT_USE_FIELD_STORE, pItemInfo->ItemNum);
					return RES_BREAK;
				}

				///////////////////////////////////////////////////////////////////////////////
				// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_ITEM_USE_ITEM, 필드창고 이용을 설정하고 Client에 T_FC_EVENT_ENTER_BUILDING를 전송한다.
				m_ItemManager.SetUsingFieldStore(TRUE);			// 2009-09-23 by cmkwon, T_FC_ITEM_USE_ITEM, 필드창고 캐쉬 아이템 구현 - 필드창고 이용을 설정
				m_ItemManager.SetUsingStore(TRUE);				// 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
				
				INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, SendBuf);
				pMsgEnterBuilding->BuildingNPCInfo				= *pBuildingNPC;
				pMsgEnterBuilding->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
				SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));
				CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
				return RES_BREAK;
			}

			if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_KILL_MARK_ITEM))
			{// 2006-08-14 by dhjin, 킬마크 아이템 사용시 

// 2007-09-03 by cmkwon, 베트남도 킬마크를 경험치로 변경 가능함
//				if(LANGUAGE_TYPE_VIETNAMESE == g_pFieldGlobal->GetLanguageType())
//				{// 2006-08-14 by cmkwon, 베트남은 아직 사용 불가
//					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM); 
//					return RES_BREAK; 					
//				}

				if(0 != pItemInfo->ReqMinLevel
					&& pItemInfo->ReqMinLevel > m_character.Level)
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, m_character.Level, pItemInfo->ReqMinLevel);
					return RES_BREAK;
				}

				// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
				//if (DES_KILLMARK_EXP != pItemInfo->DestParameter1)
				if (DES_KILLMARK_EXP != pItemInfo->ArrDestParameter[0])
				{
					// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
					//SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
					return RES_BREAK;		// 2007-08-14 by cmkwon, 버그 수정
				}
				
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//				int m_nPlusExp		= pItemInfo->ParameterValue1;
				int m_nPlusExp		= pItemInfo->ArrParameterValue[0];

				// start 2012-01-02 by hskim, EP4 [킬마크] - 워포인트 추가
				if( pItemInfo->IsExistDesParam(DES_WAR_POINT_UP) )
				{
					INT AddWarPoint = pItemInfo->GetParameterValue(DES_WAR_POINT_UP);

					if( 0 != AddWarPoint )
					{
						this->SetWarPoint(AddWarPoint);
					}
				}
				// end 2012-01-02 by hskim, EP4 [킬마크] - 워포인트 추가

// 2006-09-28 by cmkwon, 보류됨
//				///////////////////////////////////////////////////////////////////////////////
//				// 2006-09-27 by cmkwon, 상대 세력의 세금의 비율만큼 증가
//				if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN))
//				{
//					m_nPlusExp		+= (m_nPlusExp * ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(INFLUENCE_TYPE_ANI))/100.0f;
//				}
//				else if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_ANI))
//				{
//					m_nPlusExp		+= (m_nPlusExp * ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(INFLUENCE_TYPE_VCN))/100.0f;
//				}

				// 2013-03-22 by jhseol, 만렙이 아닌 케릭터만 경험치를 추가해 준다.
				if(CHARACTER_MAX_LEVEL > m_character.Level)
				{
					ChangeExperience(m_nPlusExp, FALSE, FALSE, FALSE);		// 2011-09-02 by hskim, 파트너 시스템 2차
					CAtumLogSender::SendLogMessageEXP(this,m_nPlusExp,m_character.Experience);
				}
				// end 2013-03-22 by jhseol, 만렙이 아닌 케릭터만 경험치를 추가해 준다.
				
				tmpItemForLog.CurrentCount--;
				CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);	
				m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);	// Item Count 수정하기
				
				igLock.auto_unlock_cancel();
				CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
				return RES_RETURN_TRUE;
			}

			// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 외변 킷 사용
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 외변 킷 사용
			if ( pItemInfo->IsExistDesParam(DES_COLLECTION_ARMOR_INDEX) && 0 < pItemInfo->SkillLevel )
			{
				if ( TRUE == g_pFieldGlobal->IsArenaServer() )
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM_IN_ARENA);
					return RES_BREAK;
				}

				ITEM_GENERAL *pArmorItem = GetAttachItemGeneralByPosition(POS_CENTER);
				if( NULL != pArmorItem)
				{
					if ( pArmorItem->ShapeItemNum == pItemInfo->LinkItem && SHAPE_STAT_INIT_LEVEL < pArmorItem->FixedTermShape.nStatLevel )
					{
						// 사용 하려는 외변킷과 동일한 컬렉션이 적용된 아머를 장착중이다.
						SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0006);
						SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
						return RES_BREAK;
					}
				}

				ITEM *pShapeItem = ms_pFieldIOCP->GetItemInfo(pItemInfo->LinkItem);
				if ( NULL == pShapeItem )
				{
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
					return RES_BREAK;
				}

				UINT nRemainSeconds = (UINT)(pItemInfo->GetParameterValue(DES_FIXED_TERM_SHAPE_TIME)*60);
				COLLECTION_INFO *tmCollectionInfo = NULL;
				tmCollectionInfo = m_ArmorCollection.GetCollectionInfoPtr(pItemInfo->LinkItem);
				if( NULL != tmCollectionInfo )
				{
					if ( SHAPE_STAT_MAX_LEVEL <= tmCollectionInfo->EnchantLevel )
					{
#ifdef  SC_PREMIUM_COLLECTION_ARMOR_YMJOO_BCKIM		// 2014-07-17 by bckim, 프리미엄 아머 컬렉션
						ITEM *pPremium = ms_pFieldIOCP->GetItemInfo(tmCollectionInfo->ShapeItemNum);
						if( pPremium->IsExistDesParam(DES_PREMIUM_COLLECTION_ARMOR_INDEX) )
						{
							INT tempGearKit = m_ItemManager.ReturnItemNumWithShapeNum(pItemInfo->ReqUnitKind);
							ITEM *pGearKitItem = ms_pFieldIOCP->GetItemInfo(tempGearKit);							
							if ( NULL == pGearKitItem )
						{
							SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
							return RES_BREAK;
						}
						else
						{
								m_ItemManager.InsertItemBaseByItemNum(tempGearKit, 1, IUT_RANDOMBOX);
								SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0003, pShapeItem->ItemName, pGearKitItem->ItemName);
							}
						}
						else
						{
							ITEM *pReturnItem = ms_pFieldIOCP->GetItemInfo(COLLECTION_XAM_ENCHANT_RETURN_ITEMNUM);
							if ( NULL == pReturnItem )
							{
								SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
								return RES_BREAK;
							}
							else
							{
							m_ItemManager.InsertItemBaseByItemNum(COLLECTION_XAM_ENCHANT_RETURN_ITEMNUM, 1, IUT_RANDOMBOX);
							SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0003, pShapeItem->ItemName, pReturnItem->ItemName);
						}
						}
						// End. 2014-07-17 by bckim, 프리미엄 아머 컬렉션
#else
						ITEM *pReturnItem = ms_pFieldIOCP->GetItemInfo(COLLECTION_XAM_ENCHANT_RETURN_ITEMNUM);
						if ( NULL == pReturnItem )
						{
							SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_CANNOT_USE_ITEM);
							return RES_BREAK;
						}
						else
						{
							m_ItemManager.InsertItemBaseByItemNum(COLLECTION_XAM_ENCHANT_RETURN_ITEMNUM, 1, IUT_RANDOMBOX);
							SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0003, pShapeItem->ItemName, pReturnItem->ItemName);
						}
#endif
					}
					else
					{
						m_ArmorCollection.CollectionEnchant(tmCollectionInfo, pItemInfo->SkillLevel, nRemainSeconds);// 컬렉션 업데이트
						SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0002, pShapeItem->ItemName, tmCollectionInfo->EnchantLevel);

						// 해당 외형이 적용 중인 아머들의 정보 갱신
						mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));
						mtmapUID2ItemGeneral::iterator itrItem = m_ItemManager.m_mapItemGeneral.begin();
						for(; m_ItemManager.m_mapItemGeneral.end() != itrItem; itrItem++)
						{
							ITEM_GENERAL *pShapeUpdateItemG = itrItem->second;
							if ( ITEM_IN_CHARACTER == pShapeUpdateItemG->ItemStorage				// 인벤토리에 있고
								&& ITEMKIND_DEFENSE == pShapeUpdateItemG->Kind						// 아머류 중에
								&& tmCollectionInfo->ShapeNum == pShapeUpdateItemG->ShapeItemNum	// 사용한 컬렉션 과 동일한 외형이며
								&& SHAPE_STAT_INIT_LEVEL < pShapeUpdateItemG->FixedTermShape.nStatLevel )	// 외형 lv이 있는 녀석들만(=아머 컬렉션에 등록된 외형이 적용중임을 의미함)
							{
								// 기존에 진행중인 타이머가 있으면 지운다.
								if( 0 != pShapeUpdateItemG->FixedTermShape.TimerUID )
								{
									m_TimerManager.StopTimerField(pShapeUpdateItemG->FixedTermShape.TimerUID);
									
									CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pShapeUpdateItemG, pShapeUpdateItemG->ShapeItemNum, pShapeUpdateItemG->FixedTermShape);
								}

								// 새로운 컬렉션 정보 적용
								pShapeUpdateItemG->FixedTermShape.bActive			= TRUE;
								pShapeUpdateItemG->FixedTermShape.StartDate.SetCurrentDateTime();
								pShapeUpdateItemG->FixedTermShape.EndDate			= tmCollectionInfo->EndTime;
								pShapeUpdateItemG->FixedTermShape.TimerUID			= 0;
								pShapeUpdateItemG->FixedTermShape.nStatLevel		= tmCollectionInfo->EnchantLevel;
								pShapeUpdateItemG->FixedTermShape.nStatShapeItemNum	= tmCollectionInfo->ShapeItemNum;
								// 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경
#ifdef S_MONTHL_ARMOR_EVENT_JHSEOL_BCKIM
								pShapeUpdateItemG->nMonthlyOptionItemNum			= tmCollectionInfo->nOptionItemNum;
								pShapeUpdateItemG->atMonthlyEventEndDate			= tmCollectionInfo->DurationTime;
#endif
								// end 2013-09-06 by jhseol, 이달의 아머 이벤트 적용 기간 변경

								// 타이머 설정 전에 영구제 인지 확인
								if ( SHAPE_STAT_FIXED_TIME_LIMITE_LEVEL <= tmCollectionInfo->EnchantLevel )
								{
									pShapeUpdateItemG->FixedTermShape.bActive			= FALSE;
								}
								ATUM_DATE_TIME atCurrentTime(TRUE);
								if( tmCollectionInfo->EndTime.GetTimeDiffTimeInSeconds(atCurrentTime) < MANAGE_MAX_TIME_FIXED_TERM_MINUTELY*60 && TRUE == pShapeUpdateItemG->FixedTermShape.bActive )
								{
									pShapeUpdateItemG->FixedTermShape.TimerUID = m_TimerManager.StartTimerField(TE_TYPE_FIXED_TERM_SHAPE, tmCollectionInfo->EndTime.GetTimeDiffTimeInSeconds(atCurrentTime) * TIMER_DECREASE_SP_INTERVAL, 0, 0);
									CAtumLogSender::SendLogMessageFixedTermShapeStart(this, pShapeUpdateItemG, tmCollectionInfo->ShapeItemNum);
								}

								// 새로 적용된 ShapeStatLevel 저장
								QPARAM_SHAPE_STATLEVEL	*pQParamSS = new QPARAM_SHAPE_STATLEVEL;
								pQParamSS->ItemKind				= pShapeUpdateItemG->ItemInfo->Kind;
								pQParamSS->ItemUID				= pShapeUpdateItemG->UniqueNumber;
								pQParamSS->nStatLevel			= pShapeUpdateItemG->FixedTermShape.nStatLevel;
								pQParamSS->nStatShapeItemNum	= pShapeUpdateItemG->FixedTermShape.nStatShapeItemNum;
								ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertShapeStatLevel, this, m_character.AccountUniqueNumber, pQParamSS);
								
								// 변경된 정보를 저장하고 클라에게 보내준다
								QPARAM_UPDATE_SHAPEITEMNUM *pQParam = new QPARAM_UPDATE_SHAPEITEMNUM;
								pQParam->ItemUID							= pShapeUpdateItemG->UniqueNumber;
								pQParam->nShapeItemNum						= pShapeUpdateItemG->ShapeItemNum;
								pQParam->FixedTermShape.bActive				= pShapeUpdateItemG->FixedTermShape.bActive;
								pQParam->FixedTermShape.StartDate			= pShapeUpdateItemG->FixedTermShape.StartDate;
								pQParam->FixedTermShape.EndDate				= pShapeUpdateItemG->FixedTermShape.EndDate;
								pQParam->FixedTermShape.TimerUID			= pShapeUpdateItemG->FixedTermShape.TimerUID;
								pQParam->FixedTermShape.nStatLevel			= pShapeUpdateItemG->FixedTermShape.nStatLevel;
								pQParam->FixedTermShape.nStatShapeItemNum	= pShapeUpdateItemG->FixedTermShape.nStatShapeItemNum;
								ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateShapeItemNum, this, m_character.AccountUniqueNumber, pQParam);
							}
						}
					}
				}	// if( NULL != tmCollectionInfo )
				else
				{
					// 컬렉션 등록
					COLLECTION_INFO addCollectionInfo;
					addCollectionInfo.CollectionType = 1;
					addCollectionInfo.AccountUID = m_character.AccountUniqueNumber;
					addCollectionInfo.CharacterUID = 0;		// 지금은 계정 공유라 0으로 셋팅하지만 추후에 케릭터 귀속용 외형이 나오면 코드를 추가해서 캐릭터 UID를 셋팅하도록 하자.
					addCollectionInfo.ShapeNum = pItemInfo->LinkItem;
					addCollectionInfo.ShapeItemNum = pItemInfo->ItemNum;
					addCollectionInfo.EnchantLevel = pItemInfo->SkillLevel;
					addCollectionInfo.RemainSeconds = nRemainSeconds;
					addCollectionInfo.EndTime.Reset();
					m_ArmorCollection.CollectionAdd(&addCollectionInfo,TRUE);	// 디비 업데이트 
//					SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0001, pShapeItem->ItemName);
					INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_ITEM_OK, T_FC_ITEM_USE_ITEM_OK, pSendOKMsg, SendOKBuf);
					pSendOKMsg->ClientIndex = this->GetClientArrayIndex();
					pSendOKMsg->ItemNum = pItemInfo->ItemNum;
					SendAddData(SendOKBuf, MSG_SIZE(MSG_FC_ITEM_USE_ITEM_OK));
				}

				tmpItemForLog.CurrentCount--;
				CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);	
				m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);	// Item Count 수정하기
				CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
				return RES_RETURN_TRUE;
			}	// if ( pItemInfo->IsExistDesParam(DES_COLLECTION_ARMOR_INDEX) && 0 < pItemInfo->SkillLevel )
#endif
			// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 외변 킷 사용

		}
		break;
	case ITEMKIND_BULLET:
		break;
	default:
		{
			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED
				, pItemInfo->ItemNum, pItemInfo->Kind);
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 총알류 아이템(ITEMKIND_BULLET)
	if (pItemInfo->Kind == ITEMKIND_BULLET)
	{// 총알 채우기

		///////////////////////////////////////////////////////////////////////////////
		// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 - Caliber가 255인 아이템 따로 처리
		if(RECHARGE_BULLET_ALL_CALIBER == pItemInfo->Caliber)
		{
			ITEM_GENERAL *pPriItemG = this->GetAttachItemGeneralByPosition(POS_PROWOUT);
			ITEM_GENERAL *pSecItemG = this->GetAttachItemGeneralByPosition(POS_WINGOUT);
			if(NULL == pPriItemG && NULL == pSecItemG)
			{// 2007-08-07 by cmkwon, 장착한 무기가 없다
				SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_NO_SUCH_WEAPON_ITEM, pItemInfo->ItemNum, pItemInfo->Kind);
				return RES_BREAK;
			}

			BOOL bRechargeable	= FALSE;
			if(pPriItemG
				&& pPriItemG->CurrentCount < pPriItemG->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout()))	// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다	// 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
				// 2014-12-08 by bckim, 고급고급무기 이펙트 장탄수 확장 기능추가
			// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다
			//	&& pPriItemG->CurrentCount < pPriItemG->ItemInfo->Charging)
			{
				bRechargeable	= TRUE;
				RechargeBullet(pPriItemG, FALSE, BULLET_RECHARGE_TYPE_BULLET_ITEM);
			}
			if(pSecItemG
				&& pSecItemG->CurrentCount < pSecItemG->GetMaxBulletCount(m_ItemManager.IsExistPremiumCard(),IsEffectInWingout()))	// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다	// 2014-12-08 by bckim, jwLee 고급무기 이펙트 장탄수 확장 기능추가
			// 2007-10-15 by cmkwon, 멤버쉬 유저는 탄창이 두배로 커진다
			//	&& pSecItemG->CurrentCount < pSecItemG->ItemInfo->Charging)
			{
				bRechargeable	= TRUE;
				RechargeBullet(pSecItemG, FALSE, BULLET_RECHARGE_TYPE_BULLET_ITEM);
			}
			
			if(FALSE == bRechargeable)
			{
				SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_ALREADY_FULL_BULLET, pItemInfo->ItemNum, pItemInfo->Kind);
				return RES_BREAK;
			}

			tmpItemForLog.CurrentCount--;
			CAtumLogSender::SendLogMessageITEMUseENERGY(this, &tmpItemForLog);	
			m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);	// Item Count 수정하기
			igLock.auto_unlock_cancel();
			CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
			return RES_RETURN_TRUE;
		}

		if (m_ItemProwOut.ItemNum != NULL && m_ItemProwOut.Caliber == pItemInfo->Caliber)
		{
			// 1형 무기 총알인 경우
			RechargeBullet((ITEM_GENERAL*)m_ItemProwOut.ItemNum, TRUE, BULLET_RECHARGE_TYPE_BULLET_ITEM);	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		}
		else if (m_ItemWingOut.ItemNum != NULL && m_ItemWingOut.Caliber == pItemInfo->Caliber)
		{
			// 2형 무기 총알인 경우
			RechargeBullet((ITEM_GENERAL*)m_ItemWingOut.ItemNum, TRUE, BULLET_RECHARGE_TYPE_BULLET_ITEM);	// 2007-08-07 by cmkwon, 1형/2형 무기 총알 충전 아이템 구현 -
		}
		else
		{
			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum);
			return RES_BREAK;
		}
		CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
		return RES_RETURN_TRUE;
	}

	if(0 != pItemInfo->ReqMinLevel
		&& pItemInfo->ReqMinLevel > m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}
	if(0 != pItemInfo->ReqMaxLevel
		&& pItemInfo->ReqMaxLevel < m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}
	
//	ITEM_GENERAL tmpItemForLog = *pItemG;	// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
	
	///////////////////////////////////////////////////////////////////////////////
	// 카드류 아이템(ITEMKIND_CARD)
	if(FALSE == COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_TIME_LIMITE|ITEM_ATTR_DELETED_TIME_LIMITE_AFTER_USED))		// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 
	{// 1회성 카드 아이템 - 
		
		Err_t errCode = ApplyCardItem(pItemG->ItemInfo, TRUE, pMsgUseItem->str256ChatMsg);			// 사용된 아이템 기능 적용 하기
		if(ERR_NO_ERROR != errCode)
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//SendErrorMessage(T_FC_ITEM_USE_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->DestParameter1);
			SendErrorMessage(T_FC_ITEM_USE_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
			return RES_BREAK;
		}	
		
	}
	else
	{// 시간 제한형 카드 아이템 - 스텔스 카드, 에너지/쉴드 키트

		if(ITEM_NOT_USING != pItemG->UsingTimeStamp)
		{
			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_ITEM, pItemInfo->ItemNum, pItemG->UniqueNumber);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-01-31 by cmkwon, 시간제한 아이템 DB 에 추가 중 체크 - DB 에 추가 상태인것 체크
		if(m_ItemManager.IsExistInsertingItemNumList2DB(pItemG->ItemNum))
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1, "100");
			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0], "100");
			return RES_BREAK;
		}

// 2007-06-15 by cmkwon, 사용 시간 제한 아이템 시스템 수정 - ReAttackTime 체크 추가, 아래와 같이 수정
//		if(m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(pItemInfo->DestParameter1))
//		{
//			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
//			return RES_BREAK;
//		}

		if(0 >= pItemInfo->ReAttacktime)
		{// 2007-06-15 by cmkwon, ReAttacktime이 0이면 동시사용 불가능하다
			if(m_ItemManager.IsExistAlreadyUsingItemByItemNum(pItemInfo->ItemNum))
			{
				// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
				//SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1, "101");
				SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0], "101");
				return RES_BREAK;
			}
		}
		else
		{
			ITEM_GENERAL *pUsingItemG = m_ItemManager.FindUsingItemByItemNumNoLock(pItemInfo->ItemNum);
			if(pUsingItemG)				
			{
				if(pUsingItemG->UsingStartTime.GetTimeDiffToCurrentTimeInSeconds()+pUsingItemG->UsingTimeStamp < (pItemInfo->ReAttacktime/1000))
				{
					// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
					//SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1, "102");
					SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0], "102");
					return RES_BREAK;
				}

				m_ItemManager.DeleteUsingTimeLimitedItemList(pItemInfo->ItemNum);
			}
		}
//////////////////////////////////////////////////////////////////////////
// 2009-01-06 by dhjin, 미션마스터 - 아이템 번호가 다르면 중복 적용 가능하게 수정
//		// 2007-06-15 by cmkwon, 사용 시간 제한 아이템 시스템 수정 - 위에서는 IsExistAlreadyUsingItemByItemNum()을 체크하고 아래는 기획적이 오류를 체크한다
//		if(m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(pItemInfo->DestParameter1))
//		{
//			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1, "103");
//			return RES_BREAK;
//		}

// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - 아래 체크 사항도 같이 같이 체크
// 		// 2009-02-25 by cmkwon, 사용 후 시간제한 아이템의 DesParam 체크 다시 추가 - 아래와 같이 기획 요청으로 다시 체크 추가 함. 기간제 아이템(7일,30일,90일)이 추가된 서비스에서 적용되어야 하는 사항임
// 		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 		//if(m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(pItemInfo->DestParameter1))
// 		if(m_ItemManager.IsExistAlreadyUsingItemByDestParameter1(pItemInfo->ArrDestParameter[0]))
// 		{
// 			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 			//SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->DestParameter1, "103");
// 			SendErrorMessage(T_FC_ITEM_USE_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0], "103");
// 			return RES_BREAK;
// 		}


		Err_t errCode = ApplyCardItem(pItemG->ItemInfo, TRUE);			// 사용된 아이템 기능 적용 하기
		if(ERR_NO_ERROR != errCode)
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//SendErrorMessage(T_FC_ITEM_USE_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->DestParameter1);
			SendErrorMessage(T_FC_ITEM_USE_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
			return RES_BREAK;
		}

// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 로 처리
// 		ITEM_GENERAL *pUsingItemG		= (ITEM_GENERAL*)m_ItemManager.MakeNewItem(pItemInfo->ItemNum, ITEM_IN_CHARACTER, pItemInfo);
// 		pUsingItemG->UsingTimeStamp		= ITEM_NOT_USING + 1;				// ITEM_NOT_USING이 아니므로 사용이 시작된것
// 		pUsingItemG->UsingStartTime.SetCurrentDateTime();	// 사용 시작 시간 설정
// 		if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pUsingItemG, IUT_USE_ITEM))
// 		{
// 			SAFE_DELETE(pUsingItemG);
// 		}
		// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 로 처리
		if(FALSE == this->InsertTimeLimiteItem(pItemInfo, FALSE))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertTimeLimiteItem error !!, CFieldIOCPSocket::Process_FC_ITEM_USE_ITEM User(%s) Item(%s)\r\n"
				, GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemG, string()));
		}

// 2005-05-11 by cmkwon, 카운터블로 처리중		
//		///////////////////////////////////////////////////////////////////////////////
//		// 2. m_mapItemGeneral에서 m_vectUsingGeneralItem로 저장 컨테이너 이동
//		m_ItemManager.PopItemGeneralByUID(pItemG->UniqueNumber);
//		m_ItemManager.Add2UsingTimeLimitedItemList(pItemG);
//		
//		///////////////////////////////////////////////////////////////////////////////
//		// 3. 인벤토리에서 삭제하기 위해 클라이언트로 전송
//		INIT_MSG_WITH_BUFFER(MSG_FC_STORE_DELETE_ITEM, T_FC_STORE_DELETE_ITEM, pSDItem, SendBuf);
//		pSDItem->ItemUniqueNumber = pItemG->UniqueNumber;
//		pSDItem->ItemDeletionType = IUT_USE_ITEM;
//		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_DELETE_ITEM));
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 4. 사용중 아이템으로 추가하기 위해 클라이언트로 전송
//		INIT_MSG(MSG_FC_STORE_INSERT_USINGITEM, T_FC_STORE_INSERT_USINGITEM, pSUsingItem, SendBuf);
//		pSUsingItem->ItemNum				= pItemG->ItemNum;
//		pSUsingItem->ItemInsertionType		= IUT_USE_ITEM;
//		pSUsingItem->nRemainSecond			= pItemG->ItemInfo->Time/1000;			// 초단위로 변환
//		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_INSERT_USINGITEM));
//
//		///////////////////////////////////////////////////////////////////////////////
//		// 5. DB에 사용 시작을 저장한다
//		QPARAM_UPDATE_ITEM_USINGTIMESTAMP *pQParam = new QPARAM_UPDATE_ITEM_USINGTIMESTAMP;
//		pQParam->ItemUniqueNumber	= pItemG->UniqueNumber;
//		pQParam->UsingTimeStamp1	= pItemG->UsingTimeStamp;
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemUsingTimeStamp, this, m_character.AccountUniqueNumber, pQParam);
	}
	
	// 2012-10-09 by jhjnag 해피아워 경험치 보너스 시스템 리뉴얼 - 킬카운트 시스템
	if(pItemG->ItemNum == KILLCOUNT_ITEMNUM)
	{
		SetKillCountEventItem(false);
	}
	// end 2012-10-09 by jhjnag 해피아워 경험치 보너스 시스템 리뉴얼 - 킬카운트 시스템


	tmpItemForLog.CurrentCount--;
	// 2008-01-31 by cmkwon, 아래의 SendLogMessageITEMUseITEM() 함수로 수정함
	//CAtumLogSender::SendLogMessageITEMUseENERGY(this, &tmpItemForLog);	
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);	
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);	// Item Count 수정하기

// 2005-05-11 by cmkwon
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);		// 사용 아이템 로그 추가
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
	igLock.auto_unlock_cancel();

	CheckQuestUseItem(pItemInfo->ItemNum);	// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_ENCHANT(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////
	// 인챈트와 겜블 카드에 사용함
	///////////////////////////////////////////

	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_ENCHANT,
									MSG_FC_ITEM_USE_ENCHANT, pMsgUseEnchant);

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}
	
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 옵션머신 상점에서도 이용 가능
	if (m_pCurrentBuildingNPC == NULL
		|| (m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_LABORATORY && BUILDINGKIND_LUCKY_OPTION_MACHINE != m_pCurrentBuildingNPC->BuildingKind && BUILDINGKIND_MYSTERY_SHOP != m_pCurrentBuildingNPC->BuildingKind))		// 2012-07-09 by hskim, 미스터리 머신 구현
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0042);
		return RES_BREAK;
	}


	// 2013-04-04 by bckim, 인챈트 시퀀스 넘버 받지못하는 버그 
	//////////////////////////////////////////////////////////////////////////
	// 2008-08-18 by dhjin, 1초 텀 시스템 기획안
	if(!this->CheckOneSecondTermSystem())
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_INTERVAL_SYSTEM_SECOND, m_dwMSTermSystem);
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ENCHANT_SEQ_NUM_AFTER ]===== 1초 텀 시스템===== \r\n");
		return RES_BREAK;
	}
	// End. 2013-04-04 by bckim, 인챈트 시퀀스 넘버 받지못하는 버그 

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_ENCHANT
	if(this->CheckTradingItem(pMsgUseEnchant->EnchantItemUniqueNumber)
		|| this->CheckTradingItem(pMsgUseEnchant->TargetItemUniqueNumber)
		|| this->CheckTradingItem(pMsgUseEnchant->AttachItemUniqueNumber)
		|| this->CheckTradingItem(pMsgUseEnchant->IncreaseProbabilityItemUID)
		|| this->CheckTradingItem(pMsgUseEnchant->EnchantItemUniqueNumber2))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

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

	ITEM_GENERAL *pItemEnchant = m_ItemManager.GetItemGeneralByUID(pMsgUseEnchant->EnchantItemUniqueNumber);
	if (pItemEnchant == NULL)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnchant->EnchantItemUniqueNumber, 0, "enchant");
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	INT				nEnchantCost	= 0;
	ITEM_GENERAL *pSuffixItemG = NULL;
	if(IS_VALID_UID64(pMsgUseEnchant->EnchantItemUniqueNumber2))
	{		
		if(pMsgUseEnchant->EnchantItemUniqueNumber == pMsgUseEnchant->EnchantItemUniqueNumber2)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_DB_INVALID_PARAMETER, pMsgUseEnchant->EnchantItemUniqueNumber, pMsgUseEnchant->EnchantItemUniqueNumber2, "enchant");
			return RES_BREAK;
		}

		pSuffixItemG = m_ItemManager.GetItemGeneralByUID(pMsgUseEnchant->EnchantItemUniqueNumber2);
		if(NULL == pSuffixItemG)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnchant->EnchantItemUniqueNumber2, 0, "enchant");
			return RES_BREAK;
		}
		if(ITEMKIND_GAMBLE != pSuffixItemG->Kind
			|| ITEMKIND_ENCHANT == pItemEnchant->Kind)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, pItemEnchant->Kind, pSuffixItemG->Kind, "target");
			return RES_BREAK;
		}
	}

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

	if (pItemEnchant->Kind != ITEMKIND_ENCHANT
		&& pItemEnchant->Kind != ITEMKIND_GAMBLE)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, pMsgUseEnchant->EnchantItemUniqueNumber, pItemEnchant->ItemInfo->Kind);
		return RES_BREAK;
	}

	ITEM_GENERAL *pItemTarget = m_ItemManager.GetItemGeneralByUID(pMsgUseEnchant->TargetItemUniqueNumber);
	if (pItemTarget == NULL)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnchant->TargetItemUniqueNumber, 0, "target");
		return RES_BREAK;
	}

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

// 2010-04-07 by cmkwon, 와디이 레전드 갬블 이벤트 종료 처리 - 아래와 같이 기존과 같이 수정.
// ///////////////////////////////////////////////////////////////////////////////
// // 2010-03-30 by cmkwon, 와이디 레전드 아이템 갬블 이벤트 처리 - 무기 레전드 아이템만 갬블이 가능하게, 인챈트는 불가
// #if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_KOREAN_SERVER_2)
// 	if(COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM|ITEM_ATTR_LEGEND_ITEM))
// 	{
// 		if(pItemEnchant->Kind != ITEMKIND_GAMBLE
// 			|| FALSE == IS_WEAPON(pItemTarget->Kind)
// 			|| COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM))
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_ITEM, COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM), COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_LEGEND_ITEM));
// 			return RES_BREAK;
// 		}
// 	}
// #else
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2005-11-21 by cmkwon, 유니크 아이템 체크
// 	// 2007-08-22 by cmkwon, 레전드 아이템 - 체크 추가
// 	if(COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM|ITEM_ATTR_LEGEND_ITEM))
// 	{
// 		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_ITEM, COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM), COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_LEGEND_ITEM));
// 		return RES_BREAK;
// 	}
// #endif
	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-07 by cmkwon, 와디이 레전드 갬블 이벤트 종료 처리 - 아래와 같이 기존과 같이 수정.
	// 2005-11-21 by cmkwon, 유니크 아이템 체크
	// 2007-08-22 by cmkwon, 레전드 아이템 - 체크 추가
	if(COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM|ITEM_ATTR_LEGEND_ITEM))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_ITEM, COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_UNIQUE_ITEM), COMPARE_BIT_FLAG(pItemTarget->ItemInfo->ItemAttribute, ITEM_ATTR_LEGEND_ITEM));
		return RES_BREAK;
	}


	// 2009-02-17 by cmkwon, 인챈트 할 수 있는 아이템 카인드 수정 - 인챈트 시도시 인챈트 가능한 아이템인지 체크 여부 추가
	if(ITEMKIND_ENCHANT == pItemEnchant->Kind
		&& FALSE == IS_ENCHANT_TARGET_ITEMKIND(pItemTarget->Kind))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_ITEM, 1001, pItemTarget->Kind);
		return RES_BREAK;
	}

	ITEM_GENERAL *pAttachItem = NULL;
	if(0 != pMsgUseEnchant->AttachItemUniqueNumber)
	{
		// 2009-01-22 by cmkwon, 아래와 같이 인챈트가 아닌지 여부로 체크 수정.
		//if(ITEMKIND_GAMBLE == pItemEnchant->Kind)
		if(ITEMKIND_ENCHANT != pItemEnchant->Kind)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED
							, pItemEnchant->ItemInfo->ReqUnitKind, pItemTarget->ItemInfo->ReqUnitKind);
			return RES_BREAK;
		}

		pAttachItem = m_ItemManager.GetItemGeneralByUID(pMsgUseEnchant->AttachItemUniqueNumber);
		if (pAttachItem == NULL)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnchant->AttachItemUniqueNumber, 0, "attach");
			return RES_BREAK;
		}

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

		if(ITEMKIND_PREVENTION_DELETE_ITEM != pAttachItem->Kind)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, pAttachItem->ItemNum, pAttachItem->ItemInfo->Kind);
			return RES_BREAK;
		}

		// 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도
		if(FALSE == pAttachItem->ItemInfo->IsExistDesParam(DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT))
		{
			////////////////////////////////////
			// 핵프로그램을 사용함 강제 블락
			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 program. Enchant:%I64d Target:%I64d Attach:%I64d IncreaseProbability:%I64d Enchant2:%I64d",pMsgUseEnchant->EnchantItemUniqueNumber,pMsgUseEnchant->TargetItemUniqueNumber,pMsgUseEnchant->AttachItemUniqueNumber,pMsgUseEnchant->IncreaseProbabilityItemUID,pMsgUseEnchant->EnchantItemUniqueNumber2);
				
				INIT_MSG_WITH_BUFFER(MSG_FP_ADMIN_BLOCKACCOUNT, T_FP_ADMIN_BLOCKACCOUNT, pBlockAcc, SendBuf);
				pBlockAcc->blockAccInfo	= blockedAccInfo;
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, pAttachItem->ItemNum, 0, "Invalid desparam(190)");
				ms_pFieldIOCP->Send2PreServerW(SendBuf, MSG_SIZE(MSG_FP_ADMIN_BLOCKACCOUNT));
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[HACK] CFieldIOCPSocket::Process_FC_ITEM_USE_ENCHANT _ AutoBlockSystem : Try enchant using hack program and Blocked AUID(%d) CUID(%d) EnchantItemUID(%I64d) TargetItemUID(%I64d) AttachItemUID(%I64d) IncreaseProbabilityItemUID(%I64d) EnchantItemUID2(%I64d)\r\n", m_character.AccountUniqueNumber, m_character.CharacterUniqueNumber,pMsgUseEnchant->EnchantItemUniqueNumber,pMsgUseEnchant->TargetItemUniqueNumber,pMsgUseEnchant->AttachItemUniqueNumber,pMsgUseEnchant->IncreaseProbabilityItemUID,pMsgUseEnchant->EnchantItemUniqueNumber2);
				// end 2014-03-10 by jekin, 캐나다 치트엔진 사용 인첸트 시도 로그 추가
			}
			else
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, pAttachItem->ItemNum, 0, "Invalid desparam(190)");
				SendString128(STRING_128_USER_POPUP, "AutoBlockSystem : Try enchant using hack program and Blocked");
			}
			return RES_BREAK;
		}
		// end 2014-02-05 by jhseol, 캐나다 치트엔진 사용 인첸트 시도

		//////////////////////////////////////////////////////////////////////////
		// 2008-09-30 by dhjin, 신규 인첸트 - 레이더와 엔진은 파방 사용 불가
		if(ITEMKIND_RADAR == pItemTarget->Kind
			|| ITEMKIND_SUPPORT == pItemTarget->Kind
			|| ITEMKIND_ACCESSORY_UNLIMITED == pItemTarget->Kind			// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
			)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_ITEM);
			return RES_BREAK;		
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-19 by dhjin, 인첸트 확률 증가, 10인첸 파방 카드 - 인첸트 확률 증가 카드 적용
	ITEM_GENERAL *pEnchantProbabilityIncreaseItemG = NULL;
	if(0 != pMsgUseEnchant->IncreaseProbabilityItemUID)
	{
		if(ITEMKIND_ENCHANT != pItemEnchant->Kind)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED
				, pItemEnchant->ItemInfo->ReqUnitKind, pItemTarget->ItemInfo->ReqUnitKind, "Can't use this item !!");
			return RES_BREAK;
		}

		pEnchantProbabilityIncreaseItemG = m_ItemManager.GetItemGeneralByUID(pMsgUseEnchant->IncreaseProbabilityItemUID);
		if (NULL == pEnchantProbabilityIncreaseItemG)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pMsgUseEnchant->IncreaseProbabilityItemUID, 0, "Invalid ItemUID !!");
			return RES_BREAK;
		}
		if(FALSE == pEnchantProbabilityIncreaseItemG->ItemInfo->IsExistDesParam(DES_ENCHANT_INCREASE_PROBABILITY))
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_INVALID_ITEM_KIND, 0, 0, "Invalid desparam");
			return RES_BREAK;
		}
		
		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_ITEM_USE_ENCHANT
		if(pEnchantProbabilityIncreaseItemG->UniqueNumber != pMsgUseEnchant->IncreaseProbabilityItemUID
			|| pEnchantProbabilityIncreaseItemG->Possess != GetCharacter()->CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1003);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d\r\n"
				, GetProtocolTypeString(T_FC_ITEM_USE_ENCHANT), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pEnchantProbabilityIncreaseItemG, string()), pEnchantProbabilityIncreaseItemG->Possess, pMsgUseEnchant->IncreaseProbabilityItemUID);
			return RES_BREAK;
		}
	}


	if (!COMPARE_ITEMKIND(pItemEnchant->ItemInfo->ReqItemKind, pItemTarget->ItemInfo->Kind))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED
						, (BYTE)pItemEnchant->ItemInfo->ReqItemKind, pItemTarget->ItemInfo->Kind);
		return RES_BREAK;
	}
	else if(pItemEnchant->ItemInfo->ReqUnitKind != UNITKIND_ALL_MASK
		&& pItemEnchant->ItemInfo->ReqUnitKind != pItemTarget->ItemInfo->ReqUnitKind)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_UNITKIND_NOT_MATCHED
						, pItemEnchant->ItemInfo->ReqUnitKind, pItemTarget->ItemInfo->ReqUnitKind);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 빠진부분 추가
	if(pSuffixItemG
		&& FALSE == COMPARE_ITEMKIND(pSuffixItemG->ItemInfo->ReqItemKind, pItemTarget->ItemInfo->Kind))
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED
			, (BYTE)pSuffixItemG->ItemInfo->ReqItemKind, pItemTarget->ItemInfo->Kind);
		return RES_BREAK;
	}

//	Err_t tmpErr = CheckItemRequirements(pItemEnchant->ItemInfo);
//	if (tmpErr != ERR_NO_ERROR)
//	{
//		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, tmpErr);
//		return RES_BREAK;
//	}

	int tmpNumOfEnchants = 0;
	if (pItemEnchant->Kind == ITEMKIND_ENCHANT)
	{
		mt_auto_lock mtA(&m_mapEnchant);
// 2007-04-03 by cmkwon, 아래와 같이 인챈트 초기화 아이템 추가하면서 아래와 같이 수정함
//		mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(pItemTarget->UniqueNumber);
//		if (m_mapEnchant.end() != itrEnchantList)
//		{
//			vectENCHANT &vecECH = itrEnchantList->second;
//			tmpNumOfEnchants = vecECH.size();
//			if (tmpNumOfEnchants >= SIZE_MAX_ENCHANT_PER_ITEM)
//			{
//				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_MAX_ENCHANT_PER_ITEM, pItemEnchant->ItemNum, tmpNumOfEnchants);
//				return RES_BREAK;
//			}
//			else if(pAttachItem
//				&& tmpNumOfEnchants >= SIZE_MAX_ENCHANT_USE_ITEMKIND_PREVENTION_DELETE_ITEM)
//			{
//				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEMKIND_PREVENTION_DELETE_ITEM, pItemEnchant->ItemNum, tmpNumOfEnchants);
//				return RES_BREAK;
//			}
//		}
//		else
//		{
//			tmpNumOfEnchants = 0;
//		}
		vectENCHANT *pVectEnchant = this->GetVectEnchantListPtr(pItemTarget->UniqueNumber);
		if(pVectEnchant)
		{
			tmpNumOfEnchants = pVectEnchant->size();
		}

		// start 2012-08-27 by hskim, 베트남 인첸트 핵 관련 추가 보안 처리 (코드상의 문제점은 발견되지 않았으나 만일의 경우에는 로그를 남긴다) (동기화 DB 접속을 시도해서 성능 저하가 있음 : 필요없다고 판단되면 삭제 진행)
		QPARAM_GET_ENCHANT_COUNT EnchantCount;

		EnchantCount.ItemUniqueNumber = pItemTarget->UniqueNumber;
		EnchantCount.EnchantCount = -1;

		ms_pFieldIOCP->m_pAtumDBManager->ExecuteQuery(QT_GetEnchantCount, this, &EnchantCount);

		if( tmpNumOfEnchants != EnchantCount.EnchantCount )
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify] Detected EnchantHack (%s) %s, ItemUID = %I64d, Memory Count = %d, DB Count = %d\r\n"
				, GetProtocolTypeString(T_FC_ITEM_USE_ENCHANT), GetCharacterString(GetCharacter(), string()), pItemTarget->UniqueNumber, tmpNumOfEnchants, EnchantCount.EnchantCount);

			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEM);
			return RES_BREAK;			
		}
		// end 2012-08-27 by hskim, 베트남 인첸트 핵 관련 추가 보안 처리 (코드상의 문제점은 발견되지 않았으나 만일의 경우에는 로그를 남긴다) (동기화 DB 접속을 시도해서 성능 저하가 있음 : 필요없다고 판단되면 삭제 진행)

		// start 2011-10-19 by hskim, EP4 [Free to play] - 10 회 인첸트 아이템 기능 구현
		if( NULL != pVectEnchant && TRUE == pItemEnchant->ItemInfo->IsExistDesParam(DES_ENCHANT_ONCE_APPLY) )
		{
			// ON/OFF 기능 구현

			#ifdef S_EP4_HSKIM
			#else
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEM);
				return RES_BREAK;
			#endif

			// 다른 조합이 있으면 인챈트할 수 없음

			if( 0 != pMsgUseEnchant->AttachItemUniqueNumber || 0 != pMsgUseEnchant->IncreaseProbabilityItemUID || 0 != pMsgUseEnchant->EnchantItemUniqueNumber2 )
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEM);
				return RES_BREAK;
			}

			// 10 인챈트 이상 아이템으로 인챈트할 수 없음

			if( tmpNumOfEnchants >= MAX_ENCHANT_ONCE_APPLY_COUNT )
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_MORE_THEN_10);
				return RES_BREAK;
			}

			// 인챈트 속성이 틀려 인챈트 할 수 없음

			ITEM *pSourceITEM = pItemEnchant->ItemInfo;

			vectENCHANT::iterator itr = pVectEnchant->begin();
			while(itr != pVectEnchant->end())
			{
				ITEM *pEnchantITEM = ms_pFieldIOCP->GetItemInfo(itr->EnchantItemNum);

				if( NULL == pEnchantITEM )
				{
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEM);
					return RES_BREAK;
				}

				for(int i=0; i<SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
				{
					BOOL bSame = FALSE;

					if( DES_NULL == pSourceITEM->ArrDestParameter[i] || DES_ENCHANT_ONCE_APPLY == pSourceITEM->ArrDestParameter[i] )
					{
						continue;
					}

					for(int j=0; j<SIZE_MAX_DESPARAM_COUNT_IN_ITEM; j++)
					{
						if( DES_NULL == pSourceITEM->ArrDestParameter[j] || DES_ENCHANT_ONCE_APPLY == pSourceITEM->ArrDestParameter[j] )
						{
							continue;
						}

						if( pSourceITEM->ArrDestParameter[i] == pEnchantITEM->ArrDestParameter[j] &&
							pSourceITEM->ArrParameterValue[i] == pEnchantITEM->ArrParameterValue[j] )
						{
							bSame = TRUE;

							break;
						}
					}

					if( bSame == FALSE )
					{
						SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_ENCHANT_DIFFERENCE_ATTRIBUTE);
						return RES_BREAK;
					}
				}

				itr++;	
			}

		}
		// end 2011-10-19 by hskim, EP4 [Free to play] - 10 회 인첸트 아이템 기능 구현

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-03 by cmkwon, 인챈트 초기화 아이템 구현 추가
		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - ITEM::IsExistDesParam() 함수로 통합함
		//if(IS_EXIST_DES_PARAM(pItemEnchant->ItemInfo, DES_ENCHANT_INITIALIZE))
		if(pItemEnchant->ItemInfo->IsExistDesParam(DES_ENCHANT_INITIALIZE))
		{
			if(0 >= tmpNumOfEnchants)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEM, pItemEnchant->ItemNum, tmpNumOfEnchants);
				return RES_BREAK;
			}

			ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pItemEnchant->ItemNum);
			if (pEnchantInfo == NULL)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, 0, 0, STRMSG_S_F2NOTIFY_0043);
				return RES_BREAK;
			}

			// 돈 확인
			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);
				}
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2006-08-23 by cmkwon, 모든 인챈트를 가져온다, 인챈트맵에서 제거됨.
			vectENCHANT tmvectEnchant;
			this->PopAllEnchantByItemUID(&tmvectEnchant, pItemTarget->UniqueNumber);

			///////////////////////////////////////////////////////////////////////////////
			// 2006-08-23 by cmkwon, 모든 인챈트 삭제
			ENCHANT *pNewEnchant				= new ENCHANT;
			pNewEnchant->TargetItemUniqueNumber	= pItemTarget->UniqueNumber;
			pNewEnchant->TargetItemNum			= pItemTarget->ItemNum;
			pNewEnchant->EnchantItemNum			= pItemEnchant->ItemNum;

			INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_DELETE_ALL_ENCHANT, T_FC_ITEM_DELETE_ALL_ENCHANT, pDeleteEnchant, SendBuf);
			pDeleteEnchant->ItemUniqueNumber	= pItemTarget->UniqueNumber;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_DELETE_ALL_ENCHANT));

			// Update DB
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteAllEnchant, this, m_character.AccountUniqueNumber, pNewEnchant);

			///////////////////////////////////////////////////////////////////////////////
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 
			INIT_MSG(MSG_FC_ITEM_USE_ENCHANT_OK, T_FC_ITEM_USE_ENCHANT_OK, pUseEnchantOK, SendBuf);
			pUseEnchantOK->EnchantItemNum		= pItemEnchant->ItemNum;
			pUseEnchantOK->SuffixRareItemNum	= 0;
			pUseEnchantOK->bSuccessFlag			= TRUE;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_ENCHANT_OK));

			// 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 (일반유저만 기록)	
			{
				MSG_FL_LOG_ITEM LogItemParameter;
				MEMSET_ZERO(&LogItemParameter, sizeof(LogItemParameter));	// 2013-05-30 by jhseol, GLog 시스템 보완 - 초기화
				LogItemParameter.LogType		= GLOG_IL_LT_ENCHANT_BEGINNING;
				LogItemParameter.ItemSerial		= (UID64_t)pItemEnchant->ItemNum;	// 2013-05-30 by jhseol, GLog 시스템 보완 - 캐스팅
				LogItemParameter.Count1			= -1;
				LogItemParameter.Count2			= 0;
				// 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차

			// 인챈트초기화 아이템 사용 시 대상 아이템 로그
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			// 2012-08-30 by jhseol, 풀로그 남기기 - 변경전의 함수 임으로 주석 해제 안함.
			//CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemTarget, ENCHANT_LOGTYPE_TARGETITEM, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
			CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemTarget, pItemEnchant, 0, TRUE);

			ITEM_GENERAL tmpItemForLog = *pItemEnchant;
			tmpItemForLog.CurrentCount--;
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			// 2012-08-30 by jhseol, 풀로그 남기기 - 변경전의 함수 임으로 주석 해제 안함.
			//CAtumLogSender::SendLogMessageITEMUseENCHANT(this, &tmpItemForLog, ENCHANT_LOGTYPE_SUCCESS, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
			m_ItemManager.UpdateItemCountByPointer(pItemEnchant, -1, IUT_ENCHANT);		// Current 수정하기
			m_ItemManager.UpdateItemCountByPointer(pMoney, -pEnchantInfo->EnchantCost, IUT_ENCHANT);		// 돈 지우기
			return RES_RETURN_TRUE;
		}

		if(tmpNumOfEnchants >= SIZE_MAX_ENCHANT_PER_ITEM)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_MAX_ENCHANT_PER_ITEM, pItemEnchant->ItemNum, tmpNumOfEnchants);
			return RES_BREAK;
		}
		else if(pAttachItem
			&& tmpNumOfEnchants >= SIZE_MAX_ENCHANT_USE_ITEMKIND_PREVENTION_DELETE_ITEM)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEMKIND_PREVENTION_DELETE_ITEM, pItemEnchant->ItemNum, tmpNumOfEnchants);
			return RES_BREAK;
		}

		if(pAttachItem
			&& tmpNumOfEnchants < pAttachItem->ItemInfo->GetParameterValue(DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT))
		{// 2009-01-19 by dhjin, 인첸트 확률 증가, 10인첸 파방 카드 - 사용 가능한 인첸트 수 체크
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_USE_ITEMKIND_PREVENTION_DELETE_ITEM_BY_STARTCOUNT, pAttachItem->ItemInfo->GetParameterValue(DES_ENCHANT_PREVENTION_DELETE_USE_ENCHANT), tmpNumOfEnchants);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템, 인첸트 시 DestParam체크 추가
		if(pItemEnchant->ItemInfo->EnchantCheckDestParam
			&& FALSE == this->CheckDestParamEnchantItemNoLock(pItemEnchant, pItemTarget)) {
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_DES_PARAM);
			return RES_BREAK;
		}
	}
	else if (pItemEnchant->Kind == ITEMKIND_GAMBLE)
	{
		// 2009-09-09 ~ 2010-02-10 by dhjin, 인피니티 - 발동류장착아이템
		if(FALSE == IS_RARE_TARGET_ITEMKIND(pItemTarget->Kind))
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_CANNOT_RARE_ITEM, 1001, pItemTarget->Kind);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
		if(pSuffixItemG)
		{
			// 2010-04-20 by cmkwon, 반드시 pItemEnchant = Prefix, pSuffixItemG = Suffix
			if(pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE)
				|| pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX)
				|| pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE)
				|| pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX))
			{
				char szErrTxt[1024];
				sprintf(szErrTxt, "Prefix(%I64d IsPrefixInit<%d> IsPrefix<%d>) Suffix(%I64d IsSuffixInit<%d> IsSuffix<%d>)"
					, pItemEnchant->UniqueNumber, pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE), pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX)
					, pSuffixItemG->UniqueNumber, pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE), pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX));
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED, 2001, 0, szErrTxt);
				return RES_BREAK;
			}

			if(pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE)
				&& FALSE == pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE))
			{
				char szErrTxt[1024];
				sprintf(szErrTxt, "Prefix(%I64d IsPrefixInit<%d> IsPrefix<%d>) Suffix(%I64d IsSuffixInit<%d> IsSuffix<%d>)"
					, pItemEnchant->UniqueNumber, pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE), pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX)
					, pSuffixItemG->UniqueNumber, pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE), pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX));
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED, 2001, 0, szErrTxt);
				return RES_BREAK;
			}
		}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 		if(DES_RARE_FIX_PREFIX_INITIALIZE == pItemEnchant->ItemInfo->DestParameter1
// 			|| DES_RARE_FIX_SUFFIX_INITIALIZE == pItemEnchant->ItemInfo->DestParameter1)

// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
//		if(DES_RARE_FIX_PREFIX_INITIALIZE == pItemEnchant->ItemInfo->ArrDestParameter[0]
//			|| DES_RARE_FIX_SUFFIX_INITIALIZE == pItemEnchant->ItemInfo->ArrDestParameter[0])
		if(pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE)
			|| pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE))
		{// 접두/접미 개블 초기화

			// 인챈트 정보 검색
			{
				// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 
				if((pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE) && 0 == pItemTarget->PrefixCodeNum)
					|| (pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE) && 0 == pItemTarget->SuffixCodeNum))
				{
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_INITIALIZE_RARE_FIX, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);
					return RES_BREAK;
				}

				ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pItemEnchant->ItemNum);
				if (pEnchantInfo == NULL)
				{
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pItemEnchant->ItemNum, 0, STRMSG_S_F2NOTIFY_0043);
					return RES_BREAK;
				}
				nEnchantCost	= pEnchantInfo->EnchantCost;	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			}

			if(pSuffixItemG)
			{
				// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 접미초기화 아이템인지 여부 체크
				if(FALSE == pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE)
					|| FALSE == pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE))
				{
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED, pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE), pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE));
					return RES_BREAK;
				}
				if(0 == pItemTarget->PrefixCodeNum
					|| 0 == pItemTarget->SuffixCodeNum)
				{// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 접미초기화가 설정되어 있으면 접두초기화도 설정되어야 한다.
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_INITIALIZE_RARE_FIX, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);
					return RES_BREAK;
				}

				ENCHANT_INFO *pEnchantInfo = ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pSuffixItemG->ItemNum);
				if (pEnchantInfo == NULL)
				{
					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NO_SUCH_ITEM, pSuffixItemG->ItemNum, 0, STRMSG_S_F2NOTIFY_0043);
					return RES_BREAK;
				}
				nEnchantCost	+= pEnchantInfo->EnchantCost;
			}

			// 돈 확인
			ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			//if (pMoney == NULL || pMoney->CurrentCount < pEnchantInfo->EnchantCost)
			if (pMoney == NULL || pMoney->CurrentCount < nEnchantCost)
			{
				if(NULL == pMoney)
				{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
					m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
				}
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
				return RES_BREAK;
			}

			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//if(DES_RARE_FIX_PREFIX_INITIALIZE == pItemEnchant->ItemInfo->DestParameter1)
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			//if(DES_RARE_FIX_PREFIX_INITIALIZE == pItemEnchant->ItemInfo->ArrDestParameter[0])
			if(pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX_INITIALIZE))
			{
// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 위쪽에서 체크
//				if(0 == pItemTarget->PrefixCodeNum)
//				{
//					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_INITIALIZE_RARE_FIX);
//					return RES_BREAK;
//				}
				pItemTarget->PrefixCodeNum		= 0;
			}
			
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//if(DES_RARE_FIX_SUFFIX_INITIALIZE == pItemEnchant->ItemInfo->DestParameter1)
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			//if(DES_RARE_FIX_SUFFIX_INITIALIZE == pItemEnchant->ItemInfo->ArrDestParameter[0])
			if(pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX_INITIALIZE)
				|| NULL != pSuffixItemG)	// pSuffixItemG가 NULL이 아니면 접미초기화 아이템이다.
			{
// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 위쪽에서 체크
//				if(0 == pItemTarget->SuffixCodeNum)
//				{
//					SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_INITIALIZE_RARE_FIX);
//					return RES_BREAK;
//				}
				pItemTarget->SuffixCodeNum		= 0;
			}

			// 인챈트/갬블 사용 시 대상 아이템 로그
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			// 2012-08-30 by jhseol, 풀로그 남기기 - 변경전의 함수 임으로 주석 해제 안함.
			//CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemTarget, ENCHANT_LOGTYPE_TARGETITEM, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
			///////////////////////////////////////////////////////////////////////////////
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			if(pItemEnchant)
			{
				CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemTarget, pItemEnchant, tmpNumOfEnchants, TRUE);
			}
			if(pSuffixItemG)
			{
				CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemTarget, pSuffixItemG, tmpNumOfEnchants, TRUE);
			}

			// Send MSG				
			INIT_MSG_WITH_BUFFER(MSG_FC_STORE_UPDATE_RARE_FIX, T_FC_STORE_UPDATE_RARE_FIX, pUpdateRareFix, SendBuf);
			pUpdateRareFix->ItemUID			= pItemTarget->UniqueNumber;
			pUpdateRareFix->PrefixCodeNum	= pItemTarget->PrefixCodeNum;
			pUpdateRareFix->SuffixCodeNum	= pItemTarget->SuffixCodeNum;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_STORE_UPDATE_RARE_FIX));

			// Update DB
			QPARAM_UPDATE_ITEM_RARE_FIX *pQParam = new QPARAM_UPDATE_ITEM_RARE_FIX;
			pQParam->ItemUID				= pItemTarget->UniqueNumber;
			pQParam->PrefixCodeNum			= pItemTarget->PrefixCodeNum;
			pQParam->SuffixCodeNum			= pItemTarget->SuffixCodeNum;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateItemRareFix, this, m_character.AccountUniqueNumber, pQParam);

// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 
// 			INIT_MSG(MSG_FC_ITEM_USE_ENCHANT_OK, T_FC_ITEM_USE_ENCHANT_OK, pUseEnchantOK, SendBuf);
// 			pUseEnchantOK->ItemNum			= pItemEnchant->ItemNum;
// 			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_ENCHANT_OK));
			///////////////////////////////////////////////////////////////////////////////
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 
			INIT_MSG(MSG_FC_ITEM_USE_ENCHANT_OK, T_FC_ITEM_USE_ENCHANT_OK, pUseEnchantOK, SendBuf);
			pUseEnchantOK->EnchantItemNum		= pItemEnchant->ItemNum;
			pUseEnchantOK->SuffixRareItemNum	= (NULL == pSuffixItemG) ? 0 : pSuffixItemG->ItemNum;
			pUseEnchantOK->bSuccessFlag			= TRUE;
			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_ENCHANT_OK));

// 2005-05-12 by cmkwon, 카운터블로 수정중
//			pItemEnchant->CurrentCount = 0;
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
//			CAtumLogSender::SendLogMessageITEMUseENCHANT(this, pItemEnchant);		// 2012-08-30 by jhseol, 풀로그 남기기 - 변경 전의 함수 임으로 주석 해제 안함.
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
//			m_ItemManager.DeleteItemFromCharacterByUID(pItemEnchant->UniqueNumber, IUT_ENCHANT);			// 지우기
			ITEM_GENERAL tmpItemForLog = *pItemEnchant;
			tmpItemForLog.CurrentCount--;

			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			// 2012-08-30 by jhseol, 풀로그 남기기 - 변경 전의 함수 임으로 주석 해제 안함.
			//CAtumLogSender::SendLogMessageITEMUseENCHANT(this, &tmpItemForLog, ENCHANT_LOGTYPE_SUCCESS, pItemTarget->PrefixCodeNum, pItemTarget->SuffixCodeNum);	// 2007-07-30 by cmkwon, 갬블/인챈트 로그에 접두/접미 정보 저장 
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기

			m_ItemManager.UpdateItemCountByPointer(pItemEnchant, -1, IUT_ENCHANT);		// Current 수정하기
			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
			if(pSuffixItemG) // 2010-05-25 by jsKim, 듀얼갬블초기화 관련 버그 - 
			{
				m_ItemManager.UpdateItemCountByPointer(pSuffixItemG, -1, IUT_ENCHANT);		// Current 수정하기
			}
			//m_ItemManager.UpdateItemCountByPointer(pMoney, -pEnchantInfo->EnchantCost, IUT_ENCHANT);		// 돈 지우기
			m_ItemManager.UpdateItemCountByPointer(pMoney, -nEnchantCost, IUT_ENCHANT);		// 돈 지우기
			return RES_RETURN_TRUE;
		}// end_접두/접미 갬블 초기화

		// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
		//if (pItemEnchant->ItemInfo->DestParameter1 == DES_RARE_FIX_PREFIX && pItemTarget->PrefixCodeNum != 0)
		if (IS_DES_RARE_FIX_PREFIX(pItemEnchant->ItemInfo) && pItemTarget->PrefixCodeNum != 0)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_HAVE_RARE_FIX, 0, pItemTarget->PrefixCodeNum);
			return RES_BREAK;
		}

		// 2008-10-21 by cmkwon, 마지막에 선택된 레어는 다시 나오지 않게 수정 - 
		//if (pItemEnchant->ItemInfo->DestParameter1 == DES_RARE_FIX_SUFFIX && pItemTarget->SuffixCodeNum != 0)
		if (IS_DES_RARE_FIX_SUFFIX(pItemEnchant->ItemInfo) && pItemTarget->SuffixCodeNum != 0)
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_HAVE_RARE_FIX, 1, pItemTarget->SuffixCodeNum);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 2010-05-26 추가 버그 수정 - 체크루틴 추가
		if(pSuffixItemG)
		{
			if(FALSE == pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX))
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_REQ_ITEM_NOT_MATCHED, pItemEnchant->ItemInfo->IsExistDesParam(DES_RARE_FIX_PREFIX), pSuffixItemG->ItemInfo->IsExistDesParam(DES_RARE_FIX_SUFFIX));
				return RES_BREAK;
			}
			if(0 != pItemTarget->PrefixCodeNum
				|| 0 != pItemTarget->SuffixCodeNum)
			{
				SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_HAVE_RARE_FIX, 1, pItemTarget->SuffixCodeNum);
				return RES_BREAK;
			}
		}

		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
		//if (pItemEnchant->ItemInfo->DestParameter1 == DES_RARE_FIX_BOTH
		if (pItemEnchant->ItemInfo->ArrDestParameter[0] == DES_RARE_FIX_BOTH
			&& (pItemTarget->PrefixCodeNum != 0 || pItemTarget->SuffixCodeNum != 0))
		{
			SendErrorMessage(T_FC_ITEM_USE_ENCHANT, ERR_PROTOCOL_ALREADY_HAVE_RARE_FIX);
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_ENCHANT_OK, T_FC_ITEM_USE_ENCHANT_OK, pUseEnchantOK, pUseEnchantOKBuf);
	pUseEnchantOK->EnchantItemNum		= pItemEnchant->ItemNum;
	pUseEnchantOK->SuffixRareItemNum	= (NULL == pSuffixItemG) ? 0 : pSuffixItemG->ItemNum;

	Err_t	errCode			= ERR_NO_ERROR;
	BOOL	bSuccessEnchant	= FALSE;
	// 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력
	BOOL	bIsSuccessMessage = FALSE;
	// end 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력
	if(ITEMKIND_ENCHANT == pItemEnchant->Kind)
	{
		errCode = this->TryEnchantItem(&bSuccessEnchant, pItemTarget, tmpNumOfEnchants, pItemEnchant, pAttachItem, pEnchantProbabilityIncreaseItemG);
		// 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력
		bIsSuccessMessage = bSuccessEnchant;
		// end 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력
	}
	else
	{
		errCode = this->TryGambleItem(&bSuccessEnchant, pItemTarget, tmpNumOfEnchants, pItemEnchant, pSuffixItemG);
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 에러체크
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ITEM_USE_ENCHANT, errCode, 10000);
		return RES_BREAK;
	}

	// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - (빠진부분추가) - 인챈트 결과 전송
	pUseEnchantOK->bSuccessFlag		= bSuccessEnchant;
	SendAddData(pUseEnchantOKBuf, MSG_SIZE(MSG_FC_ITEM_USE_ENCHANT_OK));

	// 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력
#if defined(S_INFO_ENCHANT_RESULT_DISPLAY)
	if (bIsSuccessMessage)
	{
		// 접속중인 모든 유저에게 메세지 보내기
		CFieldIOCPSocket *pSock = NULL;
		
		for (int i = (CLIENT_INDEX_START_NUM); i < ms_pFieldIOCP->GetArrayClientSize(); i++)
		{
			pSock = (CFieldIOCPSocket*)ms_pFieldIOCP->GetIOCPSocket(i);
			if (pSock
				&& pSock->IsValidCharacter(FALSE)
				&& pSock->IsCheckInfluenceTypeANDSocketType(INFLUENCE_TYPE_ALL_MASK, ST_CLIENT_TYPE)
				&& pSock->IsCheckLevel(1, CHARACTER_MAX_LEVEL)
				&& COMPARE_BIT_FLAG(pSock->GetCharacter()->UnitKind, UNITKIND_ALL_MASK))	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 기어타입 인자 추가
			{
// 				typedef struct
// 				{
// 					char		szCharacterName[SIZE_MAX_CHARACTER_NAME];
// 					char		szSucItemFullName[SIZE_MAX_RARE_FIX_NAME + SIZE_MAX_ITEM_NAME + SIZE_MAX_RARE_FIX_NAME + 20]; // prefix len + item name len + suffix len
// 					BYTE		flag;
// 				} MSG_FC_INFO_ENCHANT_DISPLAY;
// #define T1_FC_INFO_ENCHANT_DISPLAY				0x80
// #define T_FC_INFO_ENCHANT_DISPLAY				(MessageType_t)((T0_FC_INFO<<8)|T1_FC_INFO_ENCHANT_DISPLAY)
//  				INIT_MSG_WITH_BUFFER(MSG_FC_INFO_ENCHANT_DISPLAY, T_FC_INFO_ENCHANT_DISPLAY, pSucMessage, pSucMessageBuf);
//				// 예외 맵의 유저 체크
// 				MAP_CHANNEL_INDEX pMapChannel;
// 				if(pMapChannel->IsSameMapChannelIndex(pSock->m_character.MapChannelIndex))
// 				{
// 					continue;
// 				}
// 				// 아레나 진행중인지 체크
// 				if(IS_MAP_INFLUENCE_ARENA(pSock->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
// 				{
// 					continue;	
// 				}	
//				pSock->SendAddData(pSucMessageBuf, sizeof(MSG_FC_INFO_ENCHANT_DISPLAY));
				RARE_ITEM_INFO* pPrefixInfo = ms_pFieldIOCP->GetRareItemInfo(pItemTarget->PrefixCodeNum);
				RARE_ITEM_INFO* pSuffixInfo = ms_pFieldIOCP->GetRareItemInfo(pItemTarget->SuffixCodeNum);
				char szPrefixName[SIZE_MAX_RARE_FIX_NAME];
				char szSuffixName[SIZE_MAX_RARE_FIX_NAME];
				char szEnchantSuccessMsg[1024];
				memset(szEnchantSuccessMsg , 0x00, sizeof(szEnchantSuccessMsg));
				memset(szPrefixName , 0x00, sizeof(szPrefixName));
				memset(szSuffixName , 0x00, sizeof(szSuffixName));

				if (pPrefixInfo)
				{
					sprintf(szPrefixName, "%s ", pPrefixInfo->Name);
				}
				if (pSuffixInfo)
				{
					sprintf(szSuffixName, " %s", pSuffixInfo->Name);
				}

				sprintf(szEnchantSuccessMsg, "\\w%s\\w님이 \\g%s\\g\\e%s\\e\\g%s\\g 아이템 \\e+%d\\e 인챈트에 성공하셨습니다.",
					this->GetCharacter()->CharacterName, szPrefixName, pItemTarget->ItemInfo->ItemName, szSuffixName,this->GetVectEnchantListPtr(pItemTarget->UniqueNumber)->size());
				pSock->SendString128(STRING_128_USER_NOTICE, szEnchantSuccessMsg);
			}
		}
	}
#endif
	// end 2015-07-21 by jwlee 인챈트 성공시 모든 유저에게 메세지 출력

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_MIX_ITEMS(const char* pPacket, int nLength, int &nBytesUsed)
{
	int						nRecvTypeSize = 0;
	MSG_FC_ITEM_MIX_ITEMS	*pMsgMixItems = NULL;

	nRecvTypeSize = sizeof(MSG_FC_ITEM_MIX_ITEMS) + ((MSG_FC_ITEM_MIX_ITEMS*)(pPacket+nBytesUsed))->NumOfItems*sizeof(ITEM_UNIQUE_NUMBER_W_COUNT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_INVALID_FIELD_DATA);
		return RES_BREAK;
	}
	pMsgMixItems = (MSG_FC_ITEM_MIX_ITEMS*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

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

	if (m_pCurrentBuildingNPC == NULL
		|| m_pCurrentBuildingNPC->BuildingKind != BUILDINGKIND_FACTORY)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	ITEM_UNIQUE_NUMBER_W_COUNT *arrItemUniqueNumberWithCount
		= (ITEM_UNIQUE_NUMBER_W_COUNT*)(((char*)pMsgMixItems) + sizeof(MSG_FC_ITEM_MIX_ITEMS));

	if (pMsgMixItems->NumOfItems > COUNT_ITEM_MIXING_SOURCE)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_NO_SUCH_MIXING_INFO);
		return RES_BREAK;
	}
	///////////////////////////////////////////////////////////////////////////////
	// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 
	pMsgMixItems->nMixCounts	= max(1, pMsgMixItems->nMixCounts);
	if(COUNT_MAX_MIXING_COUNT < pMsgMixItems->nMixCounts)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_INVALID_ITEM_COUNT, COUNT_MAX_MIXING_COUNT, pMsgMixItems->nMixCounts);
		return RES_BREAK;
	}

	ITEM_W_COUNT_CHECK arrItemWCountCheck[COUNT_ITEM_MIXING_SOURCE];
	MEMSET_ZERO(arrItemWCountCheck, COUNT_ITEM_MIXING_SOURCE*sizeof(arrItemWCountCheck[0]));

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

	// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - Temporary variable in order to save to GameLog.
	BOOL						bIsSuccessforGLog = FALSE;
	ITEM_GENERAL				tmTargetItemGforLog;				
	ITEM_UID_W_ITEMNUM_COUNT	tmArrSourceItemListforGLog[COUNT_ITEM_MIXING_SOURCE];
	MEMSET_ZERO(tmArrSourceItemListforGLog, sizeof(tmArrSourceItemListforGLog[0])*COUNT_ITEM_MIXING_SOURCE);

// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
//	BOOL			bOnlyChangeItemNum = FALSE;		// 2006-06-14 by cmkwon
//	ITEM_GENERAL	*pSourceWeaponItemG = NULL;		// 2006-06-14 by cmkwon
//	int				nSourceWeaponItemCnt = 0;

	// 해당 아이템을 소지 하지 않거나, 개수가 맞지 않는 경우
	for (int i = 0; i < pMsgMixItems->NumOfItems; i++)
	{
		ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(arrItemUniqueNumberWithCount[i].ItemUniqueNumber);

		if ( pItemGeneral == NULL
			|| (IS_COUNTABLE_ITEM(pItemGeneral->Kind) && pItemGeneral->CurrentCount < arrItemUniqueNumberWithCount[i].Count)
			)
		{
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_NO_SUCH_ITEM);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_MIX_ITEMS
		if(this->CheckTradingItem(pItemGeneral->UniqueNumber))
		{
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_ITEM_TRADING, pItemGeneral->UniqueNumber);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-07-22 by cmkwon, 아이템 복사 체크(ItemUID 체크) 추가 - Process_FC_ITEM_MIX_ITEMS
		if(pItemGeneral->UniqueNumber != arrItemUniqueNumberWithCount[i].ItemUniqueNumber
			|| pItemGeneral->Possess != GetCharacter()->CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, 1000);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ItemBug(%s) %s %s, %d %I64d\r\n"
				, GetProtocolTypeString(T_FC_ITEM_MIX_ITEMS), GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemGeneral, string()), pItemGeneral->Possess, arrItemUniqueNumberWithCount[i].ItemUniqueNumber);
			return RES_BREAK;
		}
		
		if(WEAR_NOT_ATTACHED != pItemGeneral->Wear)
		{// 2007-12-12 by cmkwon, 장착 아이템은 조합 불가
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, pItemGeneral->ItemNum, pItemGeneral->Wear);
			return RES_BREAK;
		}

		if((pItemGeneral->Kind == ITEMKIND_ACCESSORY_TIMELIMIT || COMPARE_BIT_FLAG(pItemGeneral->ItemInfo->ItemAttribute, ITEM_ATTR_TIME_LIMITE|ITEM_ATTR_DELETED_TIME_LIMITE_AFTER_USED))	// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 
			&& ITEM_NOT_USING != pItemGeneral->UsingTimeStamp)
		{// 2007-12-12 by cmkwon, 조합시 재료 아이템의 시간 제한 아이템의 사용 여부 체크
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_ALREADY_USE_ITEM, pItemGeneral->ItemNum, pItemGeneral->UsingTimeStamp);
			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 모든 재료 아이템이 카운터블 아이템이 어야 한다.
		if(1 < pMsgMixItems->nMixCounts
			&& FALSE == IS_COUNTABLE_ITEM(pItemGeneral->Kind))
		{
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_REQ_MIX_ITEM_NOT_MATCHED, pItemGeneral->ItemNum, IS_COUNTABLE_ITEM(pItemGeneral->Kind));
			return RES_BREAK;
		}

		arrItemWCountCheck[i].ItemNum	= pItemGeneral->ItemNum;
		arrItemWCountCheck[i].Count		= arrItemUniqueNumberWithCount[i].Count;
		if(FALSE == IS_COUNTABLE_ITEM(pItemGeneral->Kind))
		{
			arrItemWCountCheck[i].Count	= 1;
		}

		// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - setting
		tmArrSourceItemListforGLog[i].ItemUID	= arrItemUniqueNumberWithCount[i].ItemUniqueNumber;
		tmArrSourceItemListforGLog[i].ItemNum	= arrItemWCountCheck[i].ItemNum;
		tmArrSourceItemListforGLog[i].Count		= arrItemWCountCheck[i].Count;

// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
// 		// 2007-08-29 by cmkwon, 조합시 아머도 무기와 같이 레어/인챈트 정보 유지하기 - 추가된 디파인 사용
// 		//if(IS_WEAPON(pItemGeneral->ItemInfo->Kind))
// 		if(IS_ITEMKIND_REMAIN_RARE8ENCHANT_AS_MIX(pItemGeneral->ItemInfo->Kind))
// 		{// 2006-06-14 by cmkwon, weapon item
// 			pSourceWeaponItemG		= pItemGeneral;
// 			nSourceWeaponItemCnt++;
// 		}
	}

// 2009-03-23 by cmkwon, 조합시 인챈트 정보 남기는 시스템 수정 - 아래에서 체크 처리함
//	if(1 != nSourceWeaponItemCnt
//		|| NULL == pSourceWeaponItemG)
//	{// 2006-06-14 by cmkwon, 무기 아이템이 하나인지 체크
//		pSourceWeaponItemG			= NULL;
//	}

	// start 2012-03-16 by hskim, DB 조합식 정리 (고정값 수식으로 변경)
	ITEM_MIXING_INFO FixMixingInfo;
	MEMSET_ZERO(&FixMixingInfo, sizeof(ITEM_MIXING_INFO));

	ITEM_MIXING_INFO *pMixingInfo = ms_pFieldIOCP->CheckAndGetItemFixMixingInfo(arrItemWCountCheck, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, &FixMixingInfo);

	if(pMixingInfo == NULL)
	{
		pMixingInfo = ms_pFieldIOCP->CheckAndGetItemMixingInfo(arrItemWCountCheck, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts);		// 2012-03-16 by hskim, DB 조합식 정리 (고정값 수식으로 변경)
	}
	// end 2012-03-16 by hskim, DB 조합식 정리 (고정값 수식으로 변경)

	// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 인자추가(INT i_nMixCnts)
	//ITEM_MIXING_INFO *pMixingInfo = ms_pFieldIOCP->CheckAndGetItemMixingInfo(arrItemWCountCheck, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts);		// 2012-03-16 by hskim, DB 조합식 정리 (고정값 수식으로 변경)
	if (pMixingInfo == NULL)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_NO_SUCH_MIXING_INFO);
		return RES_BREAK;
	}

	ITEM *pTargetITEM = ms_pFieldIOCP->GetItemInfo(pMixingInfo->TargetItemNum);
	if(NULL == pTargetITEM)
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_NO_SUCH_MIXING_INFO);
		return RES_BREAK;
	}

// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
// 	///////////////////////////////////////////////////////////////////////////////
// 	// 2009-03-23 by cmkwon, 조합시 인챈트 정보 남기는 시스템 수정 - 아래와 같이 정리함
// 	if(1 != nSourceWeaponItemCnt							// 재료 중 무기/아머가 1개 일때만
// 		|| 2 != pMixingInfo->NumOfSourceItems)				// 재료가 2개 일때만
// 	{
// 		bOnlyChangeItemNum		= FALSE;
// 		pSourceWeaponItemG		= NULL;
// 	}

	///////////////////////////////////////////////////////////////////////////////	
	// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 타겟 아이템도 카운터블 아이템 이어야 한다
	if(1 < pMsgMixItems->nMixCounts
		&& FALSE == IS_COUNTABLE_ITEM(pTargetITEM->Kind))
	{
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_REQ_MIX_ITEM_NOT_MATCHED, pTargetITEM->ItemNum, IS_COUNTABLE_ITEM(pTargetITEM->Kind));
		return RES_BREAK;
	}

	ITEM_GENERAL *pMoney = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
	// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 아래와 같이 조합 회수 만큼 체크 한다.
	//if (pMoney == NULL || pMoney->CurrentCount < pMixingInfo->MixingCost)
	INT64 nTotalCost = ((INT64)pMixingInfo->MixingCost) * pMsgMixItems->nMixCounts;
	if(MAX_ITEM_COUNTS < nTotalCost)
	{// 2008-03-18 by cmkwon, 통합비용 체크
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_INVALID_ITEM_COUNT, pMixingInfo->MixingCost, pMsgMixItems->nMixCounts);
		return RES_BREAK;
	}
	if (pMoney == NULL || pMoney->CurrentCount < nTotalCost)	// 2008-03-18 by cmkwon, 통합비용으로 체크
	{
		if(NULL == pMoney)
		{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		}
		SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_NOT_ENOUGH_MONEY);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 아래의 순서로 호출 해야 한다.
	// 2009-10-01 by cmkwon, 그래픽 리소스 변경 관련 초기화 기능 구현 - 
	ITEM_GENERAL *pMainItemG		= NULL;
	ITEM_GENERAL *pSubItemG			= NULL;

	if(this->IsInitEffectItemNumMix(&pMainItemG, &pSubItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM))
	{
		if(0 == pMainItemG->ColorCode)
		{
			char szErrTxt[1024];
			sprintf(szErrTxt, "cannot mix(initEffectItemNum)!! %s, EffectItemNum(%d) ", GetItemString(pMainItemG, string()), pMainItemG->ColorCode);
			SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_CANNOT_USE_ITEM, pMainItemG->ColorCode, 0, szErrTxt);
			return RES_BREAK;
		}
	}
	else
	{
		if(this->IsInitShapeItemNumMix(&pMainItemG, &pSubItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM))
		{
			if(0 == pMainItemG->ShapeItemNum)
			{
				char szErrTxt[1024];
				sprintf(szErrTxt, "cannot mix(initShapeItemNum)!! %s, ShapeItemNum(%d) ", GetItemString(pMainItemG, string()), pMainItemG->ShapeItemNum);
				SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_CANNOT_USE_ITEM, pMainItemG->ShapeItemNum, 0, szErrTxt);
				return RES_BREAK;
			}
		}
		else
		{
			if(FALSE == this->IsChangeEffectItemNumMix(&pMainItemG, &pSubItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM))
			{
				if(FALSE == this->IsChangeShapeItemNumMix(&pMainItemG, &pSubItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM))
				{
					this->IsChangeItemNumMix(&pMainItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM);
				}
			}
		}
	}

	// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 
	tmTargetItemGforLog.AccountUniqueNumber	= this->GetCharacter()->AccountUniqueNumber;
	tmTargetItemGforLog.Possess				= this->GetCharacter()->CharacterUniqueNumber;
	tmTargetItemGforLog.ItemNum				= pMixingInfo->TargetItemNum;

	// 확률 계산 및 적용
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_MIX_ITEMS_RESULT, T_FC_ITEM_MIX_ITEMS_RESULT, msgMixResult, msgMixResultBuf);
	// 2007-12-10 by cmkwon, 랜덤 시스템 수정 - 
	//Prob10K_t prob = RAND10K();
	Prob10K_t prob = ms_pFieldIOCP->GetRandInt32(0, MAX_RAND10K_VALUE);	// 2007-12-10 by cmkwon, 랜덤 시스템 수정 - 
	if (prob <= pMixingInfo->MixingProbability)
	{// 성공

		msgMixResult->Err					= ERR_NO_ERROR;
		bIsSuccessforGLog					= TRUE;
		tmTargetItemGforLog.CurrentCount	= pMsgMixItems->nMixCounts;	// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 

		if(pMainItemG && pSubItemG)		
		{// 2009-08-27 by cmkwon, ShapeItemNum or EffectItemNum 조합

			tmTargetItemGforLog.ItemNum			= pMainItemG->ItemNum;
			tmTargetItemGforLog.UniqueNumber	= pMainItemG->UniqueNumber;

			///////////////////////////////////////////////////////////////////////////////			
			// 2009-10-01 by cmkwon, 그래픽 리소스 변경 관련 초기화 기능 구현 - 
			if(pSubItemG->ItemInfo->IsExistDesParam(DES_INIT_SHAPE_ITEM))
			{		
				INT nDelShapeItemNum = pMainItemG->ShapeItemNum;		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				m_ItemManager.ReturnShapeChangeKitItem(pMainItemG);		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - ReturnShapeChangeKitItem 호출

				pMainItemG->ShapeItemNum			= 0;	// 2009-10-01 by cmkwon, 0으로 초기화
				tmTargetItemGforLog.CurrentCount	= 0;

				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				if( 0 != pMainItemG->FixedTermShape.TimerUID && 0 != nDelShapeItemNum )
				{
					m_TimerManager.StopTimerField(pMainItemG->FixedTermShape.TimerUID);

					CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pMainItemG, nDelShapeItemNum, pMainItemG->FixedTermShape);
				}

				pMainItemG->FixedTermShape.bActive = FALSE;
				pMainItemG->FixedTermShape.StartDate.Reset();
				pMainItemG->FixedTermShape.EndDate.Reset();
				pMainItemG->FixedTermShape.TimerUID = 0;

				QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
				pQParamFT->ItemUID = pMainItemG->UniqueNumber;
				pQParamFT->TermType = FIXED_TERM_SHAPE;
				pQParamFT->AppliedItemNum = pMainItemG->ShapeItemNum;
				pQParamFT->StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParamFT->EndDate = pMainItemG->FixedTermShape.EndDate;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				QPARAM_UPDATE_SHAPEITEMNUM *pQParam = new QPARAM_UPDATE_SHAPEITEMNUM;
				pQParam->ItemUID		= pMainItemG->UniqueNumber;
				pQParam->nShapeItemNum	= pMainItemG->ShapeItemNum;
				
				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				pQParam->FixedTermShape.bActive = pMainItemG->FixedTermShape.bActive;
				pQParam->FixedTermShape.StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParam->FixedTermShape.EndDate = pMainItemG->FixedTermShape.EndDate;
				pQParam->FixedTermShape.TimerUID = pMainItemG->FixedTermShape.TimerUID;
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateShapeItemNum, this, m_character.AccountUniqueNumber, pQParam);
			}
			else if(pSubItemG->ItemInfo->IsExistDesParam(DES_INIT_EFFECT_ITEM))
			{
				pMainItemG->ColorCode				= 0;	// 2009-10-01 by cmkwon, 0으로 초기화
				tmTargetItemGforLog.CurrentCount	= 0;
				QPARAM_STORE_UPDATE_COLORCODE *pQParam = new QPARAM_STORE_UPDATE_COLORCODE;
				pQParam->ItemUniqueNumber	= pMainItemG->UniqueNumber;
				pQParam->ColorCode			= pMainItemG->ColorCode;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_StoreUpdateColorCode, this, m_character.AccountUniqueNumber, pQParam);
			}
			// 2010-05-26 jsKim 이팩트 외형변경 같이 처리하도록 수정 -
            else if(pSubItemG->ItemInfo->IsExistDesParam(DES_SHAPE_ITEM) && pSubItemG->ItemInfo->IsExistDesParam(DES_EFFECT_ITEM))
			{
				INT nDelShapeItemNum = pMainItemG->ShapeItemNum;		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				m_ItemManager.ReturnShapeChangeKitItem(pMainItemG);		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - ReturnShapeChangeKitItem 호출

				// 2009-08-27 by cmkwon, ShapeItemNum 변경
				pMainItemG->ShapeItemNum			= pSubItemG->ItemInfo->LinkItem;	// 2009-09-15 by cmkwon, 버그 수정
				tmTargetItemGforLog.CurrentCount	= pMainItemG->ShapeItemNum;

				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				if( 0 != pMainItemG->FixedTermShape.TimerUID && 0 != nDelShapeItemNum )
				{
					m_TimerManager.StopTimerField(pMainItemG->FixedTermShape.TimerUID);

					CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pMainItemG, nDelShapeItemNum, pMainItemG->FixedTermShape);
				}

				pMainItemG->FixedTermShape.bActive = FALSE;
				pMainItemG->FixedTermShape.StartDate.Reset();
				pMainItemG->FixedTermShape.EndDate.Reset();
				pMainItemG->FixedTermShape.TimerUID = 0;

				QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
				pQParamFT->ItemUID = pMainItemG->UniqueNumber;
				pQParamFT->TermType = FIXED_TERM_SHAPE;
				pQParamFT->AppliedItemNum = pMainItemG->ShapeItemNum;
				pQParamFT->StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParamFT->EndDate = pMainItemG->FixedTermShape.EndDate;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				if( pSubItemG->ItemInfo->IsExistDesParam(DES_FIXED_TERM_SHAPE_TIME) )
				{
					int nFixedTermTime = (int)pSubItemG->ItemInfo->GetParameterValue(DES_FIXED_TERM_SHAPE_TIME);
					if( 0 != nFixedTermTime )
					{
						if( 0 != nDelShapeItemNum )
						{
							CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pMainItemG, nDelShapeItemNum, pMainItemG->FixedTermShape);		// 업데이트시 외형변경 종료 로그 남기기
						}

						pMainItemG->FixedTermShape.bActive = TRUE;
						pMainItemG->FixedTermShape.StartDate.SetCurrentDateTime();
						pMainItemG->FixedTermShape.EndDate.SetCurrentDateTime();
						pMainItemG->FixedTermShape.EndDate.AddDateTime(0, 0, 0, 0, nFixedTermTime, 0);
						pMainItemG->FixedTermShape.TimerUID = 0;

						if( nFixedTermTime < MANAGE_MAX_TIME_FIXED_TERM_MINUTELY )
						{
							pMainItemG->FixedTermShape.TimerUID = m_TimerManager.StartTimerField(TE_TYPE_FIXED_TERM_SHAPE, nFixedTermTime * TIMER_DO_MINUTELY_WORK, 0, 0);
						}

						QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
						pQParamFT->ItemUID = pMainItemG->UniqueNumber;
						pQParamFT->TermType = FIXED_TERM_SHAPE;
						pQParamFT->AppliedItemNum = pMainItemG->ShapeItemNum;
						pQParamFT->StartDate = pMainItemG->FixedTermShape.StartDate;
						pQParamFT->EndDate = pMainItemG->FixedTermShape.EndDate;
						ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);

						CAtumLogSender::SendLogMessageFixedTermShapeStart(this, pMainItemG, pSubItemG->ItemInfo->ItemNum);
					}
				}
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				QPARAM_UPDATE_SHAPEITEMNUM *pQParam = new QPARAM_UPDATE_SHAPEITEMNUM;
				pQParam->ItemUID		= pMainItemG->UniqueNumber;
				pQParam->nShapeItemNum	= pMainItemG->ShapeItemNum;
				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				pQParam->FixedTermShape.bActive = pMainItemG->FixedTermShape.bActive;
				pQParam->FixedTermShape.StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParam->FixedTermShape.EndDate = pMainItemG->FixedTermShape.EndDate;
				pQParam->FixedTermShape.TimerUID = pMainItemG->FixedTermShape.TimerUID;
				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateShapeItemNum, this, m_character.AccountUniqueNumber, pQParam);

				// 2009-08-27 by cmkwon, EffectItemNum 변경, 기존 ColorCode 필드를 EffectItemNum 으로 변경해서 사용한다
				pMainItemG->ColorCode				= pSubItemG->ItemNum;	// 2009-09-15 by cmkwon, 버그 수정
				tmTargetItemGforLog.CurrentCount	= pMainItemG->ColorCode;
				QPARAM_STORE_UPDATE_COLORCODE* pQParam1 = new QPARAM_STORE_UPDATE_COLORCODE;
				pQParam1->ItemUniqueNumber	= pMainItemG->UniqueNumber;
				pQParam1->ColorCode			= pMainItemG->ColorCode;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_StoreUpdateColorCode, this, m_character.AccountUniqueNumber, pQParam1);
			}
			else if(pSubItemG->ItemInfo->IsExistDesParam(DES_SHAPE_ITEM))
			{
				INT nDelShapeItemNum = pMainItemG->ShapeItemNum;		// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				m_ItemManager.ReturnShapeChangeKitItem(pMainItemG);		// 2013-05-31 by jhseol,bckim 아머 컬렉션 - ReturnShapeChangeKitItem 호출
				
				// 2009-08-27 by cmkwon, ShapeItemNum 변경
				pMainItemG->ShapeItemNum			= pSubItemG->ItemInfo->LinkItem;	// 2009-09-15 by cmkwon, 버그 수정
				tmTargetItemGforLog.CurrentCount	= pMainItemG->ShapeItemNum;

				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				if( 0 != pMainItemG->FixedTermShape.TimerUID && 0 != nDelShapeItemNum )
				{
					m_TimerManager.StopTimerField(pMainItemG->FixedTermShape.TimerUID);

					CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pMainItemG, nDelShapeItemNum, pMainItemG->FixedTermShape);
				}

				pMainItemG->FixedTermShape.bActive = FALSE;
				pMainItemG->FixedTermShape.StartDate.Reset();
				pMainItemG->FixedTermShape.EndDate.Reset();
				pMainItemG->FixedTermShape.TimerUID = 0;

				QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
				pQParamFT->ItemUID = pMainItemG->UniqueNumber;
				pQParamFT->TermType = FIXED_TERM_SHAPE;
				pQParamFT->AppliedItemNum = pMainItemG->ShapeItemNum;
				pQParamFT->StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParamFT->EndDate = pMainItemG->FixedTermShape.EndDate;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				if( pSubItemG->ItemInfo->IsExistDesParam(DES_FIXED_TERM_SHAPE_TIME) )
				{
					int nFixedTermTime = (int)pSubItemG->ItemInfo->GetParameterValue(DES_FIXED_TERM_SHAPE_TIME);
					if( 0 != nFixedTermTime )
					{
						if( 0 != nDelShapeItemNum )
						{
							CAtumLogSender::SendLogMessageFixedTermShapeEnd(this, pMainItemG, nDelShapeItemNum, pMainItemG->FixedTermShape);		// 업데이트시 외형변경 종료 로그 남기기
						}

						pMainItemG->FixedTermShape.bActive = TRUE;
						pMainItemG->FixedTermShape.StartDate.SetCurrentDateTime();
						pMainItemG->FixedTermShape.EndDate.SetCurrentDateTime();
						pMainItemG->FixedTermShape.EndDate.AddDateTime(0, 0, 0, 0, nFixedTermTime, 0);
						pMainItemG->FixedTermShape.TimerUID = 0;

						if( nFixedTermTime < MANAGE_MAX_TIME_FIXED_TERM_MINUTELY )
						{
							pMainItemG->FixedTermShape.TimerUID = m_TimerManager.StartTimerField(TE_TYPE_FIXED_TERM_SHAPE, nFixedTermTime * TIMER_DO_MINUTELY_WORK, 0, 0);
						}

						QPARAM_FIXED_TERM_SHAPE	*pQParamFT = new QPARAM_FIXED_TERM_SHAPE;
						pQParamFT->ItemUID = pMainItemG->UniqueNumber;
						pQParamFT->TermType = FIXED_TERM_SHAPE;
						pQParamFT->AppliedItemNum = pMainItemG->ShapeItemNum;
						pQParamFT->StartDate = pMainItemG->FixedTermShape.StartDate;
						pQParamFT->EndDate = pMainItemG->FixedTermShape.EndDate;
						ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertFixedTerm, this, m_character.AccountUniqueNumber, pQParamFT);

						CAtumLogSender::SendLogMessageFixedTermShapeStart(this, pMainItemG, pSubItemG->ItemInfo->ItemNum);
					}
				}
				// end 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)

				QPARAM_UPDATE_SHAPEITEMNUM *pQParam = new QPARAM_UPDATE_SHAPEITEMNUM;
				pQParam->ItemUID		= pMainItemG->UniqueNumber;
				pQParam->nShapeItemNum	= pMainItemG->ShapeItemNum;
				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				pQParam->FixedTermShape.bActive = pMainItemG->FixedTermShape.bActive;
				pQParam->FixedTermShape.StartDate = pMainItemG->FixedTermShape.StartDate;
				pQParam->FixedTermShape.EndDate = pMainItemG->FixedTermShape.EndDate;
				pQParam->FixedTermShape.TimerUID = pMainItemG->FixedTermShape.TimerUID;
				// 2012-10-10 by hskim, 기간제 속성 구현 (기간제 외형)
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateShapeItemNum, this, m_character.AccountUniqueNumber, pQParam);
			}
			else if(pSubItemG->ItemInfo->IsExistDesParam(DES_EFFECT_ITEM))
			{
				// 2009-08-27 by cmkwon, EffectItemNum 변경, 기존 ColorCode 필드를 EffectItemNum 으로 변경해서 사용한다
				pMainItemG->ColorCode				= pSubItemG->ItemNum;	// 2009-09-15 by cmkwon, 버그 수정
				tmTargetItemGforLog.CurrentCount	= pMainItemG->ColorCode;
				QPARAM_STORE_UPDATE_COLORCODE *pQParam = new QPARAM_STORE_UPDATE_COLORCODE;
				pQParam->ItemUniqueNumber	= pMainItemG->UniqueNumber;
				pQParam->ColorCode			= pMainItemG->ColorCode;
				ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_StoreUpdateColorCode, this, m_character.AccountUniqueNumber, pQParam);
			}
			else
			{
				char szErrTxt[1024];
				sprintf(szErrTxt, "cannot mix(unknown type)!! Main(%s) Sub(%s)", GetItemString(pMainItemG, string()), GetItemString(pSubItemG, string()));
				SendErrorMessage(T_FC_ITEM_MIX_ITEMS, ERR_PROTOCOL_INVALID_MIXING_INFO, pMainItemG->ShapeItemNum, 0, szErrTxt);
				return RES_BREAK;
			}
		}
		else if(pMainItemG)
		{// 2009-08-27 by cmkwon, ItemNum 변경 조합
			// 2006-06-14 by cmkwon, ItemNum만 변경된다. 레어,인챈트는 자동으로 유지된다.
			tmTargetItemGforLog.CurrentCount	= pTargetITEM->ItemNum;
			m_ItemManager.UpdateItemNumByPointer(pMainItemG, pTargetITEM, IUT_MIXING);
			tmTargetItemGforLog.UniqueNumber	= pMainItemG->UniqueNumber;		// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 
		}
		else
		{// 2009-08-27 by cmkwon, 일반 조합

			// 2010-02-11 by cmkwon, 조합시 외형,이펙트 유지 시스템 구현 - 
			//m_ItemManager.InsertItemBaseByItemNum(pMixingInfo->TargetItemNum, pMsgMixItems->nMixCounts, IUT_MIXING);
			///////////////////////////////////////////////////////////////////////////////
			// 2010-02-11 by cmkwon, 조합시 외형,이펙트 유지 시스템 구현 - 
			if(TRUE == this->IsKeepShape8EffectMix(&pMainItemG, arrItemUniqueNumberWithCount, pMsgMixItems->NumOfItems, pMsgMixItems->nMixCounts, pTargetITEM))
			{
				// 2010-02-11 by cmkwon, ShapeItemNum, EffectItemNum 유지
				m_ItemManager.InsertItemBaseByItemNum(pMixingInfo->TargetItemNum, pMsgMixItems->nMixCounts, IUT_MIXING, FALSE, ITEM_IN_CHARACTER, TRUE, TRUE, 0, 0, pMainItemG->ShapeItemNum, pMainItemG->ColorCode);
				pMainItemG		= NULL;		// 2010-02-11 by cmkwon, 반드시 NULL로 초기화 해줘야함.
			}
			else
			{
				m_ItemManager.InsertItemBaseByItemNum(pMixingInfo->TargetItemNum, pMsgMixItems->nMixCounts, IUT_MIXING);
			}
		}
	}


	else
	{// 실패
		msgMixResult->Err = ERR_PROTOCOL_LOW_PROBABILITY;
		// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 
		// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
		//CAtumLogSender::SendLogMessageITEMUseMix(this, pMixingInfo->TargetItemNum, 0);	// 2012-08-30 by jhseol, 풀로그 남기기 - 변경 전의 함수 임으로 주석 해제 안함.
#endif	//#ifdef S_FULL_LOG_JHSEOL
		// end 2012-08-30 by jhseol, 풀로그 남기기
		bIsSuccessforGLog	= FALSE;				// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-09-26 by cmkwon, 조합시 GameLog 수정 - 
	CAtumLogSender::SendLogMessageITEMUseMix(this, bIsSuccessforGLog, &tmTargetItemGforLog, tmArrSourceItemListforGLog);

	///////////////////////////////////////////////////////////////////////////////
	// 돈 지우기
	// 2008-03-17 by cmkwon, 조합 시스템 기능 추가 - 조합 통합비용을 차감한다
	//m_ItemManager.UpdateItemCountByPointer(pMoney, -pMixingInfo->MixingCost, IUT_MIXING);
	m_ItemManager.UpdateItemCountByPointer(pMoney, -nTotalCost, IUT_MIXING);

	///////////////////////////////////////////////////////////////////////////////	
	// 조합 Source Item delete
	for (i = 0; i < pMsgMixItems->NumOfItems; i++)
	{
		ITEM_GENERAL *pItemGeneral = m_ItemManager.GetItemGeneralByUID(arrItemUniqueNumberWithCount[i].ItemUniqueNumber);

		if (pItemGeneral == NULL)
		{
			continue;
		}

// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 
// 		if(bOnlyChangeItemNum
// 			&& pItemGeneral == pSourceWeaponItemG)
// 		{// 2006-06-14 by cmkwon, ItemNum이 변경된다, 삭제하면 안된다.
// 			continue;
// 		}
		///////////////////////////////////////////////////////////////////////////////
		// 2009-08-26 by cmkwon, 그래픽 리소스 변경 시스템 구현 - 조합 성공시 pMainItemG가 유효하면 그 아이템은 삭제하지 않는다
		if(bIsSuccessforGLog
			&& pItemGeneral == pMainItemG)
		{
			continue;
		}

		if (IS_COUNTABLE_ITEM(pItemGeneral->Kind))
		{
			m_ItemManager.UpdateItemCountByPointer(pItemGeneral, -arrItemUniqueNumberWithCount[i].Count, IUT_MIXING);
		}
		else
		{
			m_ItemManager.DeleteItemFromCharacterByUID(pItemGeneral->UniqueNumber, IUT_MIXING);
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 조합 결과 정송
	SendAddData(msgMixResultBuf, MSG_SIZE(MSG_FC_ITEM_MIX_ITEMS_RESULT));

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_GUILDSUMMON(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_GUILDSUMMON,
									MSG_FC_ITEM_USE_CARDITEM_GUILDSUMMON, pRGuildSummon);

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 1);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_GUILDSUMMON
	if(this->CheckTradingItem(pRGuildSummon->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_ITEM_TRADING, pRGuildSummon->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRGuildSummon->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_NO_SUCH_ITEM, pRGuildSummon->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED
			, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	if(FALSE == ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_NOT_GUILD_MASTER);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_GUILD_SUMMON_MEMBER, T_FC_GUILD_SUMMON_MEMBER, pSSummon, SendBuf);
	pSSummon->MapChannel		= m_character.MapChannelIndex;
	pSSummon->PositionVector	= m_character.PositionVector;
	pSSummon->uidGuildUID		= m_character.GuildUniqueNumber;
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	switch(pItemInfo->DestParameter1)
	switch(pItemInfo->ArrDestParameter[0])
	{
	case DES_CASH_GUILD_ALL_MEMBERS_SUMMON:
		{
			int nSendedCounts = ms_pFieldIOCP->SendGuildSummonMessage(SendBuf, MSG_SIZE(MSG_FC_GUILD_SUMMON_MEMBER), m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber, this->GetCurrentFieldMapProject());
			if(nSendedCounts <= 0)
			{
				SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_NO_SUCH_GUILD_MEMBER);
				return RES_BREAK;
			}
		}
		break;
	case DES_CASH_GUILD_MEMBER_SUMMON:
		{
			CFieldIOCPSocket *pMemberFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pRGuildSummon->szCharacterName10);
			if(NULL == pMemberFISock
				|| FALSE == pMemberFISock->IsUsing()
				|| m_character.GuildUniqueNumber != pMemberFISock->m_character.GuildUniqueNumber
				|| CS_PLAYING != pMemberFISock->GetClientState()
				|| COMPARE_BODYCON_BIT(pMemberFISock->m_character.BodyCondition, BODYCON_DEAD_MASK)
				|| pMemberFISock->IsPartyBattleState())
			{
				SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_INVALID_PEER_CHARACTER
					, 0, 0, pRGuildSummon->szCharacterName10);
				return RES_BREAK;
			}
			
			pMemberFISock->SendAddData(SendBuf, MSG_SIZE(MSG_FC_GUILD_SUMMON_MEMBER));
		}
		break;
	default:
		{
			// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
			//SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILDSUMMON, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
			return RES_BREAK;
		}
	}

// 2005-05-11 by cmkwon, 카운터블로 수정중
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
//	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기

	ITEM_GENERAL tmpItemForLog = *pItemG;		// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_RESTORE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_RESTORE,
									MSG_FC_ITEM_USE_CARDITEM_RESTORE, pRRestore);

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

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_RESTORE
	if(this->CheckTradingItem(pRRestore->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_ITEM_TRADING, pRRestore->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRRestore->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_NO_SUCH_ITEM, pRRestore->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED
			, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	// 일반 부활 카드 - 7010820, 슈퍼 부활 카드 - 7010310
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(DES_CASH_NORMAL_RESTORE != pItemInfo->DestParameter1
//		&& DES_CASH_SUPER_RESTORE != pItemInfo->DestParameter1)
	if(DES_CASH_NORMAL_RESTORE != pItemInfo->ArrDestParameter[0]
			&& DES_CASH_SUPER_RESTORE != pItemInfo->ArrDestParameter[0])
	{
		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
		//SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}

	CFieldMapProject *pFMPro = GetCurrentFieldMapProject();
	if(NULL == pFMPro
		|| IS_MAP_INFLUENCE_EVENT_AREA(pFMPro->m_nMapInfluenceType)
		|| IS_MAP_INFLUENCE_ARENA(pFMPro->m_nMapInfluenceType)		// 2007-05-02 by dhjin,  아레나 대전 중에는 사용할 수 없다.
		|| IS_MAP_INFLUENCE_OUTPOST(pFMPro->m_nMapInfluenceType))	// 2007-10-06 by dhjin, 전진기지 도시 맵에서는 사용할 수 없다.
	{// 2006-11-17 by cmkwon, 이벤트맵에서는 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 2, m_character.CharacterName);
		return RES_BREAK;
	}

	if(COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI) 
		&& FALSE == pFMPro->IsConflictAreaMap()
		&& MAP_INFLUENCE_NEUTRALITY != pFMPro->GetMapInfluenceType()
		&& 0 == m_pCurrentFieldMapChannel->GetMapChannelIndex().ChannelIndex
		&& ms_pFieldIOCP->m_InflWarManager.CheckSummonBossAndStrategyPoint())	
	{// 2007-10-06 by dhjin, 모선전과 거점전이 진행 중이면 체크한다.

		if(ms_pFieldIOCP->m_InflWarManager.CheckVCNBossMonsterSummoning()
			&& IS_MAP_INFLUENCE_VCN(pFMPro->m_nMapInfluenceType))
		{// 2007-10-06 by dhjin, VCN모선이 소환되어있는 상태
			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 3, m_character.CharacterName);
			return RES_BREAK;			
		}
		
		if(ms_pFieldIOCP->m_InflWarManager.CheckANIBossMonsterSummoning()
			&& IS_MAP_INFLUENCE_ANI(pFMPro->m_nMapInfluenceType))
		{// 2007-10-06 by dhjin, ANI모선이 소환되어있는 상태
			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 4, m_character.CharacterName);
			return RES_BREAK;			
		}

		if(ms_pFieldIOCP->m_InflWarManager.CheckSummonStrategyPointInfoByMapIndex(pFMPro->m_nMapIndex))
		{// 2007-10-06 by dhjin, 거점 관련 체크
			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 5, m_character.CharacterName);
			return RES_BREAK;
		}
	}


	if (FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{// 2006-04-10 by cmkwon, 캐릭터가 죽은 상태가 아니다.
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 6, m_character.CharacterName);
		return RES_BREAK;
	}
	if (this->IsPartyBattleState())
	{// 2006-04-10 by cmkwon, 파티전 체크
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_ALREADY_PARTY_BATTLE);
		return RES_BREAK;
	}

	int nRNum = RAND100();
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(nRNum >= pItemInfo->ParameterValue1)
	if(nRNum >= pItemInfo->ArrParameterValue[0])
	{// 2006-04-10 by cmkwon, 천사의 가호/날개/깃털 사용 실패 - 아이템을 사라짐
 		ITEM_GENERAL tmpItemForLog = *pItemG;		
 		tmpItemForLog.CurrentCount--;
 		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
 		m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
 		igLock.auto_unlock_cancel();

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_FAILURE_USE_RESTORE_ITEM, pItemInfo->ItemNum, pItemInfo->ParameterValue1);
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_FAILURE_USE_RESTORE_ITEM, pItemInfo->ItemNum, pItemInfo->ArrParameterValue[0]);
		return RES_BREAK;
	}

	if(0.0f < m_character.DownExperience)
	{// 2006-04-10 by cmkwon, 떨어진 경험치 처리
 		this->ChangeExperience(max(0.0f, m_character.DownExperience), FALSE, FALSE);		// 2011-09-02 by hskim, 파트너 시스템 2차
 		this->m_character.DownExperience	= 0.0f;
	}
	if(0 < m_character.DownSPIOnDeath)
	{// 2006-04-10 by cmkwon, 떨어진 SPI 처리
		ITEM_GENERAL *pMoneyItemG = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
		if(pMoneyItemG)
		{
			m_ItemManager.UpdateItemCountByPointer(pMoneyItemG, m_character.DownSPIOnDeath, IUT_USE_ITEM);
		}
		else
		{
			// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
			// 2006-12-23 by cmkwon, 수정
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, m_character.DownSPIOnDeath, IUT_GENERAL);
		}
		this->m_character.DownSPIOnDeath	= 0;
	}
 	ITEM_GENERAL tmpItemForLog = *pItemG;		
 	tmpItemForLog.CurrentCount--;
 	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
 	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();

 	this->CharacterDeadGameStartRoutine(TRUE, this->m_character.HP, this->m_character.DP, this->m_character.SP);
	WarpToMap(m_character.MapChannelIndex);	// 같은맵의 기본 워프게이트로 이동
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(101) : %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);

// 2006-04-10 by cmkwon, 위와 같이 일반/슈퍼 부활 카드를 천사의 가호/날개/킷털로 변경함
// 	CFieldIOCPSocket *pWarpFISocket = NULL;
// 	if(DES_CASH_NORMAL_RESTORE == pItemInfo->DestParameter1
// 		|| 0 == strncmp(m_character.CharacterName, pRRestore->szCharacterName10, SIZE_MAX_CHARACTER_NAME))
// 	{
// 		if (FALSE == COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 0, m_character.CharacterName);
// 			return RES_BREAK;
// 		}
// 		pWarpFISocket						= this;
// 
// 		if (pWarpFISocket->IsPartyBattleState())
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_ALREADY_PARTY_BATTLE);
// 			return RES_BREAK;
// 		}
// 		pWarpFISocket->ChangeExperience(max(0.0f, pWarpFISocket->m_character.DownExperience), FALSE);
// 		pWarpFISocket->m_character.DownExperience		= 0.0f;
// 		pWarpFISocket->CharacterDeadGameStartRoutine(TRUE, pWarpFISocket->m_character.HP, pWarpFISocket->m_character.DP, pWarpFISocket->m_character.SP);
// 
// 		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY, T_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY, pSNotify, SendBuf);
// 		pSNotify->restoreClientIdx			= pWarpFISocket->GetCharacter()->ClientIndex;
// 		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pWarpFISocket->GetCharacter()->PositionVector
// 			, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY), pWarpFISocket->GetCurrentFieldMapChannel());
// 
// // 2005-05-11 by cmkwon, 카운터블로 수정중
// //		CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
// //		m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기		
// 		ITEM_GENERAL tmpItemForLog = *pItemG;		
// 		tmpItemForLog.CurrentCount--;
// 		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
// 		m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
// 
// 		EventResult_t ret = pWarpFISocket->WarpToMap(m_character.MapChannelIndex);	// 같은맵의 기본 워프게이트로 이동
// 		if (ret == EVENT_RESULT_BREAK)
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_WARP
// 				, m_character.MapChannelIndex.MapIndex, m_character.MapChannelIndex.ChannelIndex, pWarpFISocket->m_character.CharacterName);
// 			return RES_BREAK;
// 		}
// 		igLock.auto_unlock_cancel();
// 	}
// 	else
// 	{
// 		pWarpFISocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pRRestore->szCharacterName10);
// 		if(NULL == pWarpFISocket)
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_INVALID_CHARACTER_NAME, 0, 0, pRRestore->szCharacterName10);
// 			return RES_BREAK;
// 		}
// 		if(FALSE == COMPARE_BODYCON_BIT(pWarpFISocket->m_character.BodyCondition, BODYCON_DEAD_MASK))
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_USE_ITEM, 0, 0, pWarpFISocket->m_character.CharacterName);
// 			return RES_BREAK;
// 		}		
// 		if (pWarpFISocket->IsPartyBattleState())
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_ALREADY_PARTY_BATTLE);
// 			return RES_BREAK;
// 		}
// 
// // 2005-05-11 by cmkwon, 카운터블로 수정중
// //		CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
// //		m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기
// 		ITEM_GENERAL tmpItemForLog = *pItemG;		
// 		tmpItemForLog.CurrentCount--;
// 		CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
// 		m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
// 		igLock.auto_unlock_cancel();
// 
// 		pWarpFISocket->ChangeExperience(max(0.0f, pWarpFISocket->m_character.DownExperience), FALSE);
// 		pWarpFISocket->m_character.DownExperience		= 0.0f;
// 		pWarpFISocket->CharacterDeadGameStartRoutine(TRUE, pWarpFISocket->m_character.HP, pWarpFISocket->m_character.DP, pWarpFISocket->m_character.SP);
// 
// 		INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY, T_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY, pSNotify, SendBuf);
// 		pSNotify->restoreClientIdx			= pWarpFISocket->GetCharacter()->ClientIndex;
// 		ms_pFieldIOCP->SendInRangeMessageAroundPosition(pWarpFISocket->GetCharacter()->PositionVector
// 			, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_RESTORE_NOTIFY), pWarpFISocket->GetCurrentFieldMapChannel());
// 
// 		EventResult_t ret = pWarpFISocket->WarpToMap(m_character.MapChannelIndex);	// 같은맵의 기본 워프게이트로 이동
// 		if (ret == EVENT_RESULT_BREAK)
// 		{
// 			SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_CANNOT_WARP
// 				, m_character.MapChannelIndex.MapIndex, m_character.MapChannelIndex.ChannelIndex, pWarpFISocket->m_character.CharacterName);
// 			return RES_BREAK;
// 		}
// 	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_GUILD(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_GUILD,
									MSG_FC_ITEM_USE_CARDITEM_GUILD, pRGuild);

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_GUILD
	if(this->CheckTradingItem(pRGuild->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_ITEM_TRADING, pRGuild->ItemUniqueNumber);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRGuild->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_NO_SUCH_ITEM, pRGuild->ItemUniqueNumber);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
	//if(DES_CASH_GUILD != pItemInfo->DestParameter1)
	if(DES_CASH_GUILD != pItemInfo->ArrDestParameter[0])
	{
		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
		//SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_RESTORE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}

	int nCurrentCapacity = 0;
	if(FALSE == ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommanderAndGetMemberCapacity(m_character.CharacterUniqueNumber, &nCurrentCapacity))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_NOT_GUILD_MASTER);
		return RES_BREAK;
	}
	//////////////////////////////////////////////////////////////////////////
	// 2008-05-28 by dhjin, EP3 여단 수정 사항 - 여단원 증가 캐쉬 아이템
//	if(nCurrentCapacity != SIZE_MAX_INITIAL_GUILD_CAPACITY)
//	{
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_GUILD_CARD_ALREADY_USING, nCurrentCapacity);
//		return RES_BREAK;
//	}
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if( (nCurrentCapacity+(int)pItemInfo->ParameterValue1) > SIZE_MAX_GUILD_CAPACITY)
	if( (nCurrentCapacity+(int)pItemInfo->ArrParameterValue[0]) > SIZE_MAX_GUILD_CAPACITY)
	{// 2008-05-28 by dhjin, EP3 여단 수정 사항 - 여단원 증가 캐쉬 아이템, 최대 길드원 수 넘어가는지 체크
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_GUILD, ERR_PROTOCOL_OVER_MEMBERCOUNT, nCurrentCapacity);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// IMServer로 아이템 사용을 전송한다 - DB에 업데이트는 IMServer에서 처리
	INIT_MSG_WITH_BUFFER(MSG_FI_CASH_USING_GUILD, T_FI_CASH_USING_GUILD, pSUingGuildCard, SendBuf);
	pSUingGuildCard->guildUID					= m_character.GuildUniqueNumber;
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	pSUingGuildCard->nIncreaseMemberCapacity	= (int)pItemInfo->ParameterValue1;
	pSUingGuildCard->nIncreaseMemberCapacity	= (int)pItemInfo->ArrParameterValue[0];

	pSUingGuildCard->CashPrice					= pItemInfo->CashPrice;				// 2008-05-28 by dhjin, EP3 여단 수정 사항 - 여단원 증가 캐쉬 아이템
	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CASH_USING_GUILD));

	INIT_MSG(MSG_FC_ITEM_USE_CARDITEM_GUILD_NOTIFY, T_FC_ITEM_USE_CARDITEM_GUILD_NOTIFY, pSGuildNotify, SendBuf);
	pSGuildNotify->notifyClientIdx			= m_character.ClientIndex;
	pSGuildNotify->guildUID					= m_character.GuildUniqueNumber;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf
		, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_GUILD_NOTIFY), m_pCurrentFieldMapChannel);
	
// 2005-05-11 by cmkwon, 카운터블로 수정중
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
//	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기
	ITEM_GENERAL tmpItemForLog = *pItemG;		
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_MONSTERSUMMON(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON,
									MSG_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, pRMonsterSummon);

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

// 2008-02-12 by cmkwon, IS_CITY_MAP_INDEX() 매크로를 포괄적인 도시맵인지 여부를 리턴 - 아래와 같이 수정
//  	if(IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex)
// 		|| IS_BAZAAR_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
  	if(IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
 	{// 2006-07-19 by cmkwon, 바자맵도 사용 불가
 		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
 		return RES_BREAK;
 	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON
	if(this->CheckTradingItem(pRMonsterSummon->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_ITEM_TRADING, pRMonsterSummon->ItemUniqueNumber);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMonsterSummon->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_NO_SUCH_ITEM, pRMonsterSummon->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(DES_CASH_MONSTER_SUMMON != pItemInfo->DestParameter1)
	if(DES_CASH_MONSTER_SUMMON != pItemInfo->ArrDestParameter[0])
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}

	if(FALSE == m_pCurrentFieldMapChannel->m_pFieldMapProject->IsValidTileForCreateMonster(&m_character.PositionVector))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_INVALID_POSITION);
		return RES_BREAK;
	}

	int nSummonUnitkind	= 0;
	int nRand			= rand()%4;
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 	switch(nRand)
// 	{
// 	case 0:		nSummonUnitkind = (int)pItemInfo->ParameterValue1;		break;
// 	case 1:		nSummonUnitkind = (int)pItemInfo->ParameterValue2;		break;
// 	case 2:		nSummonUnitkind = (int)pItemInfo->ParameterValue3;		break;
// 	default:
// 		{
// 			nSummonUnitkind = (int)pItemInfo->ParameterValue4;
// 		}
// 	}
	switch(nRand)
	{
	case 0:		nSummonUnitkind = (int)pItemInfo->ArrParameterValue[0];		break;
	case 1:		nSummonUnitkind = (int)pItemInfo->ArrParameterValue[1];		break;
	case 2:		nSummonUnitkind = (int)pItemInfo->ArrParameterValue[2];		break;
	default:
		{
			nSummonUnitkind = (int)pItemInfo->ArrParameterValue[3];
		}
	}

	if(0 == nSummonUnitkind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_NO_SUCH_MONSTER_INFO, nSummonUnitkind);
		return RES_BREAK;
	}
	ez_map<int, MONSTER_INFO>::iterator itrMon = ms_pFieldIOCP->m_mapMonsterInfo.find(nSummonUnitkind);
	if (itrMon == ms_pFieldIOCP->m_mapMonsterInfo.end())
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, ERR_PROTOCOL_NO_SUCH_MONSTER_INFO, nSummonUnitkind);
		return RES_BREAK;
	}

	if (m_pCurrentFieldMapChannel->m_pFieldMapProject->GetNPCServerStartFlag() == FALSE)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON, 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		= nSummonUnitkind;
	pMsgSummonMonster->MonsterTargetType1	= MONSTER_TARGETTYPE_NORMAL;
	pMsgSummonMonster->TargetTypeData1		= 0;
	pMsgSummonMonster->CltIdxForTargetType1	= 0;
	pMsgSummonMonster->NumOfMonster			= 1;
	pMsgSummonMonster->Position				= m_character.PositionVector;

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

	m_pCurrentFieldMapChannel->Send2NPCServerW(SendBuf, MSG_SIZE(MSG_FN_ADMIN_SUMMON_MONSTER));

	INIT_MSG(MSG_FC_ITEM_USE_CARDITEM_MONSTERSUMMON_NOTIFY, T_FC_ITEM_USE_CARDITEM_MONSTERSUMMON_NOTIFY, pSNotify, SendBuf);
	pSNotify->notifyClientIdx				= m_character.ClientIndex;
	pSNotify->notifyItemNum					= pItemInfo->ItemNum;
	pSNotify->summonMonsterUnitKind			= nSummonUnitkind;
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf
		, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_MONSTERSUMMON_NOTIFY), m_pCurrentFieldMapChannel);

// 2005-05-11 by cmkwon, 카운터블로 수정중
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);				// 사용 아이템 로그 추가
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
//	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);	// Item 삭제하기
	ITEM_GENERAL tmpItemForLog = *pItemG;		
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME,
									MSG_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, pRChangeCharacterName);

	// 2009-01-23 by cmkwon, 터키 i,I 문자 문제 처리 - 캐릭터명 변경카드 사용시 캐릭터명 처리
	LowercaseOnly_i_forTurkish(pRChangeCharacterName->szChangeCharacterName, SIZE_MAX_CHARACTER_NAME);

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}
	
	if(NULL != m_pFieldParty)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_CANNOT_USEITEM_IN_PARTY);
		return RES_BREAK;
	}

	if(this->ms_pFieldIOCP->m_InflWarManager.CheckLeaderCandidateUser(this->m_character.AccountUniqueNumber, this->m_character.CharacterUniqueNumber))
	{// 2007-11-20 by dhjin, 등록한 유저
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_REQ_REG_LEADER_CANDIDATE);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME
	if(this->CheckTradingItem(pRChangeCharacterName->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_ITEM_TRADING, pRChangeCharacterName->ItemUniqueNumber);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRChangeCharacterName->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_NO_SUCH_ITEM, pRChangeCharacterName->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(DES_CASH_CHANGE_CHARACTERNAME != pItemInfo->DestParameter1)
	if(DES_CASH_CHANGE_CHARACTERNAME != pItemInfo->ArrDestParameter[0])
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}

	if(0 == strncmp(pRChangeCharacterName->szChangeCharacterName, "", SIZE_MAX_CHARACTER_NAME))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_INVALID_CHARACTER_NAME);
		return RES_BREAK;
	}
	
	if(FALSE == CAtumSJ::IsValidCharacterName(pRChangeCharacterName->szChangeCharacterName, g_pFieldGlobal->GetLanguageType()))
	{// 2006-06-14 by cmkwon
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_INVALID_CHARACTERNAME);
		return RES_BREAK;
	}

	if (!g_pFieldGlobal->CheckProhibitedName(pRChangeCharacterName->szChangeCharacterName))
	{// 2006-03-14 by cmkwon, 캐릭터명 변경시도 체크
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, ERR_PROTOCOL_INVALID_CHARACTER_NAME, 0, 0, pRChangeCharacterName->szChangeCharacterName);
		return RES_BREAK;
	}

	Err_t errCode = ms_pFieldIOCP->m_pFieldODBC->ChangeCharacterName(m_character.CharacterUniqueNumber, m_character.CharacterName, pRChangeCharacterName->szChangeCharacterName);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME, errCode);
		return RES_BREAK;
	}

	char szOldCharName[SIZE_MAX_CHARACTER_NAME];
	STRNCPY_MEMSET(szOldCharName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(m_character.CharacterName, pRChangeCharacterName->szChangeCharacterName, SIZE_MAX_CHARACTER_NAME);
	
	///////////////////////////////////////////////////////////////////////////////
	// 1. PreServer로 아이템 사용을 전송한다
	INIT_MSG_WITH_BUFFER(MSG_FP_CASH_CHANGE_CHARACTERNAME, T_FP_CASH_CHANGE_CHARACTERNAME, pS2PChangeCharName, SendBuf);
	STRNCPY_MEMSET(pS2PChangeCharName->szAccName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(pS2PChangeCharName->szChangedCharName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	ms_pFieldIOCP->m_pPreWinSocket->Write(SendBuf, MSG_SIZE(MSG_FP_CASH_CHANGE_CHARACTERNAME));

	///////////////////////////////////////////////////////////////////////////////
	// 2. IMServer로 아이템 사용을 전송한다
	INIT_MSG(MSG_FI_CASH_USING_CHANGE_CHARACTERNAME, T_FI_CASH_USING_CHANGE_CHARACTERNAME, pSChangeCharName, SendBuf);
	pSChangeCharName->charUID					= m_character.CharacterUniqueNumber;
	STRNCPY_MEMSET(pSChangeCharName->szChangedCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	ms_pFieldIOCP->m_pIMWinSocket->Write(SendBuf, MSG_SIZE(MSG_FI_CASH_USING_CHANGE_CHARACTERNAME));


	///////////////////////////////////////////////////////////////////////////////
	// 3. 아이템 정리
// 2005-05-11 by cmkwon, 카운터블로 수정중
	// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
	CAtumLogSender::SendLogMessageITEMUseChangeCharacterName(this, pItemG, szOldCharName);	// 아이템 로그 남기기
#endif	//#ifdef S_FULL_LOG_JHSEOL
	// end 2012-08-30 by jhseol, 풀로그 남기기
//	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);					// Item 삭제하기
	ITEM_GENERAL tmpItemForLog = *pItemG;		
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseChangeCharacterName(this, &tmpItemForLog, szOldCharName);		// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 4. CFieldIOCP 데이타 처리
	mt_auto_lock mtName(&ms_pFieldIOCP->m_mapCharacterName);
	char tmCharacterName[SIZE_MAX_CHARACTER_NAME];
	ms_pFieldIOCP->m_mapCharacterName.deleteNoLock(GGetLowerCase(tmCharacterName, szOldCharName, SIZE_MAX_CHARACTER_NAME));
	ms_pFieldIOCP->m_mapCharacterName.insertNoLock(GGetLowerCase(tmCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME), this);
	mtName.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 5. 주위 캐릭에게 전송
	INIT_MSG(MSG_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME_NOTIFY
		, T_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME_NOTIFY, pSChangeCharacterNameNotify, SendBuf);
	pSChangeCharacterNameNotify->notifyClientIdx	= m_character.ClientIndex;
	STRNCPY_MEMSET(pSChangeCharacterNameNotify->szChangedCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(pSChangeCharacterNameNotify->szOriginCharacterName, szOldCharName, SIZE_MAX_CHARACTER_NAME);
	ms_pFieldIOCP->SendInRangeMessageAroundPosition(m_character.PositionVector, SendBuf
		, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME_NOTIFY), m_pCurrentFieldMapChannel);

	if(IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
	{
		///////////////////////////////////////////////////////////////////////////////
		// 6. 모든 여단원에게 전송
		ms_pFieldIOCP->SendMessageToGuildMembers(SendBuf
			, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_CHANGECHARACTERNAME_NOTIFY), m_character.GuildUniqueNumber, m_character.CharacterUniqueNumber);
	}

	// 2013-01-16 by jhseol, 지도자 권한에서 케릭터 이름 변경시 통제탑 정보도 실시간 변경
	if( COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_1|RACE_INFLUENCE_SUBLEADER_2) )
	{
		this->ms_pFieldIOCP->m_InflWarManager.LeaderChangeName(m_character.InfluenceType, m_character.Race, m_character.CharacterName);
	}
	// end 2013-01-16 by jhseol, 지도자 권한에서 케릭터 이름 변경시 통제탑 정보도 실시간 변경
	
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE,
									MSG_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE, pRSkillInit);

///////////////////////////////////////////////////////////////////////////////
// 2005-04-07 by cmkwon, 미구현
//	
//	if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_DEAD_MASK))
//	{
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE, ERR_PROTOCOL_CANNOT_USE_ITEM);
//		return RES_BREAK;
//	}
//
//	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
//	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRSkillInit->ItemUniqueNumber);
//	if (NULL == pItemG
//		|| NULL == pItemG->ItemInfo)
//	{
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE, ERR_PROTOCOL_NO_SUCH_ITEM, pRSkillInit->ItemUniqueNumber);
//		return RES_BREAK;
//	}
//	ITEM *pItemInfo = pItemG->ItemInfo;
//	if(ITEMKIND_CARD != pItemInfo->Kind)
//	{
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
//		return RES_BREAK;
//	}
//
//	if(DES_CASH_SKILL_INITIALIZE != pItemInfo->DestParameter1)
//	{
//		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_SKILLINITIALIZE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->DestParameter1);
//		return RES_BREAK;
//	}
//
//	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
//	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기
//	igLock.auto_unlock_cancel();
	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE,
									MSG_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, pRChangeFace);

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-21 by cmkwon, PilotFace 변경 카드 구현 - 
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_INVALID_CHARACTER, 0, 100);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(FALSE == m_character.CharacterMode)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED, 0, 101);
		return RES_BREAK;
	}

	if(FALSE == CAtumSJ::IsValidPiotFace(pRChangeFace->pilotFace))
	{// 2007-11-21 by cmkwon, 유효하지 않음 PilotFace 이다
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_DB_INVALID_PARAMETER, pRChangeFace->pilotFace, 102);
		return RES_BREAK;
	}

	if(m_character.PilotFace == pRChangeFace->pilotFace)
	{// 2007-11-21 by cmkwon, 현재 자신의 PilotFace와 같은지 체크
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_DB_INVALID_PARAMETER, pRChangeFace->pilotFace, 103);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE
	if(this->CheckTradingItem(pRChangeFace->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_ITEM_TRADING, pRChangeFace->ItemUniqueNumber);
		return RES_BREAK;
	}


	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRChangeFace->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_PROTOCOL_NO_SUCH_ITEM, pRChangeFace->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(DES_CASH_CHANGE_PILOTFACE != pItemInfo->DestParameter1)
	if(DES_CASH_CHANGE_PILOTFACE != pItemInfo->ArrDestParameter[0])
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}

	m_character.PilotFace	= pRChangeFace->pilotFace;		// 2007-11-22 by cmkwon, 설정

	ITEM_GENERAL tmpItemForLog = *pItemG;		
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);					// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);		// Item 삭제하기
	igLock.auto_unlock_cancel();

	// 2007-11-21 by cmkwon, DB에 Update
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdatePilotFace, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber, pRChangeFace->pilotFace);

	// 2007-11-21 by cmkwon, 주위의 유저들에게 바뀐 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE_NOTIFY, T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE_NOTIFY, pSMsg, SendBuf);
	pSMsg->notifyClientIdx	= m_character.ClientIndex;
	pSMsg->notifyItemNum	= pItemInfo->ItemNum;
	pSMsg->pilotFace		= pRChangeFace->pilotFace;
	ms_pFieldIOCP->SendInRangeMessageAroundCharacter(m_character.ClientIndex, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE_NOTIFY)
														, GetCurrentFieldMapChannel(), TRUE, m_pCurrentFieldMapChannel->GetUserVisibleDiameterW());
	return RES_RETURN_TRUE;
}

// 2014-06-10 by bckim, 세력변경 아이템
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE,
		MSG_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, pRChangeInfl);
	
///////////////////////////////////////////////////////////////////////////////
	if (FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_INVALID_CHARACTER, 0, 100);
		return RES_BREAK;
	}
	
	if(TRUE == g_pFieldGlobal->IsArenaServer()) 
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}
	
	if(FALSE == m_character.CharacterMode)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_CHARACTER_MODE_NOT_MATCHED, 0, 101);
		return RES_BREAK;
	}	

	if( FALSE == IS_INFLUENCE_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex))		// 현재 맵이 도시맵인지 확인 // "도시 외부에서는 사용이 불가능합니다."
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_REQ_NOT_CITY_MAP_CHANNEL, m_character.MapChannelIndex.MapIndex, 102);
		return RES_BREAK;
	}
	
	if ( FALSE == IS_VALID_INFLUENCE_TYPE(m_character.InfluenceType))		// 유효한 세력인지 확인 
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_DB_INVALID_PARAMETER, m_character.InfluenceType, 103);
		return RES_BREAK;
	}
	
	if ( IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType))		// 노말 세력이 아닌지 확인 
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_REQ_CHOOSE_INFLUENCE_TYPE, m_character.InfluenceType, 104);
		return RES_BREAK;
	}

	if( 0 != m_character.GuildUniqueNumber)	// 여단원이면 사용안됨. // "여단에 소속되어 있는 유저는 사용할 수 없습니다."
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_GUILD_MEMBER_ALREADY_EXISTS, m_character.GuildUniqueNumber, 105);
		return RES_BREAK;
	}
	
	// 세력초기화 전까지 한번만 사용하게 
	//if( 0 != m_NumberOfChangeInfl && FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))	// 관리자는 허용
	if( 0 != m_NumberOfChangeInfl )
	{	
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_CANNOT_CHOOSE_INFLUENCE_TYPE, m_character.GuildUniqueNumber, 107);
		return RES_BREAK;
	}	
	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_CARDITEM_CHANGEPILOTFACE
	if(this->CheckTradingItem(pRChangeInfl->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_ITEM_TRADING, pRChangeInfl->ItemUniqueNumber);
		return RES_BREAK;
	}
	///////////////////////////////////////////////////////////////////////////////

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = new ITEM_GENERAL; 
	memcpy(pItemG,m_ItemManager.GetItemGeneralByUID(pRChangeInfl->ItemUniqueNumber),sizeof(ITEM_GENERAL));

	if (NULL == pItemG || NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_NO_SUCH_ITEM, pRChangeInfl->ItemUniqueNumber);
		SAFE_DELETE(pItemG);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_CARD != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		SAFE_DELETE(pItemG);
		return RES_BREAK;
	}
	
	if(DES_CASH_CHANGE_INFLUENCE != pItemInfo->ArrDestParameter[0])
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_NO_SUCH_DES_PARAM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		SAFE_DELETE(pItemG);
		return RES_BREAK;
	}

	int tempPercent = (int)(pItemInfo->ArrParameterValue[0]);
	INT tempPointGap = ms_pFieldIOCP->m_InflWarManager.m_nBeforeContributionPointGap;
	
	//if(  0 == tempPointGap )	// 세력차이가 없음	// "세력 간 균형이 치우치지 않아 사용이 불가능합니다."
	if( abs(tempPointGap) <= 15 )	// 2014-07-03 by bckim, 세력변경 아이템 15% 이하에서는 사용되지 않게	// 2014-08-01 by bckim, 세력변경아이템 버그 수정 
	{
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_REQ_INFLUENCE_BALANCED, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		SAFE_DELETE(pItemG);
		return RES_BREAK;
	}

	if( ( 0 < tempPointGap && IS_VCN_INFLUENCE_TYPE(m_character.InfluenceType) ) 	// 알링턴 우세세력이고 자신은 바이제니유  
		|| ( 0 > tempPointGap && IS_ANI_INFLUENCE_TYPE(m_character.InfluenceType) )  	// 바이제니유 우세세력 자신은 알링턴 		// 2014-08-01 by bckim, 세력변경아이템 버그 수정 
		|| ( tempPercent > abs(tempPointGap) )
		)											// 세력차이가 
	{		
		SendErrorMessage(T_FC_ITEM_USE_CARDITEM_CHANGE_INFLUENCE, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		SAFE_DELETE(pItemG);
		return RES_BREAK;
	}
	
	igLock.auto_unlock_cancel();
	
	// 변경된 세력으로 바꿈. 
	if ( IS_VCN_INFLUENCE_TYPE(m_character.InfluenceType))
	{
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AccountInflChange, this, 0, NULL, pItemG, (INT64)m_character.AccountUniqueNumber, (INT64)INFLUENCE_TYPE_ANI);
	}
	if ( IS_ANI_INFLUENCE_TYPE(m_character.InfluenceType))
	{
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_AccountInflChange, this, 0, NULL, pItemG, (INT64)m_character.AccountUniqueNumber, (INT64)INFLUENCE_TYPE_VCN);
	}

	return RES_RETURN_TRUE;
}
// End. 2014-06-10 by bckim, 세력변경 아이템




///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_BUFF(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-21 ~ 2006-04-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_BUFF(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_INFLUENCE_BUFF,
									MSG_FC_ITEM_USE_INFLUENCE_BUFF, pRInflCard);
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

//////////////////////////////////////////////////////////////////////////
// 2009-01-05 by dhjin, 미션마스터 - 편대 버프 아이템 추가 - 밑으로 이동
//	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
//	{
//		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_CANNOT_USE_ITEM);
//		return RES_BREAK;
//	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_INFLUENCE_BUFF
	if(this->CheckTradingItem(pRInflCard->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_ITEM_TRADING, pRInflCard->ItemUniqueNumber);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRInflCard->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_NO_SUCH_ITEM, pRInflCard->ItemUniqueNumber);
		return RES_BREAK;
	}
	if(ITEMKIND_INFLUENCE_BUFF != pItemG->ItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemG->ItemInfo->ItemNum, pItemG->ItemInfo->Kind);
		return RES_BREAK;
	}
	ITEM *pLinkItem = ms_pFieldIOCP->GetItemInfo(pItemG->ItemInfo->LinkItem);
	if(NULL == pLinkItem
		|| FALSE == COMPARE_BIT_FLAG(pLinkItem->ItemAttribute, ITEM_ATTR_TIME_LIMITE|ITEM_ATTR_DELETED_TIME_LIMITE_AFTER_USED))		// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_INFLUENCE_BUFF
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pLinkItem);
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_ALREADY_USE_ITEMPARAM, pLinkItem->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}

	//////////////////////////////////////////////////////////////////////////
	// 2009-01-05 by dhjin, 미션마스터 - 편대 버프 아이템 추가
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	if(DES_ITEM_BUFF_INFLUENCE == pItemG->ItemInfo->DestParameter1)
	if(DES_ITEM_BUFF_INFLUENCE == pItemG->ItemInfo->ArrDestParameter[0])
	{// 지도자 세력 버프 아이템 유저 관련 체크
		if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
		{
			SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_CANNOT_USE_ITEM);
			return RES_BREAK;
		}
	}
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
//	else if(DES_ITEM_BUFF_PARTY == pItemG->ItemInfo->DestParameter1)
	else if(DES_ITEM_BUFF_PARTY == pItemG->ItemInfo->ArrDestParameter[0])
	{// 편대 세력 버프 아이템 유저 관련 체크
		CFieldParty *pFParty = this->m_pFieldParty;
		if (pFParty == NULL)
		{
			SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_BUFF, ERR_PROTOCOL_NO_SUCH_PARTY);
			return RES_BREAK;			
		}
	}

	ITEM_GENERAL tmpItemForLog = *pItemG;		// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();

	//////////////////////////////////////////////////////////////////////////
	// 2009-01-05 by dhjin, 미션마스터 - 편대 버프 아이템 추가 - 밑과 같이 수정
//	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK, T_FC_ITEM_USE_INFLUENCE_BUFF_OK, pSBuffOK, SendBuf);
//	pSBuffOK->ItemUniqueNumber		= pRInflCard->ItemUniqueNumber;
//	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK));
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK, T_FC_ITEM_USE_INFLUENCE_BUFF_OK, pSBuffOK, SendBuf);
	pSBuffOK->ItemNum		= tmpItemForLog.ItemInfo->ItemNum;
	STRNCPY_MEMSET(pSBuffOK->ItemUseCharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);	

	///////////////////////////////////////////////////////////////////////////////
	// 2006-04-21 by cmkwon, 같은 
	//////////////////////////////////////////////////////////////////////////
	// 2009-01-05 by dhjin, 미션마스터 - 편대 버프 아이템 추가 - 밑과 같이 수정
//	ms_pFieldIOCP->InsertTimeLimiteItemAllCharacterSameMapChannel(pLinkItem, m_character.MapChannelIndex, m_character.InfluenceType);
// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 	if(DES_ITEM_BUFF_INFLUENCE == tmpItemForLog.ItemInfo->DestParameter1)
// 	{
// 		ms_pFieldIOCP->InsertTimeLimiteItemAllCharacterSameMapChannel(pLinkItem, m_character.MapChannelIndex, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK), m_character.InfluenceType);
// 	}
// 	else if(DES_ITEM_BUFF_PARTY == tmpItemForLog.ItemInfo->DestParameter1)
// 	{
// 		ms_pFieldIOCP->InsertTimeLimiteItemPartyMember(pLinkItem, this, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK));
// 	}
	if(DES_ITEM_BUFF_INFLUENCE == tmpItemForLog.ItemInfo->ArrDestParameter[0])
	{
		ms_pFieldIOCP->InsertTimeLimiteItemAllCharacterSameMapChannel(pLinkItem, m_character.MapChannelIndex, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK), m_character.InfluenceType);
	}
	else if(DES_ITEM_BUFF_PARTY == tmpItemForLog.ItemInfo->ArrDestParameter[0])
	{
		ms_pFieldIOCP->InsertTimeLimiteItemPartyMember(pLinkItem, this, SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_BUFF_OK));
	}
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_GAMEEVENT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-04-21 ~ 2006-04-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_GAMEEVENT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_INFLUENCE_GAMEEVENT,
									MSG_FC_ITEM_USE_INFLUENCE_GAMEEVENT, pRInflEvent);
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER))
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_PROTOCOL_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_INFLUENCE_GAMEEVENT
	if(this->CheckTradingItem(pRInflEvent->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_ITEM_TRADING, pRInflEvent->ItemUniqueNumber);
		return RES_BREAK;
	}

	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRInflEvent->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_PROTOCOL_NO_SUCH_ITEM, pRInflEvent->ItemUniqueNumber);
		return RES_BREAK;
	}
	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_INFLUENCE_GAMEEVENT != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 아래와 같이 수정 함
	//if(ms_pFieldIOCP->m_gameEventManager.IsDoingAllGameEvent(m_character.InfluenceType))
	if(ms_pFieldIOCP->m_gameEventManager.IsProgressGameEventGroup(m_character.InfluenceType, GAME_EVENT_GROUP_ITEM))
	{// 2006-04-21 by cmkwon, 세력별 게임이벤트가 진행중이면 아이템 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_DOING_GAMEEVENT);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_INFLUENCE_GAMEEVENT
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pItemInfo);
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_INFLUENCE_GAMEEVENT, ERR_ALREADY_USE_ITEMPARAM, pItemInfo->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}


	ITEM_GENERAL tmpItemForLog = *pItemG;		// 주의: only 로그용! 로그를 남길 때는 개수를 0으로 만들어야 하므로 임시로 이 변수를 사용한다.
	tmpItemForLog.CurrentCount--;
	CAtumLogSender::SendLogMessageITEMUseITEM(this, &tmpItemForLog);			// 사용 아이템 로그 추가
	m_ItemManager.UpdateItemCountByPointer(pItemG, -1, IUT_USE_ITEM);			// Current 수정하기
	igLock.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_INFLUENCE_GAMEEVENT_OK, T_FC_ITEM_USE_INFLUENCE_GAMEEVENT_OK, pSGEventOK, SendBuf);
	pSGEventOK->ItemUniqueNumber		= pRInflEvent->ItemUniqueNumber;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_INFLUENCE_GAMEEVENT_OK));

	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[Notify]: GAME_EVENT_GROUP_ITEM start ! %s ItemNum(%d)\r\n", GetCharacterString(GetCharacter(), string()), pItemInfo->ItemNum);

	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - CGameEventManager::StartGameEvent() 함수 인자 추가(, EN_GAME_EVENT_GROUP i_enGameEvGroup/*=GAME_EVENT_GROUP_HAPPYHOUR*/)
// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 아래와 같이 수정 함.
//	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter1, pItemInfo->ParameterValue1, pItemInfo->Time/(60*1000), 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
//	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter2, pItemInfo->ParameterValue2, pItemInfo->Time/(60*1000), 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
//	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter3, pItemInfo->ParameterValue3, pItemInfo->Time/(60*1000), 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -	
//	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter4, pItemInfo->ParameterValue4, pItemInfo->Time/(60*1000), 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter1, pItemInfo->ParameterValue1, CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(pItemInfo)/60, 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
// 	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter2, pItemInfo->ParameterValue2, CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(pItemInfo)/60, 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
// 	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter3, pItemInfo->ParameterValue3, CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(pItemInfo)/60, 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -	
// 	ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->DestParameter4, pItemInfo->ParameterValue4, CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(pItemInfo)/60, 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);		// 2008-03-14 by dhjin, Level별 해피아워 이벤트 구현 -
	for(int i=0; i < SIZE_MAX_DESPARAM_COUNT_IN_ITEM; i++)
	{
		// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_GAMEEVENT#, 
		ms_pFieldIOCP->m_gameEventManager.StartGameEvent((EN_GAME_EVENT_TYPE)pItemInfo->ArrDestParameter[i], pItemInfo->ArrParameterValue[i], CAtumSJ::GetTimeMinuteByItemKind8ItemAttribute(pItemInfo, TIME_TERM_EVENT), 1, CHARACTER_MAX_LEVEL, m_character.InfluenceType, GAME_EVENT_GROUP_ITEM);
	}
	
	// 2008-05-20 by cmkwon, 모든 이벤트(HappyHoure,MotherShip,Item) 그룹 동시에 가능하게 - 해당 세력 유저에게 전송
	INIT_MSG(MSG_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO_OK, T_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO_OK, pSHappy, SendBuf);
	pSHappy->byStateType		= GAME_EVENT_GROUP_ITEM_START;
	pSHappy->byInfluenceType4	= m_character.InfluenceType;
	pSHappy->StartATime.SetCurrentDateTime(TRUE);
	pSHappy->EndATime			= pSHappy->StartATime;
// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 아래와 같이 수정 함.
//	pSHappy->EndATime.AddDateTime(0, 0, 0, 0, pItemInfo->Time/(60*1000));
	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::Process_FC_ITEM_USE_INFLUENCE_GAMEEVENT#, 
	pSHappy->EndATime.AddDateTime(0, 0, 0, 0, CAtumSJ::GetTimeMinuteByItemKind8ItemAttribute(pItemInfo, TIME_TERM_EVENT));
	pSHappy->fEXPRate2			= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_EXP);
	pSHappy->fSPIRate2			= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_SPI);
	pSHappy->fEXPRepairRate2	= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_EXP_NO_DOWN);
	pSHappy->fDropItemRate2		= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_DROP_ITEM);
	pSHappy->fDropRareRate2		= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_DROP_REAR_ITEM);
	pSHappy->fWarPointRate2		= pItemInfo->GetParameterValue(GAME_EVENT_TYPE_WARPOINT);
	ms_pFieldIOCP->SendMessageToAllClients(SendBuf, MSG_SIZE(MSG_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO_OK), pSHappy->byInfluenceType4);

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_RANDOMBOX(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-08-10 ~ 2006-08-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_RANDOMBOX(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_RANDOMBOX,
									MSG_FC_ITEM_USE_RANDOMBOX, pRMsg);
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_RANDOMBOX
	if(this->CheckTradingItem(pRMsg->ItemUID))
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, 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_RANDOMBOX, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUID);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemG->ItemInfo;
	if(ITEMKIND_RANDOMBOX != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	
	// 2014-09-17 by bckim, 인피니티에서 랜덤박스 개봉불가
	if(TRUE == g_pFieldGlobal->IsArenaServer())
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVALID_ITEM_KIND, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}
	// End. 2014-09-17 by bckim, 인피니티에서 랜덤박스 개봉불가


	///////////////////////////////////////////////////////////////////////////////
	// 2010-01-18 by cmkwon, 아이템 사용시 Parameter 중복 체크 시스템 구현 - T_FC_ITEM_USE_RANDOMBOX
	ITEM *pUsingItemInfo = this->CheckItemParamOverlap(pItemInfo);
	if(pUsingItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_ALREADY_USE_ITEMPARAM, pItemInfo->ItemNum, pUsingItemInfo->ItemNum);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-02-10 by cmkwon, 캡슐 사용시 렙제 체크 루틴 추가 - 
	if(0 != pItemInfo->ReqMinLevel
		&& pItemInfo->ReqMinLevel > m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, m_character.Level, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}
	if(0 != pItemInfo->ReqMaxLevel
		&& pItemInfo->ReqMaxLevel < m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED, m_character.Level, pItemInfo->ReqMaxLevel);
		return RES_BREAK;
	}


	// 2006-09-29 by cmkwon, 보조스킬아이템 추가됨
	INT arrProbability[RANDOMBOX_RESULT_KIND_COUNT];
	MEMSET_ZERO(arrProbability, sizeof(arrProbability[0])*RANDOMBOX_RESULT_KIND_COUNT);

// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
// 	arrProbability[RANDOMBOX_RESULT_ITEM]	= pItemInfo->DestParameter1;
// 	arrProbability[RANDOMBOX_RESULT_SPI]	= arrProbability[RANDOMBOX_RESULT_ITEM] + pItemInfo->DestParameter2;
// 	arrProbability[RANDOMBOX_RESULT_EXP]	= arrProbability[RANDOMBOX_RESULT_SPI] + pItemInfo->DestParameter3;
// 	arrProbability[RANDOMBOX_RESULT_SKILL_SUPPORT_ITEM]	= arrProbability[RANDOMBOX_RESULT_EXP] + pItemInfo->DestParameter4;
	arrProbability[RANDOMBOX_RESULT_ITEM]	= pItemInfo->ArrDestParameter[0];
	arrProbability[RANDOMBOX_RESULT_SPI]	= arrProbability[RANDOMBOX_RESULT_ITEM] + pItemInfo->ArrDestParameter[1];
	arrProbability[RANDOMBOX_RESULT_EXP]	= arrProbability[RANDOMBOX_RESULT_SPI] + pItemInfo->ArrDestParameter[2];
	arrProbability[RANDOMBOX_RESULT_SKILL_SUPPORT_ITEM]	= arrProbability[RANDOMBOX_RESULT_EXP] + pItemInfo->ArrDestParameter[3];

	int nRandBoxResult	= RANDOMBOX_RESULT_FAIL;
	int nRandomNum		= RANDI(0, 99);
	for(int i=RANDOMBOX_RESULT_ITEM; i < RANDOMBOX_RESULT_KIND_COUNT; i++)
	{
		if(nRandomNum < arrProbability[i])
		{
			nRandBoxResult	= i;
			break;
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_RANDOMBOX_OK, T_FC_ITEM_USE_RANDOMBOX_OK, pSRandBoxOK, SendBuf);
	STRNCPY_MEMSET(pSRandBoxOK->szCharacterName0, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	pSRandBoxOK->nRandomBoxResult		= nRandBoxResult;
	switch(pSRandBoxOK->nRandomBoxResult)
	{
	case RANDOMBOX_RESULT_ITEM:
	case RANDOMBOX_RESULT_SKILL_SUPPORT_ITEM:		// 2006-09-29 by cmkwon
		{// 2007-05-11 by cmkwon, 미스테리아이템캡슐 시스템 수정

// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 여러개 아이템을 받을 수 있게 수정한다.
// 			MYSTERY_ITEM_DROP *pMysterItemDropInfo = ms_pFieldIOCP->GetMysteryDropItem(this, pItemInfo->LinkItem);
// 			if(NULL == pMysterItemDropInfo)
// 			{
// 				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_NO_SUCH_ITEM, pItemInfo->LinkItem);
// 				return RES_BREAK;
// 			}

			///////////////////////////////////////////////////////////////////////////////
			// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 아래와 같이 수정 함.
			vectMYSTERY_ITEM_DROPPtr tmVectMysteryDropItemList;
			ms_pFieldIOCP->GetMysteryDropItem(&tmVectMysteryDropItemList, this, pItemInfo->LinkItem, COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_PACKAGE_ITEM));
			if(tmVectMysteryDropItemList.empty())
			{
 				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_NO_SUCH_ITEM, pItemInfo->LinkItem);
 				return RES_BREAK;
			}

			///////////////////////////////////////////////////////////////////////////////
			// 2009-10-08 by cmkwon, 필드창고 캐쉬 아이템 시스템 보완 - T_FC_ITEM_USE_RANDOMBOX, 캡슐로 보완 처리, 캡슐 사용 가능 여부 체크
			{
				int nItemCount=0;// 2013-09-11 by jekim, 인벤토리가 꽉차도 프리미엄 아이템은 추가 가능하게 수정
				vectMYSTERY_ITEM_DROPPtr::iterator itr(tmVectMysteryDropItemList.begin());
				for(; itr != tmVectMysteryDropItemList.end(); itr++)
				{
					MYSTERY_ITEM_DROP *pMysterItemDropInfo = *itr;
					ITEM *pAddItemInfo	= ms_pFieldIOCP->GetItemInfo(pMysterItemDropInfo->DropItemNum);
					if(NULL == pAddItemInfo)
					{
						SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_CASH_INVALID_ITEM_INFORMATION, pMysterItemDropInfo->DropItemNum);
						return RES_BREAK;
					}

					if(pAddItemInfo->IsExistDesParam(DES_FIELD_STORE)
						&& this->m_ItemManager.IsUseableFieldStore())
					{
						char szErrTxt[1024];
						sprintf(szErrTxt, "can't use capsule because already use FieldStore item!! ItemNum(%d) UsedFlag(%d)", pAddItemInfo->ItemNum, m_ItemManager.IsUseableFieldStore());
						SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_ALREADY_HAVE_ITEM, pAddItemInfo->ItemNum, this->m_ItemManager.IsUseableFieldStore(), szErrTxt);
						return RES_BREAK;
					}
					// 2013-09-11 by jekim, 인벤토리가 꽉차도 프리미엄 아이템은 추가 가능하게 수정
					if( FALSE == COMPARE_BIT_FLAG(pAddItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
					{
						nItemCount++;
					}
					// end 2013-09-11 by jekim, 인벤토리가 꽉차도 프리미엄 아이템은 추가 가능하게 수정
				}
				// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 인벤토리 체크
				// 2009-11-02 by cmkwon, 캐쉬(인벤/창고 확장) 아이템 추가 구현 - 
				// 2013-09-11 by jekim, 인벤토리가 꽉차도 프리미엄 아이템은 추가 가능하게 수정
				if(nItemCount && m_ItemManager.GetInventoryItemCounts() + nItemCount > m_ItemManager.GetMaxInventoryCount())
				{
					SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVENTORY_FULL_ITEM, m_ItemManager.GetInventoryItemCounts(), tmVectMysteryDropItemList.size());
					return RES_BREAK;
				}
				// end 2013-09-11 by jekim, 인벤토리가 꽉차도 프리미엄 아이템은 추가 가능하게 수정
			}

			int nInsertedItemCounts = 0;	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
			vectMYSTERY_ITEM_DROPPtr::iterator itr(tmVectMysteryDropItemList.begin());
			for(; itr != tmVectMysteryDropItemList.end(); itr++)
			{
				MYSTERY_ITEM_DROP *pMysterItemDropInfo = *itr;

				ITEM *pAddItemInfo	= ms_pFieldIOCP->GetItemInfo(pMysterItemDropInfo->DropItemNum);
				if(NULL == pAddItemInfo)
				{
					SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_NO_SUCH_ITEM, pMysterItemDropInfo->DropItemNum);
					// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
					//return RES_BREAK;
					continue;
				}

				pSRandBoxOK->nResultItemNum0	= pAddItemInfo->ItemNum;
				pSRandBoxOK->n64ResultCounts	= RANDI(pMysterItemDropInfo->MinCount, pMysterItemDropInfo->MaxCount);
				if(0 >= pSRandBoxOK->n64ResultCounts)
				{
					SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVALID_ITEM_COUNT, pMysterItemDropInfo->DropItemNum);
					// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
					//return RES_BREAK;
					continue;
				}

				// 2009-10-28 by cmkwon, 러키캡슐로 프리미엄 아이템 추가 가능하게 수정 - 
				if(COMPARE_BIT_FLAG(pAddItemInfo->ItemAttribute, ITEM_ATTR_CASH_ITEM_PREMIUM_CARD))
				{
					pSRandBoxOK->nResultItemNum0	= pAddItemInfo->ItemNum;
					pSRandBoxOK->n64ResultCounts	= 1;

					///////////////////////////////////////////////////////////////////////////////
					// 2009-10-28 by cmkwon, 러키캡슐로 프리미엄 아이템 추가 가능하게 수정 - 프리미엄 아이템을 추가
					Err_t nRetedErr = this->m_ItemManager.CashInsertPremiumCard(pAddItemInfo);
					if(ERR_NO_ERROR != nRetedErr)
					{
						SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_CASH_PREMIUM_CARD_NOT_YET_BUY_STATE, pAddItemInfo->ItemNum, nRetedErr);
						continue;
					}

					nInsertedItemCounts++;		// 2010-01-12 by cmkwon, 러키 캡슐 프리미엄 아이템 버그 수정 - 
				}
				else
				{
					if(FALSE == IS_COUNTABLE_ITEM(pAddItemInfo->Kind))
					{// 2007-05-11 by cmkwon, 넌카운터블 아이템
						pSRandBoxOK->n64ResultCounts = min(pSRandBoxOK->n64ResultCounts, 10);			// 2007-05-11 by cmkwon, 넌카운터블 아이템은 최대 10개
						for(int i=0; i < pSRandBoxOK->n64ResultCounts; i++)
						{
							ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
							pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
							pAddItemG->Possess				= m_character.CharacterUniqueNumber;
							pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
							
							// 2010-04-20 by cmkwon, 신규 러키 머신 구현 -
							//if(IS_WEAPON(pAddItemInfo->Kind))
							if(IS_RARE_TARGET_ITEMKIND(pAddItemInfo->Kind))
							{// 2009-10-28 by cmkwon, 체크 추가

								this->ApplyGambleRareFix(pAddItemG, pMysterItemDropInfo->PrefixProbability, pMysterItemDropInfo->SuffixProbability);
								pSRandBoxOK->nPrefixCodeNum0	= pAddItemG->PrefixCodeNum;
								pSRandBoxOK->nSuffixCodeNum0	= pAddItemG->SuffixCodeNum;
							}
							
							if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_RANDOMBOX))
							{
								SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pAddItemG->ItemNum, pAddItemG->PrefixCodeNum);
								SAFE_DELETE(pAddItemG);
								// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
								//if(0 == i)
								//{
								//	return RES_BREAK;
								//}
								continue;	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 인벤토리 부족이 원인은 아님
							}

							nInsertedItemCounts++;		// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
						}
					}
					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			= pSRandBoxOK->n64ResultCounts;
						
						if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_RANDOMBOX))
						{
							SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pAddItemG->ItemNum, pAddItemG->PrefixCodeNum);
							SAFE_DELETE(pAddItemG);
							// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
							//return RES_BREAK;
							continue;	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 인벤토리 부족이 원인은 아님
						}

						nInsertedItemCounts++;		// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
					}
				}



				///////////////////////////////////////////////////////////////////////////////
				// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템,
				if(RANDOMBOX_RESULT_ITEM == pSRandBoxOK->nRandomBoxResult
					&& 0 != pSRandBoxOK->nResultItemNum0
					&& 0 != pSRandBoxOK->nPrefixCodeNum0
					&& 0 != pSRandBoxOK->nSuffixCodeNum0)
				{// 2006-08-11 by cmkwon, 무기 아이템에 레어가 모두(Prefix, Suffix) 붙을 경우는 맵의 모든 유저에게 전송
					// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_ITEM_USE_RANDOMBOX#, 
					m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK), m_character.GetInfluenceMask(), m_character.GetStartCityMapIndex());
				}
				else
				{
					SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK));
				}

			} // END - for(; itr != tmVectMysteryDropItemList.end(); itr++)

			///////////////////////////////////////////////////////////////////////////////
			// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 추가된 아이템이 없다. 원인 찾아야 함.
			if(0 >= nInsertedItemCounts)
			{
				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_COMMON_UNKNOWN_ERROR, pItemInfo->ItemNum, pItemInfo->LinkItem);
				return RES_BREAK;
			}
		}
		break;
// 2007-05-14 by cmkwon, 위와 같이 테이블을 추가하여 구현함
//		{
//
//			ITEM *pAddItemInfo				= ms_pFieldIOCP->GetRandomSkillSupportItem();
//			if ( NULL == pAddItemInfo )
//			{// 2006-08-11 by dhjin
//				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUID);
//				return RES_BREAK;
//			}
//
//			ITEM_GENERAL *pAddItemG			= new ITEM_GENERAL(pAddItemInfo);
//			pAddItemG->AccountUniqueNumber	= m_character.AccountUniqueNumber;
//			pAddItemG->Possess				= m_character.CharacterUniqueNumber;
//			pAddItemG->ItemStorage			= ITEM_IN_CHARACTER;
//			if(FALSE == IS_COUNTABLE_ITEM(pAddItemInfo->Kind))
//			{
//				this->ApplyGambleRareFix(pAddItemG, pItemInfo->ParameterValue1, pItemInfo->ParameterValue1);
//			}
//			
//			pSRandBoxOK->nResultItemNum0	= pAddItemInfo->ItemNum;
//			pSRandBoxOK->n64ResultCounts	= 1;
//			pSRandBoxOK->nPrefixCodeNum0	= pAddItemG->PrefixCodeNum;
//			pSRandBoxOK->nSuffixCodeNum0	= pAddItemG->SuffixCodeNum;
//			if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pAddItemG, IUT_RANDOMBOX))
//			{
//				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_INVENTORY_FULL_ITEM, pAddItemG->ItemNum, pAddItemG->PrefixCodeNum);
//				SAFE_DELETE(pAddItemG);
//				return RES_BREAK;
//			}
//		}
//		break;
	case RANDOMBOX_RESULT_SPI:
		{
			pSRandBoxOK->n64ResultCounts	= RANDI(((int)pItemInfo->AbilityMin), ((int)pItemInfo->AbilityMax));
			if(0 >= pSRandBoxOK->n64ResultCounts)
			{// 2006-08-10 by cmkwon, 파라미터 오류
				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_DB_INVALID_PARAMETER, 10000, pSRandBoxOK->nRandomBoxResult);
				return RES_BREAK;
			}
			ITEM_GENERAL *pItemGSPI			= m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER);
			if(NULL == pItemGSPI)
			{// 2006-10-16 by cmkwon, SPI 아이템이 없을 경우 추가
				m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, pSRandBoxOK->n64ResultCounts, IUT_RANDOMBOX);
			}
			else
			{
				if(MAX_ITEM_COUNTS < (INT64)pItemGSPI->CurrentCount + pSRandBoxOK->n64ResultCounts)
				{
					SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
					return RES_BREAK;
				}

				///////////////////////////////////////////////////////////////////////////////
				// 2006-08-10 by cmkwon, SPI 증가
				m_ItemManager.UpdateItemCountByPointer(pItemGSPI, pSRandBoxOK->n64ResultCounts, IUT_RANDOMBOX);
			}

			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK));	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 여기에서 성공 메시지 전송
		}
		break;
	case RANDOMBOX_RESULT_EXP:
		{			
			float fAddExpPercent	= RANDF2(pItemInfo->RangeAngle, pItemInfo->BoosterAngle);
			if(0.0f >= fAddExpPercent)
			{
				SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_DB_INVALID_PARAMETER, 11000, pSRandBoxOK->nRandomBoxResult);
				return RES_BREAK;
			}
			
			pSRandBoxOK->n64ResultCounts = fAddExpPercent * (CAtumSJ::GetInitialExperienceOfLevel(m_character.Level+1) - CAtumSJ::GetInitialExperienceOfLevel(m_character.Level));

			///////////////////////////////////////////////////////////////////////////////
			// 2006-08-10 by cmkwon, EXP 증가
			this->ChangeExperience(pSRandBoxOK->n64ResultCounts, FALSE, FALSE, FALSE);		// 2011-09-02 by hskim, 파트너 시스템 2차

			SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK));	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 여기에서 성공 메시지 전송
		}
		break;
	default:
		{
			// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 에러를 리턴 하는것이 맞음
			SendErrorMessage(T_FC_ITEM_USE_RANDOMBOX, ERR_DB_INVALID_PARAMETER, 12000, pSRandBoxOK->nRandomBoxResult);
			return RES_BREAK;
			
			pSRandBoxOK->nRandomBoxResult		= RANDOMBOX_RESULT_FAIL;
		}
	}
	
	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-10 by cmkwon, store log using RandomBox.
	// 2008-01-23 by cmkwon, S_F: 미스테리캡슐 사용 게임 로그 추가
	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);

	///////////////////////////////////////////////////////////////////////////////
	// 2006-08-10 by cmkwon, delete using RandomBox.
	m_ItemManager.DeleteItemFromCharacterByUID(pItemG->UniqueNumber, IUT_RANDOMBOX);

	igLock.auto_unlock_cancel();		// 2006-08-10 by cmkwon, 잠금 해제

// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 이 프로토콜 전송은 위쪽으로 위치 이동하고 아래에서 추가된 프로토콜을 전송한다.
// 	if(RANDOMBOX_RESULT_ITEM == pSRandBoxOK->nRandomBoxResult
// 		&& 0 != pSRandBoxOK->nResultItemNum0
// 		&& 0 != pSRandBoxOK->nPrefixCodeNum0
// 		&& 0 != pSRandBoxOK->nSuffixCodeNum0)
// 	{// 2006-08-11 by cmkwon, 무기 아이템에 레어가 모두(Prefix, Suffix) 붙을 경우는 맵의 모든 유저에게 전송
// 		m_pCurrentFieldMapChannel->SendMessageToAllInChannel(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK), m_character.GetInfluenceMask());
// 	}
// 	else
// 	{
// 		SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_RANDOMBOX_OK));
// 	}
	SendAddMessageType(T_FC_ITEM_USE_RANDOMBOX_OK_DONE);	// 2008-08-26 by cmkwon, ItemAttribute 추가 - 패키지(Package) 아이템, 클라이언트에서는 이 프로토콜을 받고 락상태를 해제 한다.
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-09-29 ~ 2006-09-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_SKILL_SUPPORT_ITEM,
									MSG_FC_ITEM_USE_SKILL_SUPPORT_ITEM, pRMsg);
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-08-07 by cmkwon, 개인 상점 개설중에는 아이템 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_USING_BAZAAR);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_SKILL_SUPPORT_ITEM
	if(this->CheckTradingItem(pRMsg->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_ITEM_TRADING, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);
	if (NULL == pItemG
		|| NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_CANNOT_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(FALSE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_ONLY_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵에서만 사용 가능
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_INFINITY_ONLY_USE_ITEM);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemG->ItemInfo;
	
	if(ITEMKIND_SKILL_SUPPORT_ITEM != pItemInfo->Kind
		|| FALSE == COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_TIME_LIMITE|ITEM_ATTR_DELETED_TIME_LIMITE_AFTER_USED))	// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - ITEMKIND_SKILL_SUPPORT_ITEM 사용시 아이템 요구사항 체크 추가(UnitKind 체크를 위해 추가)
	Err_t errCD = CheckItemRequirements(pItemG->ItemInfo);
	if(ERR_NO_ERROR != errCD)
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, errCD, pItemG->ItemInfo->ItemNum, 10000);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-09-29 by cmkwon, 아이템 생성 후 자동 삭제 아이템 체크
	if(COMPARE_BIT_FLAG(pItemInfo->ItemAttribute, ITEM_ATTR_DELETED_TIME_LIMITE))
	{
		ATUM_DATE_TIME expireATime;
		ATUM_DATE_TIME curATime(TRUE);
		expireATime			= pItemG->CreatedTime;
		// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM#,
		//expireATime.AddDateTime(0, 0, 0, pItemInfo->Endurance, 0, 0);
		expireATime.AddDateTime(0, 0, 0, 0, CAtumSJ::GetTimeMinuteByItemKind8ItemAttribute(pItemInfo, TIME_TERM_DELETE_ITEM));	// 2009-10-22 by cmkwon, 시간 제한형류 아이템 시스템 정리 - CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM#,

		if(curATime > expireATime)
		{// 2006-09-29 by cmkwon, 기간 만료, 삭제해야함

			SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_EXPIRED_ITEM, pItemInfo->ItemNum);


			// 2008-01-23 by cmkwon, S_F, S_L: 장착/장착해제 게임 로그에 추가 - 아래와 같이 CAtumLogSender::SendLogMessageITEMDelete() 로 대체함
			// 2012-08-30 by jhseol, 풀로그 남기기
#ifdef S_FULL_LOG_JHSEOL
			CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);						// 사용 아이템 로그 추가
#endif	//#ifdef S_FULL_LOG_JHSEOL
			// end 2012-08-30 by jhseol, 풀로그 남기기
			// 2008-01-23 by cmkwon, S_F, S_L: 장착/장착해제 게임 로그에 추가 - 
			CAtumLogSender::SendLogMessageITEMDelete(this, pItemG, IDT_EXPIRE_TIME);
			
			m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_EXPIRE_ITEM);		// Item 삭제하기
			return RES_BREAK;
		}
	}

	if(0 != pItemInfo->ReqMinLevel
		&& pItemInfo->ReqMinLevel > m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}
	if(0 != pItemInfo->ReqMaxLevel
		&& pItemInfo->ReqMaxLevel < m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-01-31 by cmkwon, 시간제한 아이템 DB 에 추가 중 체크 - DB 에 추가 상태인것 체크
	if(m_ItemManager.IsExistInsertingItemNumList2DB(pItemInfo->ItemNum))
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, 100);
		return RES_BREAK;
	}

	if(m_ItemManager.IsExistAlreadyUsingItemByItemNum(pItemInfo->ItemNum))
	{
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, 101);
		return RES_BREAK;
	}
				
	Err_t errCode = ApplyCardItem(pItemG->ItemInfo, TRUE);			// 사용된 아이템 기능 적용 하기
	if(ERR_NO_ERROR != errCode)
	{
		// 2009-04-21 by cmkwon, ITEM에 DesParam 필드 개수 8개로 늘리기 - 아래와 같이 수정
		//SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->DestParameter1);
		SendErrorMessage(T_FC_ITEM_USE_SKILL_SUPPORT_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}
// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 로 처리
// 	ITEM_GENERAL *pUsingItemG		= (ITEM_GENERAL*)m_ItemManager.MakeNewItem(pItemInfo->ItemNum, ITEM_IN_CHARACTER, pItemInfo);
// 	pUsingItemG->UsingTimeStamp		= ITEM_NOT_USING + 1;				// ITEM_NOT_USING이 아니므로 사용이 시작된것
// 	pUsingItemG->UsingStartTime.SetCurrentDateTime();	// 사용 시작 시간 설정
// 	if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pUsingItemG, IUT_USE_ITEM))
// 	{
// 		SAFE_DELETE(pUsingItemG);
// 	}
	// 2008-01-31 by cmkwon, 시간 제한 아이템 사용 관련 시스템 수정 - CFieldIOCPSocket::InsertTimeLimiteItem() 로 처리
	if(FALSE ==	this->InsertTimeLimiteItem(pItemInfo, FALSE))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertTimeLimiteItem error !!, CFieldIOCPSocket::Process_FC_ITEM_USE_SKILL_SUPPORT_ITEM User(%s) Item(%s)\r\n"
			, GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemG, string()));
	}

	CAtumLogSender::SendLogMessageITEMUseITEM(this, pItemG);					// 사용 아이템 로그 추가
	m_ItemManager.DeleteItemFromCharacterByPointer(pItemG, IUT_USE_ITEM);		// Item 삭제하기
	igLock.auto_unlock_cancel();

	///////////////////////////////////////////////////////////////////////////////
	// 2006-10-12 by cmkwon, 사용 정보 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_SKILL_SUPPORT_ITEM_OK, T_FC_ITEM_USE_SKILL_SUPPORT_ITEM_OK, pSMsg, SendBuf);
	pSMsg->ClientIndex		= m_character.ClientIndex;
	pSMsg->ItemNum			= pItemInfo->ItemNum;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_SKILL_SUPPORT_ITEM_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////
// start 2011-09-20 by hskim, 파트너 시스템 2차

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_PET_SOCKET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		소켓 아이템 사용 (토글) / 사용
/// \author		hskim
/// \date		2011-09-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_USE_PET_SOCKET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_USE_PET_SOCKET_ITEM,
		MSG_FC_ITEM_USE_PET_SOCKET_ITEM, pRMsg);

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

	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{// 2006-08-07 by cmkwon, 개인 상점 개설중에는 아이템 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_USING_BAZAAR);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래도중 아이템 사용 불가,T_FC_ITEM_USE_PET_SOCKET_ITEM
	if(this->CheckTradingItem(pRMsg->ItemUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_ITEM_TRADING, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_PET_SOCKET_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);

	if (NULL == pItemG || NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	if(TRUE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_CANNOT_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 사용 불가
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_INFINITY_CANNOT_USE_ITEM);
		return RES_BREAK;
	}

	if(FALSE == g_pFieldGlobal->IsArenaServer()
		&& COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_ONLY_USE_INFINITY)) {
		// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 인피 맵에서만 사용 가능
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_INFINITY_ONLY_USE_ITEM);
		return RES_BREAK;
	}

	ITEM *pItemInfo = pItemG->ItemInfo;

	if(ITEMKIND_PET_SOCKET_ITEM != pItemInfo->Kind)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_ITEM_KIND_NOT_MATCHED, pItemInfo->ItemNum, pItemInfo->Kind);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-03-18 by cmkwon, 몬스터변신 구현 - T_FC_ITEM_USE_PET_SOCKET_ITEM 사용시 아이템 요구사항 체크 추가(UnitKind 체크를 위해 추가)
	Err_t errCD = CheckItemRequirements(pItemG->ItemInfo);
	if(ERR_NO_ERROR != errCD)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, errCD, pItemG->ItemInfo->ItemNum, 10000);
		return RES_BREAK;
	}

	if(0 != pItemInfo->ReqMinLevel && pItemInfo->ReqMinLevel > m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_REQ_MINLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}

	if(0 != pItemInfo->ReqMaxLevel && pItemInfo->ReqMaxLevel < m_character.Level)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_REQ_MAXLEVEL_NOT_MATCHED, pItemInfo->ReqMaxLevel, pItemInfo->ReqMinLevel);
		return RES_BREAK;
	}

	// 현재 장착중인 펫의 소속된 소켓 아이템인지 확인
	ITEM_GENERAL *pPetItemG = GetAttachItemGeneralByPosition(POS_PET);

	if( NULL == pPetItemG )
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_CANNOT_ATTACHED_ITEM, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	if( FALSE == m_ItemManager.IsBelongPetSocketItemByUID(pPetItemG->UniqueNumber, pRMsg->ItemUniqueNumber) )
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_CANNOT_ATTACHED_ITEM, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-01-31 by cmkwon, 시간제한 아이템 DB 에 추가 중 체크 - DB 에 추가 상태인것 체크

	if(m_ItemManager.IsExistInsertingItemNumList2DB(pItemInfo->ItemNum))
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, 100);
		return RES_BREAK;
	}

	if(m_ItemManager.IsExistAlreadyUsingItemByItemNum(pItemInfo->ItemNum))
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_ALREADY_USE_OTHER_ITEM, pItemInfo->ItemNum, 101);
		return RES_BREAK;
	}

	if( NULL != m_ItemManager.FindUsingItemByItemNumNoLock(pItemInfo->ItemNum) )				
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_ALREADY_USE_ITEM, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0], "102");

		return RES_BREAK;
	}

	/* -- 추후 능력치 증가 소켓 아이템 추가시 사용 (추가 구현 해야함)
	Err_t errCode = ApplyCardItem(pItemG->ItemInfo, TRUE);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, errCode, pItemInfo->ItemNum, pItemInfo->ArrDestParameter[0]);
		return RES_BREAK;
	}
	*/

	if(FALSE == this->InsertTimeLimiteItem(pItemInfo, FALSE))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] InsertTimeLimiteItem error !!, CFieldIOCPSocket::Process_FC_ITEM_USE_PET_SOCKET_ITEM User(%s) Item(%s)\r\n"
			, GetCharacterString(GetCharacter(), string()), GetItemGeneralString(pItemG, string()));
	}

	igLock.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_USE_PET_SOCKET_ITEM_OK, T_FC_ITEM_USE_PET_SOCKET_ITEM_OK, pSMsg, SendBuf);
	pSMsg->ClientIndex		= pRMsg->ClientIndex;
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_USE_PET_SOCKET_ITEM_OK));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_ITEM_CANCEL_PET_SOCKET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		소켓 아이템 사용 (토글) / 사용 취소
/// \author		hskim
/// \date		2011-09-20
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_ITEM_CANCEL_PET_SOCKET_ITEM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_CANCEL_PET_SOCKET_ITEM,
									MSG_FC_ITEM_CANCEL_PET_SOCKET_ITEM, pRMsg);
	
	if(FALSE == IsValidCharacter())
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// lock m_mapItemGeneral, MSG_FC_ITEM_USE_PET_SOCKET_ITEM
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUniqueNumber);

	if (NULL == pItemG || NULL == pItemG->ItemInfo)
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUniqueNumber);
		return RES_BREAK;
	}

	Err_t errCode = ERR_NO_ERROR;
	ITEM *pItemInfo = pItemG->ItemInfo;

	errCode = PetCancelSocketItem(pItemInfo);
	
	if( ERR_NO_ERROR != errCode )
	{
		SendErrorMessage(T_FC_ITEM_USE_PET_SOCKET_ITEM, errCode, pItemInfo->ItemNum);

		return RES_BREAK;
	}

	igLock.auto_unlock_cancel();

	INIT_MSG_WITH_BUFFER(MSG_FC_ITEM_CANCEL_PET_SOCKET_ITEM_OK, T_FC_ITEM_CANCEL_PET_SOCKET_ITEM_OK, pSMsg, SendBuf);
	pSMsg->ClientIndex		= pRMsg->ClientIndex;
	pSMsg->ItemUniqueNumber	= pRMsg->ItemUniqueNumber;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_ITEM_CANCEL_PET_SOCKET_ITEM_OK));

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

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_MONSTER_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_INFO_GET_MONSTER_INFO	*pGetMonsterInfo;

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

	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	return RES_BREAK;

	ez_map<int, MONSTER_INFO>::iterator itrMon = ms_pFieldIOCP->m_mapMonsterInfo.find(pGetMonsterInfo->MonsterUnitKind);
	if (itrMon == ms_pFieldIOCP->m_mapMonsterInfo.end())
	{
		SendErrorMessage(T_FC_INFO_GET_MONSTER_INFO, ERR_PROTOCOL_NO_SUCH_MONSTER_INFO, pGetMonsterInfo->MonsterUnitKind);
		return RES_BREAK;
	}

	MONSTER_INFO &refMonsterInfo = itrMon->second;

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_MONSTER_INFO_OK, T_FC_INFO_GET_MONSTER_INFO_OK, pGetMonsterInfoOK, pGetMonsterInfoOKBuf);
	pGetMonsterInfoOK->MonsterInfo = refMonsterInfo;
	SendAddData(pGetMonsterInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_MONSTER_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_MAPOBJECT_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_INFO_GET_MAPOBJECT_INFO	*pGetObjectInfo;

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

	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	return RES_BREAK;

	ez_map<int, MAPOBJECTINFO>::iterator itrObj = ms_pFieldIOCP->GetMapWorkspace()->m_mapMapObjectInfo.find(pGetObjectInfo->Code);
	if (itrObj == ms_pFieldIOCP->GetMapWorkspace()->m_mapMapObjectInfo.end())
	{
		if(FALSE == IS_DEFAULT_OBJECT_MONSTER_OBJECT(pGetObjectInfo->Code))
		{
			SendErrorMessage(T_FC_INFO_GET_MAPOBJECT_INFO, ERR_PROTOCOL_NO_SUCH_MAPOBJECT_INFO, pGetObjectInfo->Code);
		}		
		return RES_BREAK;
	}

	MAPOBJECTINFO &refObj = itrObj->second;

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_MAPOBJECT_INFO_OK, T_FC_INFO_GET_MAPOBJECT_INFO_OK, pGetObjInfoOK, pGetObjInfoOKBuf);
	pGetObjInfoOK->MapObjectInfo = refObj;
	SendAddData(pGetObjInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_MAPOBJECT_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_ITEM_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FC_INFO_GET_ITEM_INFO	*pGetItemInfo;

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

#ifdef _ATUM_LOAD_TEST	// 2008-03-19 by cmkwon, loadtest 는 T_FC_INFO_GET_ITEM_INFO 에 응답을 한다.
		// 탄알을 감소
		if(0 == strnicmp(m_character.AccountName, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME, ATUM_LOAD_TEST_PREFIX_ACCOUNT_NAME_SIZE))
		{// 2008-03-19 by cmkwon, 캐릭터 명이 loadtest로 시작한다면 정보를 전송해줘야 공격이 가능하다

			ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pGetItemInfo->ItemNum);
			if (pItemInfo == NULL)
			{
				SendErrorMessage(T_FC_INFO_GET_ITEM_INFO, ERR_PROTOCOL_NO_SUCH_ITEM, pGetItemInfo->ItemNum);
				return RES_BREAK;
			}

			INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_ITEM_INFO_OK, T_FC_INFO_GET_ITEM_INFO_OK, pGetItemInfoOK, pGetItemInfoOKBuf);
			pGetItemInfoOK->ItemInfo = *pItemInfo;
			SendAddData(pGetItemInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_ITEM_INFO_OK)-SIZE_MAX_ITEM_DESCRIPTION);	// 아이템 설명 부분 제외하고 전송, check: 최종적으로는 아이템의 종류마다 보내는 정보의 종류를 결정하고 각각의 메세지를 만들어서 보내야 함, 20040217, kelovon
			return RES_RETURN_TRUE;
		}
#endif

	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	return RES_BREAK;

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pGetItemInfo->ItemNum);
	if (pItemInfo == NULL)
	{
		SendErrorMessage(T_FC_INFO_GET_ITEM_INFO, ERR_PROTOCOL_NO_SUCH_ITEM, pGetItemInfo->ItemNum);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_ITEM_INFO_OK, T_FC_INFO_GET_ITEM_INFO_OK, pGetItemInfoOK, pGetItemInfoOKBuf);
	pGetItemInfoOK->ItemInfo = *pItemInfo;
	SendAddData(pGetItemInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_ITEM_INFO_OK)-SIZE_MAX_ITEM_DESCRIPTION);	// 아이템 설명 부분 제외하고 전송, check: 최종적으로는 아이템의 종류마다 보내는 정보의 종류를 결정하고 각각의 메세지를 만들어서 보내야 함, 20040217, kelovon

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_SIMPLE_ITEM_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize = 0;
	MSG_FC_INFO_GET_SIMPLE_ITEM_INFO	*pGetSimpleItemInfo;

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

	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	return RES_BREAK;

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(pGetSimpleItemInfo->ItemNum);
	if (pItemInfo == NULL)
	{
		SendErrorMessage(T_FC_INFO_GET_SIMPLE_ITEM_INFO, ERR_PROTOCOL_NO_SUCH_ITEM, pGetSimpleItemInfo->ItemNum);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_SIMPLE_ITEM_INFO_OK, T_FC_INFO_GET_SIMPLE_ITEM_INFO_OK, pGetSimpleItemInfoOK, pGetSimpleItemInfoOKBuf);
	pGetSimpleItemInfoOK->ItemInfo = *pItemInfo;
	SendAddData(pGetSimpleItemInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_SIMPLE_ITEM_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_RARE_ITEM_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_INFO_GET_RARE_ITEM_INFO	*pGetRareItemInfo;

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

	// 2008-03-13 by cmkwon, 대규모 전쟁시 클라이언트 팅기는거 수정 - 
	return RES_BREAK;

	RARE_ITEM_INFO *pRareItemInfo = ms_pFieldIOCP->GetRareItemInfo(pGetRareItemInfo->CodeNum);
	if (pRareItemInfo == NULL)
	{
		SendErrorMessage(T_FC_INFO_GET_RARE_ITEM_INFO, ERR_PROTOCOL_NO_SUCH_ITEM, pGetRareItemInfo->CodeNum);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_RARE_ITEM_INFO_OK, T_FC_INFO_GET_RARE_ITEM_INFO_OK, pGetRareItemInfoOK, pGetRareItemInfoOKBuf);
	pGetRareItemInfoOK->RareItemInfo = *pRareItemInfo;
	SendAddData(pGetRareItemInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_RARE_ITEM_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_BUILDINGNPC_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_GET_BUILDINGNPC_INFO,
									MSG_FC_INFO_GET_BUILDINGNPC_INFO, pGetBuildingNPCInfo);

	BUILDINGNPC *pBuildingNPC
		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pGetBuildingNPCInfo->BuildingIndex);
	if (pBuildingNPC == NULL)
	{
		SendErrorMessage(T_FC_INFO_GET_BUILDINGNPC_INFO, ERR_COMMON_UNKNOWN_ERROR, pGetBuildingNPCInfo->BuildingIndex);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_BUILDINGNPC_INFO_OK, T_FC_INFO_GET_BUILDINGNPC_INFO_OK, pGetBuildingInfoOK, pGetBuildingInfoOKBuf);
	pGetBuildingInfoOK->BuildingNPCInfo = *pBuildingNPC;
	SendAddData(pGetBuildingInfoOKBuf, MSG_SIZE(MSG_FC_INFO_GET_BUILDINGNPC_INFO_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_ENCHANT_COST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_GET_ENCHANT_COST,
									MSG_FC_INFO_GET_ENCHANT_COST, pGetEnchantCost);

	ENCHANT_INFO *pEnchantInfo
		= ms_pFieldIOCP->m_mapEnchantInfo.findEZ_ptr(pGetEnchantCost->EnchantItemNum);
	if (pEnchantInfo == NULL)
	{
		SendErrorMessage(T_FC_INFO_GET_ENCHANT_COST, ERR_PROTOCOL_NO_SUCH_ITEM, pGetEnchantCost->EnchantItemNum);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_ENCHANT_COST_OK, T_FC_INFO_GET_ENCHANT_COST_OK, pGetCostOK, pGetCostOKBuf);
	pGetCostOK->Cost = pEnchantInfo->EnchantCost;
	SendAddData(pGetCostOKBuf, MSG_SIZE(MSG_FC_INFO_GET_ENCHANT_COST_OK));

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_CURRENT_MAP_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 2007-04-06 by cmkwon, MSG_FC_INFO_GET_CURRENT_MAP_INFO 구조체 추가함
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_GET_CURRENT_MAP_INFO,
									MSG_FC_INFO_GET_CURRENT_MAP_INFO, pRMsg);



	CFieldMapChannel *pFMChann = this->GetCurrentFieldMapChannel();
	if(NULL == pFMChann)
	{
		SendErrorMessage(T_FC_INFO_GET_CURRENT_MAP_INFO, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED, 0, 0, "NULL");
		return RES_BREAK;
	}



	if(FALSE == pRMsg->mapChannelIdx0.IsSameMapChannelIndex(pFMChann->GetMapChannelIndex()))
	{
		// 2010-04-02 by cmkwon, 인피2차 추가 수정 - 
		char szTxt[1024];	MEMSET_ZERO(szTxt, 1024);
		sprintf(szTxt, "NotSame<Cur(%s) != Reved(%s)>", GetMapString(pFMChann->GetMapChannelIndex(), string()), GetMapString(pRMsg->mapChannelIdx0, string()));
		SendErrorMessage(T_FC_INFO_GET_CURRENT_MAP_INFO, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED, pFMChann->GetMapChannelIndex().MapIndex, pFMChann->GetMapChannelIndex().ChannelIndex, szTxt);
		return RES_BREAK;
	}



// 2009-05-29 by cmkwon, Hash알고리즘 추가(SHA256) - 
//	if(pFMChann->m_pFieldMapProject->m_uiMapCheckSum != pRMsg->checkSum0)
	if(FALSE == pFMChann->m_pFieldMapProject->m_mapCheckSum.IsSame(pRMsg->nFileSize, pRMsg->byDigest))
	{
		CAtumLogSender::SendLogMessageMemoryHack(this, 0, 0, 0, HACK_CHECK_TYPE_MAP_CHECK_SUM, 0, 0, pRMsg->mapChannelIdx0.ChannelIndex);
		SendErrorMessage(T_FC_INFO_GET_CURRENT_MAP_INFO, ERR_MAP_CHECKSUM_NOT_MATCHED, pFMChann->GetMapChannelIndex().MapIndex);

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-12 by cmkwon, 관리자/운영자를 제외하고 나머지 클라이언트는 소켓을 종료한다.
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{
	// 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거
#ifdef S_DISABLE_CHECKSUM_RESOURCE
#else
		this->Close(0x14068, FALSE, 3000);
		return RES_BREAK;
#endif
	// end 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거
		}
	}

	// start 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	pFMChann->SendChangeObjectList(this);
	pFMChann->SendTimeLimit(this);
	// end 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_CURRENT_MAP_INFO_OK, T_FC_INFO_GET_CURRENT_MAP_INFO_OK, pSMsg, SendBuf);
	pSMsg->IsPKMap				= TRUE;
	pSMsg->IsCityWarStarted		= pFMChann->m_pFieldMapProject->IsCityWarStarted();
	pSMsg->byCityWarTeamType	= this->m_byCityWarTeamType;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFO_GET_CURRENT_MAP_INFO_OK));

	// 2013-05-31 by jhseol,bckim 아머 컬렉션 - 맵 이동시 장착중인 엔진이 없으면 마을로 강제워프
#ifdef SC_COLLECTION_ARMOR_JHSEOL_BCKIM	// - 맵 이동시 장착중인 엔진이 없으면 마을로 강제워프
	if ( FALSE == g_pFieldGlobal->IsArenaServer() )
	{
		if ( FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER)
			&& NULL == this->GetAttachItemGeneralByPosition(POS_REAR) )		// 장착 엔진이 없음.
		{
			if ( FALSE == IS_CITY_MAP_INDEX(this->m_character.MapChannelIndex.MapIndex) )		// 도시맵이 아니면 강제 워프
			{
				this->SendString128(STRING_128_USER_NOTICE, STRMSG_130531_0005);
				this->WarpToCityMap();
			}
		}
	}
#endif
	// end 2013-05-31 by jhseol,bckim 아머 컬렉션 - 맵 이동시 장착중인 엔진이 없으면 마을로 강제워프

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_SERVER_DATE_TIME(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-10-11 ~ 2006-10-11
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_SERVER_DATE_TIME(const char* pPacket, int nLength, int &nBytesUsed)
{// No message body

	INIT_MSG_WITH_BUFFER(MSG_FC_INFO_GET_SERVER_DATE_TIME_OK, T_FC_INFO_GET_SERVER_DATE_TIME_OK, pSMsg, SendBuf);
	pSMsg->atimeCurServerTime.SetCurrentDateTime();
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_INFO_GET_SERVER_DATE_TIME_OK));
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2007-11-02 ~ 2006-11-02
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_GET_HAPPY_HOUR_EVENT_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{// No message body

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

	ms_pFieldIOCP->SendGameEventMessage(this, GetCharacter()->InfluenceType);
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_INFO_CHECK_RESOBJ_CHECKSUM(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2007-05-28 ~ 2007-05-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_INFO_CHECK_RESOBJ_CHECKSUM(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_INFO_CHECK_RESOBJ_CHECKSUM,
									MSG_FC_INFO_CHECK_RESOBJ_CHECKSUM, pRMsg);

	// 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거
#ifdef S_DISABLE_CHECKSUM_RESOURCE
	return RES_RETURN_TRUE;
#endif
	// end 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거

	if(FALSE == this->IsValidCharacter(FALSE))
	{// 2008-11-27 by cmkwon, CheckSum 리스트 파일 이름을 대문자로 변경 처리 - 기본 체크 추가
		return RES_BREAK;
	}

	SRESOBJ_CHECKSUM *pResObj = ms_pFieldIOCP->GetResObjCheckSum(pRMsg->szObjFileName);
	if(NULL == pResObj)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ResObj CheckSum error !! not exist file(%s), ItemNum(%d)\r\n", pRMsg->szObjFileName, pRMsg->nItemNum0);
		return RES_BREAK;
	}

// 2009-05-29 by cmkwon, Hash알고리즘 추가(SHA256) - 
//	if(pResObj->uiObjCheckSum != pRMsg->uiCheckSum0
//		|| pResObj->nFileSize != pRMsg->nFileSize0)
	if(FALSE == pResObj->IsSame(pRMsg->nFileSize0, pRMsg->byDigest))
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] ResObj CheckSum error !! %s, FileName(%s) ItemNum(%d)\r\n", GetCharacterString(GetCharacter(), string()), pRMsg->szObjFileName, pRMsg->nItemNum0);
		CAtumLogSender::SendLogMessageMemoryHack(this, ITEMKIND_DEFENSE, pRMsg->nItemNum0, 0, HACK_CHECK_TYPE_RESOBJ_CHECK_SUM, 0, 0, pRMsg->nFileSize0);
		SendErrorMessage(T_FC_INFO_CHECK_RESOBJ_CHECKSUM, ERR_MAP_CHECKSUM_NOT_MATCHED, pRMsg->nItemNum0, 0, pRMsg->szObjFileName);

		///////////////////////////////////////////////////////////////////////////////
		// 2007-04-12 by cmkwon, 관리자/운영자를 제외하고 나머지 클라이언트는 소켓을 종료한다.
		if(FALSE == CheckCommandExecutability(RACE_OPERATION|RACE_GAMEMASTER))
		{

#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 RES_RETURN_TRUE;
			}
#endif // END - #if defined(SERVICE_TYPE_KOREAN_SERVER_1) || defined(SERVICE_TYPE_KOREAN_SERVER_2)

			// 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거
#ifdef S_DISABLE_CHECKSUM_RESOURCE
			return RES_RETURN_TRUE;
#endif
			// end 2012-12-11 by hskim, 디버깅용 리소스 체크섬 제거

			this->Close(0x14069, FALSE, 3000);
			return RES_BREAK;
		}
	}
	return RES_RETURN_TRUE;
}



// 1:1 PvP 는 다른 프로토콜로 처리한다.
// 파티전 요청 처리
// 여단전 요청 처리
ProcessResult CFieldIOCPSocket::Process_FC_REQUEST_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	/**************************************************************************
	* 해야 할 일 리스트

	// 상대방 확인
	// 거리 및 동일 맵 조건 확인
	// 파티 확인
	// 파티장 확인
	// 요청중 확인
	// 진행중 확인
	// 상대방 파티 확인
	// 상대방 파티장 확인
	// 상대방의 요청중 확인
	// 상대방의 진행중 확인
	// Level 조건 확인
	// 모든 파티원이 같은 맵에 있는지 확인
	// 파티원 수 조건 확인
	// 상대방을 setting (동시에 파티전 요청중 상태로 바꿈)
	***************************************************************************/

	int						nRecvTypeSize = 0;
	MSG_FC_REQUEST_REQUEST	*pRequest;
	BOOL					bSendOK = FALSE;

	nRecvTypeSize = sizeof(MSG_FC_REQUEST_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pRequest = (MSG_FC_REQUEST_REQUEST*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(FALSE == this->IsValidCharacter())
	{// 2009-02-05 by cmkwon, 전쟁시 강제 워프 관련 처리 수정 - 체크 추가
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2009-02-05 by cmkwon, 전쟁시 강제 워프 관련 처리 수정 - 전진기지전 중이면 파티전,여단전 불가
	CFieldMapChannel *pFMapChann = this->GetCurrentFieldMapChannel();
	if(IS_MAP_INFLUENCE_OUTPOST(pFMapChann->GetMapInfluenceTypeW())
		&& ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pFMapChann->GetMapChannelIndex().MapIndex))
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_WARING_OUTPOST_TO_OWNMAP, pFMapChann->GetMapChannelIndex().MapIndex);
		return RES_BREAK;		
	}

	//////////////////////////////////////////////////////////////////////////
	// 2007-05-11 by dhjin, 아레나 맵에서는 불가능하다.
	if(IS_MAP_INFLUENCE_ARENA(m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_ARENA_STATE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-02-12 by cmkwon, 도시맵에서 파티전, 여단전 불가
	if(IS_CITY_MAP_INDEX(m_pCurrentFieldMapChannel->GetMapChannelIndex().MapIndex))
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_CANNOT_IN_CITY_MAP_CHANNEL);
		return RES_BREAK;
	}

	// 상대방 확인
	CFieldIOCPSocket *pTargetSocket = NULL;
	if (pRequest->TargetClientIndex != 0)
	{
		pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pRequest->TargetClientIndex);
		if (pTargetSocket == NULL || !pTargetSocket->IsUsing() || pTargetSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER
				, pRequest->RequestType, pRequest->TargetClientIndex);
			return RES_BREAK;
		}
	}
	else
	{
		pTargetSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pRequest->TargetCharacterName);
		if (pTargetSocket == NULL 
			|| !pTargetSocket->IsUsing() 
			|| pTargetSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER
				, pRequest->RequestType, 0, pRequest->TargetCharacterName);
			return RES_BREAK;
		}
	}

	if (pTargetSocket == this)
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_COMMON_NOT_ALLOWED_TO_MYSELF, pRequest->RequestType);
// 2004-12-16 by cmkwon, 위의 에러메시지로 변경함
//		SendString128(STRING_128_USER_ERR, "자기 자신에게는 요청할 수 없습니다.");
		return RES_BREAK;
	}

	if(false == m_character.MapChannelIndex.IsSameMapChannelIndex(pTargetSocket->GetCharacter()->MapChannelIndex))
	{// 2005-11-03 by cmkwon, MapChannelIndex 체크
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
		return RES_BREAK;
	}

	// 2014-04-15 by bckim, 버닝맵에서는 결투 불가
	if( ms_pFieldIOCP->IsBurningMap(m_character.MapChannelIndex.MapIndex))
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_NOT_WARP_BURNING_MAP);
		return RES_BREAK;
	}
	// End. 2014-04-15 by bckim, 버닝맵에서는 결투 불가

	// 거리가 멀어서 불가
	if (pRequest->RequestType != REQUEST_TYPE_GUILD_WAR
		&& D3DXVec3Length(&(m_character.PositionVector - pTargetSocket->m_character.PositionVector)) > REQUERED_REQUEST_DISTANCE)
	{
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_TOO_FAR_TO_DO
			, pRequest->RequestType);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////
	// Request Type별 처리 루틴
	///////////////////////////////////////////////////////////////////////////
	if (pRequest->RequestType == REQUEST_TYPE_PARTY_BATTLE)
	{
		if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BATTLE_PARTY_WAR, m_character.Race, m_character.InfluenceType
												, pTargetSocket->GetCharacter()->Race,  pTargetSocket->GetCharacter()->InfluenceType))
		{// 2006-01-05 by cmkwon, 세력이 다르면
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pRequest->RequestType);
			return RES_BREAK;
		}

		// 파티 확인
		CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if (NULL == pMeFParty)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY
				, pRequest->RequestType);
			return RES_BREAK;
		}

		// 파티장 확인
		if (m_character.CharacterUniqueNumber != pMeFParty->GetMasterCharacterUniqueNumber())
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED
				, pRequest->RequestType);
			return RES_BREAK;
		}

		// 요청중 확인
		if (pMeFParty->m_PeerBattleRequesterPartyID != 0)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_ALREADY_REQUESTING_PARTY_BATTLE
				, pRequest->RequestType, HIDWORD(pMeFParty->m_PeerBattleRequesterPartyID), m_character.CharacterName);
			return RES_BREAK;
		}

		// 진행중 확인
		if (pMeFParty->m_PeerBattlePartyID != 0)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_ALREADY_PARTY_BATTLE
				, pRequest->RequestType, HIDWORD(pMeFParty->m_PeerBattlePartyID), m_character.CharacterName);
			return RES_BREAK;
		}

		// 상대방 파티 확인
		CFieldParty *pTargetParty = pTargetSocket->m_pFieldParty;
		if (pTargetParty == NULL)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY
				, pRequest->RequestType, pRequest->TargetClientIndex, "Target Party");
			return RES_BREAK;
		}

		// 상대방 파티장 확인
		if (pTargetParty->GetMasterCharacterUniqueNumber() != pTargetSocket->m_character.CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED
				, pRequest->RequestType, pRequest->TargetClientIndex, "Target Party");
			return RES_BREAK;
		}

		// 상대방의 요청중 확인
		if (pTargetParty->m_PeerBattleRequesterPartyID != 0)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_ALREADY_REQUESTING_PARTY_BATTLE
				, pRequest->RequestType, HIDWORD(pTargetParty->m_PeerBattleRequesterPartyID), pTargetSocket->m_character.CharacterName);
			return RES_BREAK;
		}

		// 상대방의 진행중 확인
		if (pTargetParty->m_PeerBattlePartyID != 0)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_ALREADY_PARTY_BATTLE
				, pRequest->RequestType, HIDWORD(pTargetParty->m_PeerBattlePartyID), pTargetSocket->m_character.CharacterName);
			return RES_BREAK;
		}

		// Level 조건 확인
		if (FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_PARTY_WAR, pMeFParty->GetLowestMemberLevel())
			|| FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_PARTY_WAR, pTargetParty->GetLowestMemberLevel()))
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED
				, pRequest->RequestType, pTargetParty->GetLowestMemberLevel());
			return RES_BREAK;
		}

		// 파티원이 같은 맵에 있는지 확인
		// 2007-06-26 by cmkwon, 파티 경험치 관련 수정 - 살아 있는지 체크
		if (pMeFParty->GetMembersInSameMap(NULL, m_pCurrentFieldMapChannel, TRUE) != pMeFParty->m_FieldPartyInfo.nTotalPartyMember
			|| pTargetParty->GetMembersInSameMap(NULL, m_pCurrentFieldMapChannel, TRUE) != pTargetParty->m_FieldPartyInfo.nTotalPartyMember)
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED
				, pRequest->RequestType);
// 2004-12-16 by cmkwon, 위의 에러전송으로 변경함
//			SendString128(STRING_128_USER_ERR, "모든 파티원들이 같은 맵에 있지 않습니다");
			return RES_BREAK;
		}

		// 상대방을 setting (동시에 파티전 요청중 상태로 바꿈)
		pMeFParty->m_PeerBattleRequesterPartyID = pTargetParty->m_PartyID;
		pTargetParty->m_PeerBattleRequesterPartyID = pMeFParty->m_PartyID;

		// Time Out 설정
		m_TimerManager.StartTimerField(TE_TYPE_REQUEST_TIMEOUT, FC_REQUEST_TIMEOUT_INTERVAL,
						REQUEST_TYPE_PARTY_BATTLE, LODWORD(pMeFParty->m_PartyID), HIDWORD(pMeFParty->m_PartyID));
		pTargetSocket->m_TimerManager.StartTimerField(TE_TYPE_REQUEST_TIMEOUT, FC_REQUEST_TIMEOUT_INTERVAL,
						REQUEST_TYPE_PARTY_BATTLE, LODWORD(pTargetParty->m_PartyID), HIDWORD(pTargetParty->m_PartyID));

		bSendOK = TRUE;
	}
	else if (pRequest->RequestType == REQUEST_TYPE_GUILD_WAR)
	{
		// 2007-05-11 by dhjin, 상대 여단장이 아레나 맵에 있다면 불가능하다.
		if(IS_MAP_INFLUENCE_ARENA(pTargetSocket->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
		{
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_ARENA_STATE);
			return RES_BREAK;
		}

		if(FALSE == GCheckRaceAndInfluenceType(CHECK_TYPE_BATTLE_GUILD_WAR, m_character.Race, m_character.InfluenceType
												, pTargetSocket->GetCharacter()->Race,  pTargetSocket->GetCharacter()->InfluenceType))
		{// 2006-01-05 by cmkwon, 세력이 다르면
			SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pRequest->RequestType);
			return RES_BREAK;
		}

		if (FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber)
			|| FALSE == IS_VALID_UNIQUE_NUMBER(pTargetSocket->m_character.GuildUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0046);
			return RES_BREAK;
		}

		if (!m_RequestHandler.IsRequestableAndResetIfTimeOut()
			|| !pTargetSocket->m_RequestHandler.IsRequestableAndResetIfTimeOut())
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0047);
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0048);
			return RES_BREAK;
		}

		if (!ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber)
			|| !ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(pTargetSocket->m_character.CharacterUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0049);
			return RES_BREAK;
		}

		if (ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(m_character.GuildUniqueNumber)
			|| ms_pFieldIOCP->m_GuildWarManager.FindGuildWarPtr(pTargetSocket->m_character.GuildUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0050);
			return RES_BREAK;
		}

		if (m_character.MapChannelIndex != pTargetSocket->m_character.MapChannelIndex)
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0051);
			return RES_BREAK;
		}

		m_RequestHandler.SetPeerRequest(REQUEST_TYPE_GUILD_WAR, pTargetSocket->m_character.ClientIndex);
		pTargetSocket->m_RequestHandler.SetPeerRequest(REQUEST_TYPE_GUILD_WAR, m_character.ClientIndex);

		bSendOK = TRUE;
	}
	else
	{
		// 지원되지 않는 타입인 경우
		bSendOK = FALSE;

		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pRequest->RequestType);
		return RES_BREAK;
	}

	if (bSendOK)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_REQUEST_REQUEST_OK, T_FC_REQUEST_REQUEST_OK, pRequestOK, pRequestOKBuf);
		pRequestOK->SourceClientIndex = m_character.ClientIndex;
		STRNCPY_MEMSET(pRequestOK->SourceCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		pRequestOK->RequestType = pRequest->RequestType;
		pTargetSocket->SendAddData(pRequestOKBuf, MSG_SIZE(MSG_FC_REQUEST_REQUEST_OK));
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_REQUEST_ACCEPT_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_REQUEST_ACCEPT_REQUEST	*pAccept;

	nRecvTypeSize = sizeof(MSG_FC_REQUEST_ACCEPT_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pAccept = (MSG_FC_REQUEST_ACCEPT_REQUEST*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 상대방 확인
	CFieldIOCPSocket *pSourceSocket = NULL;
	if (pAccept->SourceClientIndex != 0)
	{
		pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pAccept->SourceClientIndex);
		if (pSourceSocket == NULL || !pSourceSocket->IsUsing() || pSourceSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER, pAccept->SourceClientIndex);
			return RES_BREAK;
		}
	}
	else
	{
	
		pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pAccept->SourceCharacterName);
		if (pSourceSocket == NULL || !pSourceSocket->IsUsing() || pSourceSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER, 0, 0, pAccept->SourceCharacterName);
			return RES_BREAK;
		}
	}

	if(false == m_character.MapChannelIndex.IsSameMapChannelIndex(pSourceSocket->GetCharacter()->MapChannelIndex))
	{// 2005-11-03 by cmkwon, MapChannelIndex 체크
		SendErrorMessage(T_FC_REQUEST_REQUEST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
		return RES_BREAK;
	}

	// 거리가 멀어서 불가
	if (pAccept->RequestType != REQUEST_TYPE_GUILD_WAR
		&& D3DXVec3Length(&(m_character.PositionVector - pSourceSocket->m_character.PositionVector)) > REQUERED_REQUEST_DISTANCE)
	{
		SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_TOO_FAR_TO_DO);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////
	// Request Type별 처리 루틴
	///////////////////////////////////////////////////////////////////////////
	if (pAccept->RequestType == REQUEST_TYPE_PARTY_BATTLE)
	{
		// 파티 확인
		CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if (pMeFParty == NULL)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY, pAccept->RequestType);
			return RES_BREAK;
		}

		// 파티장 확인
		if (m_character.CharacterUniqueNumber != pMeFParty->GetMasterCharacterUniqueNumber())
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED, m_character.CharacterUniqueNumber, pMeFParty->GetMasterCharacterUniqueNumber());
			return RES_BREAK;
		}

		// 상대방 파티 확인
		CFieldParty *pSourceParty = pSourceSocket->m_pFieldParty;
		if (pSourceParty == NULL)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY, pAccept->SourceClientIndex, 0, "Source Party");
			return RES_BREAK;
		}

		// 상대방 파티장 확인
		if (pSourceParty->GetMasterCharacterUniqueNumber() != pSourceSocket->m_character.CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED, pAccept->SourceClientIndex, 0, "Source Party");
			return RES_BREAK;
		}

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

		// Level 조건 확인, 시작하기 전 다시 확인
		if (FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_PARTY_WAR, pMeFParty->GetLowestMemberLevel())
			|| FALSE == GCheckLimitLevel(CHECK_TYPE_BATTLE_PARTY_WAR, pSourceParty->GetLowestMemberLevel()))
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_REQ_LEVEL_NOT_MATCHED
				, pMeFParty->GetLowestMemberLevel()
				, pSourceParty->GetLowestMemberLevel());

			INIT_MSG_WITH_BUFFER(MSG_FC_REQUEST_CANCEL_REQUEST, T_FC_REQUEST_CANCEL_REQUEST, pCancelRequest, pCancelRequestBuf);
			pCancelRequest->PeerClientIndex = 0;
			pCancelRequest->RequestType = REQUEST_TYPE_PARTY_BATTLE;
			SendAddData(pCancelRequestBuf, MSG_SIZE(MSG_FC_REQUEST_CANCEL_REQUEST));
			pSourceSocket->SendAddData(pCancelRequestBuf, MSG_SIZE(MSG_FC_REQUEST_CANCEL_REQUEST));

			// reset party battle
			pMeFParty->m_PeerBattleRequesterPartyID = 0;
			pSourceParty->m_PeerBattleRequesterPartyID = 0;

			return RES_BREAK;
		}

		// 시작하기 전 다시 확인
		// 2007-06-26 by cmkwon, 파티 경험치 관련 수정 - 살아 있는지 체크
		if (pMeFParty->GetMembersInSameMap(NULL, m_pCurrentFieldMapChannel, TRUE) != pMeFParty->m_FieldPartyInfo.nTotalPartyMember
			|| pSourceParty->GetMembersInSameMap(NULL, m_pCurrentFieldMapChannel, TRUE) != pSourceParty->m_FieldPartyInfo.nTotalPartyMember)
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0052);
			pSourceSocket->SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0053);

			INIT_MSG_WITH_BUFFER(MSG_FC_REQUEST_CANCEL_REQUEST, T_FC_REQUEST_CANCEL_REQUEST, pCancelRequest, pCancelRequestBuf);
			pCancelRequest->PeerClientIndex = 0;
			pCancelRequest->RequestType = REQUEST_TYPE_PARTY_BATTLE;
			SendAddData(pCancelRequestBuf, MSG_SIZE(MSG_FC_REQUEST_CANCEL_REQUEST));
			pSourceSocket->SendAddData(pCancelRequestBuf, MSG_SIZE(MSG_FC_REQUEST_CANCEL_REQUEST));

			// reset party battle
			pMeFParty->m_PeerBattleRequesterPartyID = 0;
			pSourceParty->m_PeerBattleRequesterPartyID = 0;

			return RES_BREAK;
		}

		///////////////////////////////////////////////////////////////////////
		// 파티전 시작
		///////////////////////////////////////////////////////////////////////

		// 상대편 파티 아이디 할당
		pMeFParty->m_PeerBattlePartyID		= pSourceParty->m_PartyID;		
		pSourceParty->m_PeerBattlePartyID	= pMeFParty->m_PartyID;
		pMeFParty->m_PartyBattleMapChannelIndex		= this->m_character.MapChannelIndex;
		pSourceParty->m_PartyBattleMapChannelIndex	= this->m_character.MapChannelIndex;

		// 파티전 구조체 생성
		pMeFParty->m_PartyBattle.InitFieldPartyBattle(pMeFParty, pSourceParty, m_pCurrentFieldMapChannel);
		pSourceParty->m_PartyBattle.InitFieldPartyBattle(pSourceParty, pMeFParty, m_pCurrentFieldMapChannel);

		INIT_MSG_WITH_BUFFER(MSG_FC_COUNTDOWN_START, T_FC_COUNTDOWN_START, pSMsg, pSendBuf);
		pSMsg->byCountdownType = COUNTDOWN_TYPE_PARTY_WAR;
		pSMsg->nWaitingSecond = SECOND_COUNTDOWN_TIME_GAP;
		
		if(m_pCurrentFieldMapChannel && pMeFParty)
		{
			// 같은편 파티원 모두에게 전송
			pMeFParty->SendMsgToMembersMap(pSendBuf, MSG_SIZE(MSG_FC_COUNTDOWN_START), m_pCurrentFieldMapChannel, INVALID_UNIQUE_NUMBER, pSMsg);
		}

		if(m_pCurrentFieldMapChannel)
		{
			// 상대편 파티원 모두에게 전송
			pSourceParty->SendMsgToMembersMap(pSendBuf, MSG_SIZE(MSG_FC_COUNTDOWN_START), m_pCurrentFieldMapChannel, INVALID_UNIQUE_NUMBER, pSMsg);
		}
	}
	else if (pAccept->RequestType == REQUEST_TYPE_GUILD_WAR)
	{
		if (FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber)
			|| FALSE == IS_VALID_UNIQUE_NUMBER(pSourceSocket->m_character.GuildUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0054);
			return RES_BREAK;
		}

		if (m_RequestHandler.GetPeerClientIndex() != pSourceSocket->m_character.ClientIndex
			|| pSourceSocket->m_RequestHandler.GetPeerClientIndex() != m_character.ClientIndex)
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0055);
			return RES_BREAK;
		}

		if (!ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber)
			|| !ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(pSourceSocket->m_character.CharacterUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0056);
			return RES_BREAK;
		}

		if (m_character.MapChannelIndex != pSourceSocket->m_character.MapChannelIndex)
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0057);
			return RES_BREAK;
		}

		// 요청 상태 초기화
		m_RequestHandler.Reset();
		pSourceSocket->m_RequestHandler.Reset();

		// 길드전 시작
		ms_pFieldIOCP->m_GuildWarManager.StartGuildWar(m_character.GuildUniqueNumber, pSourceSocket->m_character.GuildUniqueNumber, &m_character.MapChannelIndex);
	}
	else
	{
		// 지원되지 않는 타입인 경우
		SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pAccept->RequestType);
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_REQUEST_REJECT_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_REQUEST_REJECT_REQUEST	*pReject;
	BOOL							bSendRejectOK = FALSE;

	nRecvTypeSize = sizeof(MSG_FC_REQUEST_REJECT_REQUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pReject = (MSG_FC_REQUEST_REJECT_REQUEST*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 상대방 확인
	CFieldIOCPSocket *pSourceSocket = NULL;
	if (pReject->SourceClientIndex != 0)
	{
		pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocket(pReject->SourceClientIndex);
		if (pSourceSocket == NULL || !pSourceSocket->IsUsing() || pSourceSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER, pReject->SourceClientIndex);
			return RES_BREAK;
		}
	}
	else
	{
		pSourceSocket = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterName(pReject->SourceCharacterName);
		if (pSourceSocket == NULL || !pSourceSocket->IsUsing() || pSourceSocket->m_PeerSocketType != ST_CLIENT_TYPE)
		{
			SendErrorMessage(T_FC_REQUEST_ACCEPT_REQUEST, ERR_COMMON_NO_SUCH_CHARACTER, 0, 0, pReject->SourceCharacterName);
			return RES_BREAK;
		}
	}

//	// 거리가 멀어서 불가
//	if (D3DXVec3Length(&(m_character.PositionVector - pSourceSocket->m_character.PositionVector)) > REQUERED_REQUEST_DISTANCE)
//	{
//		SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_TOO_FAR_TO_DO);
//		return RES_BREAK;
//	}

	///////////////////////////////////////////////////////////////////////////
	// Request Type별 처리 루틴
	///////////////////////////////////////////////////////////////////////////
	if (pReject->RequestType == REQUEST_TYPE_PARTY_BATTLE)
	{
		// 파티 확인
		CFieldParty *pMeFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
		if (pMeFParty == NULL)
		{
			SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY, pReject->RequestType);
			return RES_BREAK;
		}

		// 파티장 확인
		if (m_character.CharacterUniqueNumber != pMeFParty->GetMasterCharacterUniqueNumber())
		{
			SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED, m_character.CharacterUniqueNumber, pMeFParty->GetMasterCharacterUniqueNumber());
			return RES_BREAK;
		}

		// 상대방 파티 확인
		CFieldParty *pSourceParty = pSourceSocket->m_pFieldParty;
		if (pSourceParty == NULL)
		{
			SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_NO_SUCH_PARTY, pReject->SourceClientIndex, 0, "Source Party");
			return RES_BREAK;
		}

		// 상대방 파티장 확인
		if (pSourceParty->GetMasterCharacterUniqueNumber() != pSourceSocket->m_character.CharacterUniqueNumber)
		{
			SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_PARTY_PERMISSION_DENIED, pReject->SourceClientIndex, 0, "Source Party");
			return RES_BREAK;
		}

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

		// reset party battle
		pMeFParty->m_PeerBattleRequesterPartyID = 0;
		pSourceParty->m_PeerBattleRequesterPartyID = 0;

		bSendRejectOK = TRUE;
	}
	else if (pReject->RequestType == REQUEST_TYPE_GUILD_WAR)
	{
		if (FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber)
			|| FALSE == IS_VALID_UNIQUE_NUMBER(pSourceSocket->m_character.GuildUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0058);
			return RES_BREAK;
		}

		if (m_RequestHandler.GetPeerClientIndex() != pSourceSocket->m_character.ClientIndex
			|| pSourceSocket->m_RequestHandler.GetPeerClientIndex() != m_character.ClientIndex)
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0059);
			return RES_BREAK;
		}

		if (!ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(m_character.CharacterUniqueNumber)
			|| !ms_pFieldIOCP->m_GuildWarManager.CheckGuildCommander(pSourceSocket->m_character.CharacterUniqueNumber))
		{
			SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0060);
			return RES_BREAK;
		}

		// 요청 상태 초기화
		m_RequestHandler.Reset();
		pSourceSocket->m_RequestHandler.Reset();

		bSendRejectOK = TRUE;
	}
	else
	{
		// 지원되지 않는 타입인 경우
		SendErrorMessage(T_FC_REQUEST_REJECT_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pReject->RequestType);
		return RES_BREAK;
	}

	if (bSendRejectOK)
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_REQUEST_REJECT_REQUEST_OK, T_FC_REQUEST_REJECT_REQUEST_OK, pRejectOK, pRejectOKBuf);
		pRejectOK->PeerClientIndex = m_character.ClientIndex;
		STRNCPY_MEMSET(pRejectOK->PeerCharacterName, m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
		pRejectOK->RequestType = pReject->RequestType;
		pSourceSocket->SendAddData(pRejectOKBuf, MSG_SIZE(MSG_FC_REQUEST_REJECT_REQUEST_OK));
	}

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// FC_CITY - 도시용 프로토콜
ProcessResult CFieldIOCPSocket::Process_FC_CITY_GET_BUILDING_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_GET_BUILDING_LIST,
									MSG_FC_CITY_GET_BUILDING_LIST, pGetBuildingList);

	if (pGetBuildingList->MapChannelIndex != m_pCurrentFieldMapChannel->m_MapChannelIndex)
	{
		SendErrorMessage(T_FC_CITY_GET_BUILDING_LIST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
		return RES_BREAK;
	}

	SendAddDataBuffer(m_pCurrentFieldMapChannel->m_pFieldMapProject->m_buffGetBuildingListOK);

	return RES_RETURN_TRUE;
}

// 2004-11-10 by cmkwon, Process_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST로 대체함
//ProcessResult CFieldIOCPSocket::Process_FC_CITY_GET_WARP_TARGET_MAP_LIST(const char* pPacket, int nLength, int &nBytesUsed)
//{
//	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_GET_WARP_TARGET_MAP_LIST,
//									MSG_FC_CITY_GET_WARP_TARGET_MAP_LIST, pGetWarpMapList);
//
//	if (pGetWarpMapList->MapChannelIndex != m_pCurrentFieldMapChannel->m_MapChannelIndex)
//	{
//		SendErrorMessage(T_FC_CITY_GET_WARP_TARGET_MAP_LIST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
//		return RES_BREAK;
//	}
//
//	SendAddDataBuffer(m_pCurrentFieldMapChannel->m_pFieldMapProject->m_buffGetWarpTargetMapListOK);
//	return RES_RETURN_TRUE;
//}

ProcessResult CFieldIOCPSocket::Process_FC_CITY_REQUEST_ENTER_BUILDING(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_REQUEST_ENTER_BUILDING,
									MSG_FC_CITY_REQUEST_ENTER_BUILDING, pRequestEnterBuidling);

	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pRequestEnterBuidling->BuildingIndex);
	if (pBuildingNPC == NULL)
	{
		SendErrorMessage(T_FC_CITY_REQUEST_ENTER_BUILDING, ERR_PROTOCOL_NO_SUCH_SHOP, pRequestEnterBuidling->BuildingIndex);
		return RES_BREAK;
	}
			
	// 현재 들어가 있는 건물 저장
	m_pCurrentBuildingNPC = pBuildingNPC;

	// MSG_FC_CITY_REQUEST_ENTER_BUILDING_OK 전송
	INIT_MSG_WITH_BUFFER(MSG_FC_CITY_REQUEST_ENTER_BUILDING_OK, T_FC_CITY_REQUEST_ENTER_BUILDING_OK, pMsgEnterBuildingOK, pMsgEnterBuildingOKBuf);
	pMsgEnterBuildingOK->BuildingIndex					= pBuildingNPC->BuildingIndex;
// 2006-02-08 by cmkwon
//	pMsgEnterBuildingOK->fCityWarTexRate				= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pRequestEnterBuidling->BuildingIndex, m_character.GuildUniqueNumber);
	pMsgEnterBuildingOK->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	SendAddData(pMsgEnterBuildingOKBuf, MSG_SIZE(MSG_FC_CITY_REQUEST_ENTER_BUILDING_OK));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_CITY_CHECK_WARP_STATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	INIT_MSG_OF_SIZE(MSG_FC_CITY_CHECK_WARP_STATE_OK, T_FC_CITY_CHECK_WARP_STATE_OK, pMsgCheckWarpStateOK, pMsgCheckWarpStateOKBuf);
	pMsgCheckWarpStateOK->Err = ERR_NO_ERROR;

	// 파티전 중이면 워프 불가
	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pFParty)
	{
		mt_auto_lock(&pFParty->m_ListPartyMember);

		if (pFParty->m_PartyBattle.IsUsing())
		{
			pMsgCheckWarpStateOK->Err = ERR_PROTOCOL_ALREADY_PARTY_BATTLE;
			SendAddData(pMsgCheckWarpStateOKBuf, MSG_SIZE(MSG_FC_CITY_CHECK_WARP_STATE_OK));
			return RES_RETURN_TRUE;
		}
	}

	// no error
	pMsgCheckWarpStateOK->Err = ERR_NO_ERROR;
	SendAddData(pMsgCheckWarpStateOKBuf, MSG_SIZE(MSG_FC_CITY_CHECK_WARP_STATE_OK));

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		지도자 후보 리스트 전송 
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	ATUM_DATE_TIME tmCurrentTime;
	tmCurrentTime.SetCurrentDateTime();
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPollDateRange(&tmCurrentTime))
	{// 2007-11-20 by dhjin, 선거 등록 기간인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_LIST, ERR_REQ_NOT_POLLDATE_ALL_RANGE);
		return RES_BREAK;
	}
	
	this->ms_pFieldIOCP->m_InflWarManager.SendLeaderCandidateList(this);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		지도자 후보 정보 전송
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO
		, MSG_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO, pRMsg);

	if(!this->IsValidCharacter())
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REQUEST_LEADER_CANDIDATE_INFO, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_SelectLeaderCandidateInfoByRealTimeVariable, this, 0, NULL, NULL, pRMsg->LeaderCandidateNum, this->m_character.InfluenceType);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REG_LEADER_CANDIDATE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		지도자 후보 등록
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REG_LEADER_CANDIDATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_POLL_REG_LEADER_CANDIDATE
		, MSG_FC_CITY_POLL_REG_LEADER_CANDIDATE, pRMsg);

	if(!this->IsValidCharacter()
		|| this->m_character.CharacterUniqueNumber != pRMsg->CharacterUID
		|| this->m_character.GuildUniqueNumber != pRMsg->GuildUID)
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REG_LEADER_CANDIDATE, ERR_INVALID_CHARACTER, 13000);
		return RES_BREAK;
	}

	// 2007-10-30 by dhjin, 조건 체크
	ATUM_DATE_TIME tmCurrentTime;
	tmCurrentTime.SetCurrentDateTime();
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPollDateByApplication(&tmCurrentTime))
	{// 2007-10-30 by dhjin, 후보 등록 기간인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REG_LEADER_CANDIDATE, ERR_REQ_NOT_POLLDATE_APPLICATION, 14000);
		return RES_BREAK;
	}
	
	//////////////////////////////////////////////////////////////////////////
	// 2008-02-21 by dhjin, 전진기지 여단장은 지도자 후보가 될수 없다.
	if(this->ms_pFieldIOCP->m_OutPostManager.CheckOutPostPossessByGuildUID(this->m_character.GuildUniqueNumber))
	{
		SendErrorMessage(T_FC_CITY_POLL_REG_LEADER_CANDIDATE, ERR_REQ_NOT_LEADER_CANDIDATE, 15000);
		return RES_BREAK;
	}

	if(LEADERCANDIDATE_REQUIRE_LEVEL > this->m_character.Level
		|| LEADERCANDIDATE_REQUIRE_PROPENSITY > this->m_character.Propensity)
	{// 2007-10-30 by dhjin, 후보 조건 체크
		SendErrorMessage(T_FC_CITY_POLL_REG_LEADER_CANDIDATE, ERR_REQ_NOT_LEADER_CANDIDATE, 16000);
		return RES_BREAK;
	}

	if(this->ms_pFieldIOCP->m_InflWarManager.CheckLeaderCandidateUser(this->m_character.AccountUniqueNumber, this->m_character.CharacterUniqueNumber))
	{// 2007-11-01 by dhjin, 이미 등록한 유저이다.
		SendErrorMessage(T_FC_CITY_POLL_REG_LEADER_CANDIDATE, ERR_REQ_NOT_LEADER_CANDIDATE, 17000);
		return RES_BREAK;
	}
	
	QPARAM_INSERT_LEADER_CANDIDATE *pQParam = new QPARAM_INSERT_LEADER_CANDIDATE;
	pQParam->Influence			= this->m_character.InfluenceType;
	pQParam->ReqGuildMemberNum	= LEADERCANDIDATE_REQUIRE_GUILDMEMBERNUM;
	pQParam->ReqGuildFame		= LEADERCANDIDATE_REQUIRE_GUILDFAME;
	pQParam->AccountUID			= this->m_character.AccountUniqueNumber;
	pQParam->CharacterUID		= this->m_character.CharacterUniqueNumber;
	pQParam->GuildUID			= this->m_character.GuildUniqueNumber;
	STRNCPY_MEMSET(pQParam->GuildName, this->m_character.GuildName, SIZE_MAX_GUILD_NAME);
	STRNCPY_MEMSET(pQParam->CharacterName, this->m_character.CharacterName, SIZE_MAX_CHARACTER_NAME);
	STRNCPY_MEMSET(pQParam->CampaignPromises, pRMsg->CampaignPromises, SIZE_MAX_CAMPAIGNPROMISES);	

	this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertLeaderCandidate, this, 0, pQParam);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_DELETE_LEADER_CANDIDATE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		지도자 후보 탈퇴
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_DELETE_LEADER_CANDIDATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE
		, MSG_FC_CITY_POLL_DELETE_LEADER_CANDIDATE, pRMsg);

	if(!this->IsValidCharacter()
		|| this->m_character.CharacterUniqueNumber != pRMsg->CharacterUID)
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2007-10-30 by dhjin, 조건 체크
	ATUM_DATE_TIME tmCurrentTime;
	tmCurrentTime.SetCurrentDateTime();
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPollDateByApplication(&tmCurrentTime))
	{// 2007-10-30 by dhjin, 후보 등록 기간인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE, ERR_REQ_NOT_POLLDATE_APPLICATION);
		return RES_BREAK;
	}
	
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPossibleDeleteLeaderCandidate(this->m_character.CharacterUniqueNumber))
	{// 2007-11-02 by dhjin, 후보 탈퇴가 가능한지 체크
		SendErrorMessage(T_FC_CITY_POLL_DELETE_LEADER_CANDIDATE, ERR_ALREADY_DELETE_LEADER_CANDIDATE);
		return RES_BREAK;
	}
	
	this->ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateLeaderDeleteCandidate, this, 0, NULL, NULL);

	CAtumLogSender::SendLogMessageDeleteLeaderCandidate(this->m_character.CharacterUniqueNumber);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_VOTE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		투표
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_VOTE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_CITY_POLL_VOTE
		, MSG_FC_CITY_POLL_VOTE, pRMsg);

	if(!this->IsValidCharacter()
		|| this->m_character.CharacterUniqueNumber != pRMsg->VoteCharacterUID)
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_VOTE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 2007-10-30 by dhjin, 조건 체크
	ATUM_DATE_TIME tmCurrentTime;
	tmCurrentTime.SetCurrentDateTime();
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPollDateByVote(&tmCurrentTime))
	{// 2007-10-30 by dhjin, 투표 기간인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_VOTE, ERR_REQ_NOT_POLLDATE_VOTE);
		return RES_BREAK;
	}
	
	if(LEADERVOTE_REQUIRE_LEVEL > this->m_character.Level
		|| !COMPARE_INFLUENCE(this->m_character.InfluenceType, INFLUENCE_TYPE_VCN|INFLUENCE_TYPE_ANI))
	{// 2007-10-30 by dhjin, 
		SendErrorMessage(T_FC_CITY_POLL_VOTE, ERR_REQ_NOT_VOTE);
		return RES_BREAK;
	}	

	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.CheckPossibleVoterUser(this->m_character.AccountUniqueNumber))
	{// 2007-10-31 by dhjin, 투표한 유저인지 체크
		SendErrorMessage(T_FC_CITY_POLL_VOTE, ERR_ALREADY_VOTE);
		return RES_BREAK;
	}

	// 2007-10-31 by dhjin, 투표 점수 가져오기
	INT PollPoint = this->ms_pFieldIOCP->GetPollPointActionByLevel(this->m_character.Level);
	// 2007-10-31 by dhjin, 지도자 후보에게 득표
	if(FALSE == this->ms_pFieldIOCP->m_InflWarManager.LeaderCandidateVote(pRMsg->LeaderCandidateNum, this->m_character.InfluenceType, PollPoint))
	{
		SendErrorMessage(T_FC_CITY_POLL_VOTE, ERR_ALREADY_LEADER_CANDIDATE);
		return RES_BREAK;
	}
	
	this->SendAddMessageType(T_FC_CITY_POLL_VOTE_OK);

	CAtumLogSender::SendLogMessagePollVote(this->m_character.CharacterUniqueNumber, pRMsg->CharacterUID);

	SVOTER_LIST		VoterUserInfo;
	MEMSET_ZERO(&VoterUserInfo, sizeof(SVOTER_LIST));
	VoterUserInfo.AccountUID		= this->m_character.AccountUniqueNumber;
	VoterUserInfo.CharacterUID		= this->m_character.CharacterUniqueNumber;
	VoterUserInfo.LeaderCandidateNum= pRMsg->LeaderCandidateNum;
	this->ms_pFieldIOCP->m_InflWarManager.InsertVoterUser(&VoterUserInfo);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_POLL_DATE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		선거 일정
/// \author		dhjin
/// \date		2007-10-29 ~ 2007-10-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_POLL_REQUEST_POLL_DATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{// 2007-10-29 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_POLL_REQUEST_POLL_DATE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	this->ms_pFieldIOCP->m_InflWarManager.SendPollDate(this);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_WARINFO_INFLUENCE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		세력 정보
/// \author		dhjin
/// \date		2007-12-03 ~ 2007-12-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_WARINFO_INFLUENCE(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{// 2007-12-03 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_WARINFO_INFLUENCE, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	this->ms_pFieldIOCP->m_InflWarManager.SendCityInfoInfluence(this);
	
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_CITY_WARINFO_OUTPOST(const char* pPacket, int nLength, int &nBytesUsed)	
/// \brief		전진기지 정보
/// \author		dhjin
/// \date		2007-12-03 ~ 2007-12-03
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_CITY_WARINFO_OUTPOST(const char* pPacket, int nLength, int &nBytesUsed)
{
	if(!this->IsValidCharacter())
	{// 2007-12-03 by dhjin, 유효한 유저인지 체크 
		SendErrorMessage(T_FC_CITY_WARINFO_OUTPOST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_CITY_WARINFO_OUTPOST_OK, T_FC_CITY_WARINFO_OUTPOST_OK, pSOutPostWarInfo, SendBuf);
	pSOutPostWarInfo->CityWarInfoOutpostListCount = this->ms_pFieldIOCP->m_OutPostManager.MakeAllOutPostInfoMsg((SCITY_WARINFO_OUTPOST*)(SendBuf+MSG_SIZE(MSG_FC_CITY_WARINFO_OUTPOST_OK)));
	if(0 < pSOutPostWarInfo->CityWarInfoOutpostListCount)
	{
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_CITY_WARINFO_OUTPOST_OK)+pSOutPostWarInfo->CityWarInfoOutpostListCount*sizeof(SCITY_WARINFO_OUTPOST));
	}

	return RES_RETURN_TRUE;
}





///////////////////////////////////////////////////////////////////////////////
// FC_QUEST
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_START(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FC_QUEST_REQUEST_START	*pRequestStartQuest;

	nRecvTypeSize = sizeof(MSG_FC_QUEST_REQUEST_START);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pRequestStartQuest = (MSG_FC_QUEST_REQUEST_START*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-04-26 by dhjin, 아레나 맵 에서는 퀘스트를 시작할 수 없다.
	if(IS_MAP_INFLUENCE_ARENA(this->m_pCurrentFieldMapChannel->GetMapInfluenceTypeW()))
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, ERR_ARENA_STATE);
		return RES_BREAK;
	}

	// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 퀘스트 시작/완료 불가
	if(g_pFieldGlobal->GetIsJamboreeServer())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, ERR_JAMBOREE_NO_SUCH_CHARACTER);
		return RES_BREAK;
	}

	int nErrP1 = ERR_NO_ERROR;
	Err_t err = this->CheckQuestStartByQuestIndex(&nErrP1, pRequestStartQuest);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, err, nErrP1);
		return RES_BREAK;		
	}
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_QUEST_ACCEPT_QUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FC_QUEST_ACCEPT_QUEST	*pAcceptQuest;

	nRecvTypeSize = sizeof(MSG_FC_QUEST_ACCEPT_QUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_QUEST_ACCEPT_QUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pAcceptQuest = (MSG_FC_QUEST_ACCEPT_QUEST*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}
	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 = m_mapQuest.findNoLock_Ptr(pAcceptQuest->QuestIndex);
	if (NULL == pFCharQuest)
	{
		SendErrorMessage(T_FC_QUEST_ACCEPT_QUEST, ERR_PROTOCOL_NO_SUCH_CHARACTER_QUEST, pAcceptQuest->QuestIndex);
		return RES_BREAK;
	}

	CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
	if (pQuestInfo == NULL)
	{
		SendErrorMessage(T_FC_QUEST_ACCEPT_QUEST, ERR_PROTOCOL_NO_SUCH_QUEST_INFO, pAcceptQuest->QuestIndex);
		return RES_BREAK;
	}

	if (pQuestInfo->QuestEndType == QUEST_END_TYPE_IMMEDIATE)
	{
		// 바로 결과 처리한다

		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 (!ProcessQuestResult(&nExpOfCompensation, pQuestInfo, 0, pSuccessResult
							, (QUEST_PAY_ITEM_INFO*)(pSuccessResultBuf+MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT))))
		{
			SendErrorMessage(T_FC_QUEST_ACCEPT_QUEST, 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				= pFCharQuest->QuestIndex;
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);

			m_mapQuest.deleteLock(pFCharQuest->QuestIndex);
		}
		else
		{
			// Update Field
			pFCharQuest->QuestState = QUEST_STATE_COMPLETED;

			// Update DB
			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);

			// send log
			CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, pQUpdateQuest->QuestIndex);
		}

		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));
	}
	else if (pQuestInfo->QuestEndType == QUEST_END_TYPE_REQESTED_BY_CLIENT)
	{
		// 클라이언트가 결과 요청할 때 처리한다, 여기서는 do nothing
	}

	return RES_RETURN_TRUE;
}

BOOL CFieldIOCPSocket::InsertQuestPayItem(QUEST_PAY_ITEM *i_pQuestPayItem)
{
	if (!IS_SAME_UNITKIND(m_character.UnitKind, i_pQuestPayItem->ToUnitKind))
	{
		return FALSE;
	}

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

	ITEM *pItemInfo = ms_pFieldIOCP->GetItemInfo(i_pQuestPayItem->ItemNum);
	if (i_pQuestPayItem->Count == 1)
	{
		ITEM_GENERAL *pNewItemGeneral = (ITEM_GENERAL*)m_ItemManager.MakeNewItem(i_pQuestPayItem->ItemNum, ITEM_IN_CHARACTER, pItemInfo);
		if (pNewItemGeneral == NULL)
		{
			return FALSE;
		}

		if (i_pQuestPayItem->ToBeAttached)
		{
			pNewItemGeneral->Wear = WEAR_ATTACHED;
			pNewItemGeneral->ItemWindowIndex = pNewItemGeneral->ItemInfo->Position;
		}

		// 2008-03-28 by cmkwon, PlayTime 관련 제한 버그 수정 - 퀘스트 보상이기 때문에 PlayTime 관련 제한 체크 하지 않아야 함
		//if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pNewItemGeneral, IUT_QUEST))
		if(FALSE == m_ItemManager.InsertItemGeneralByPointer(pNewItemGeneral, IUT_QUEST, FALSE, ITEM_IN_CHARACTER, TRUE, TRUE, INVALID_UNIQUE_NUMBER, FALSE))
		{
			SAFE_DELETE(pNewItemGeneral);
		}
	}
	else
	{
		m_ItemManager.InsertItemBaseByItemNum(i_pQuestPayItem->ItemNum, i_pQuestPayItem->Count, IUT_QUEST);
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			
/// \brief		
/// \author		cmkwon
/// \date		2005-01-30 ~ 2005-01-30
/// \warning	함수 내부에서만 m_mapQuest가 Lock으로 보호된다, 리턴받은것을 유효하게 사용하려면 자체적으로 lock처리를 해야한다
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsExistQuestCityWar(void)
{
	mt_auto_lock mtAuto(&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->IsCityWar)
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}

BOOL CFieldIOCPSocket::CityWarQuestResult(INT i_questIdx, BOOL i_bSuccess)
{
	mt_auto_lock mtA(&m_mapQuest);

	CFieldCharacterQuest *pFCharQuest = this->m_mapQuest.findNoLock_Ptr(i_questIdx);
	if(NULL == pFCharQuest
		|| NULL == pFCharQuest->GetQuestInfo())
	{
		return FALSE;
	}

	if(FALSE == i_bSuccess)
	{// 도시점령전 실패 - 퀘스트를 삭제한다

		INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_DISCARD_QUEST_OK, T_FC_QUEST_DISCARD_QUEST_OK, pMsgDiscard, BufDiscard);
		pMsgDiscard->QuestIndex		= pFCharQuest->QuestIndex;
		pMsgDiscard->IsDiscarded	= TRUE;
		SendAddData(BufDiscard, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));
		
		// 퀘스트 지우기 - DB
		QPARAM_DELETE_QUEST *pQDeleteQuest = new QPARAM_DELETE_QUEST;
		pQDeleteQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQDeleteQuest->QuestIndex				= pFCharQuest->QuestIndex;
			
		m_mapQuest.deleteNoLock(i_questIdx);			// 퀘스트를 제거한다
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);
	}
	else
	{// 도시점령전 성공 - 퀘스트 완료

		if(QUEST_STATE_COMPLETED == pFCharQuest->QuestState)
		{			
			SendString128(STRING_128_USER_NOTICE, STRMSG_S_F2NOTIFY_0061);
		}
		else
		{
			pFCharQuest->QuestState					= QUEST_STATE_COMPLETED;

			// Update DB
			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);

			// send log
			CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, pQUpdateQuest->QuestIndex);	

			INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT, T_FC_QUEST_REQUEST_SUCCESS_RESULT, pSuccessResult, pSuccessResultBuf);
			pSuccessResult->QuestIndex		= pFCharQuest->QuestIndex;
			pSuccessResult->IsSuccessful	= TRUE;
			SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT));
		}
	}
				
	return TRUE;
}

BOOL CFieldIOCPSocket::IsCheckQuestComplited(INT i_questIdx)
{
	mt_auto_lock mtA(&m_mapQuest);
	CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(i_questIdx);
	if (NULL == pFCharQuest
		|| QUEST_STATE_COMPLETED != pFCharQuest->QuestState)
	{
		return FALSE;
	}

	return TRUE;
}

BOOL CFieldIOCPSocket::ProcessQuestStartAction(MapIndex_t *o_pWarpMapIndex, BOOL *o_pbPartyWarp, CQuest *pQuestInfo)
{
	int i = 0;

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

	// StartPayItem이 있다면 삽입
	for (i = 0; i < pQuestInfo->StartPayItemVector.size(); i++)
	{
		InsertQuestPayItem(&pQuestInfo->StartPayItemVector[i]);
	}

	// StartDelItem이 있다면 제거
	for (i = 0; i < pQuestInfo->StartDelItemVector.size(); i++)
	{
		m_ItemManager.DeleteItemFromCharacterByItemNum(pQuestInfo->StartDelItemVector[i].ItemNum, pQuestInfo->StartDelItemVector[i].Count, IUT_QUEST);
	}

	// 시작 맵으로 워프
	*o_pWarpMapIndex	= pQuestInfo->StartMapIndex;
	*o_pbPartyWarp		= pQuestInfo->IsPartyWarp();	// 2006-03-24 by cmkwon

	return TRUE;
}

// 2007-03-06 by cmkwon, 보상경험치를 넘기는 output 인자추가(int *o_pnExpOfCompensation)
BOOL CFieldIOCPSocket::ProcessQuestResult(int *o_pnExpOfCompensation, CQuest *pQuestInfo, int i_nQuestResultParam/*=0*/, MSG_FC_QUEST_REQUEST_SUCCESS_RESULT * o_pQuestResult /* = NULL*/, QUEST_PAY_ITEM_INFO * o_QuestPayItemInfo/* = NULL*/)
{
	*o_pnExpOfCompensation		= 0;	// 2007-03-06 by cmkwon

	int i = 0;

 	MSG_FL_LOG_QUEST_COMPENSATION pMsgQuestCompensation;	// 2007-01-16 by dhjin, 퀘스트 보상 구조체 
	string		szCompensationItemList;	// 2007-01-16 by dhjin, 퀘스트 보상 아이템 리스트
	MEMSET_ZERO(&pMsgQuestCompensation,sizeof(MSG_FL_LOG_QUEST_COMPENSATION));
	pMsgQuestCompensation.CharacterUniqueNumber		= this->m_character.CharacterUniqueNumber;			// 2007-04-18 by cmkwon
	pMsgQuestCompensation.CurrentMapIndex			= this->m_character.MapChannelIndex.MapIndex;		// 2007-04-18 by cmkwon
	pMsgQuestCompensation.CurrentPosition			= this->m_character.PositionVector;					// 2007-04-18 by cmkwon
	pMsgQuestCompensation.QuestIndex				= pQuestInfo->QuestIndex;							// 2007-04-18 by cmkwon


	////////////////////////////////////////////////////////
	// 퀘스트 수행 시 주어지는 아이템
	////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////////////////////	
	// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 퀘스트 보상 아이템 처리, 
	BOOL	bNoInsertItem	= FALSE;
	float	fDropRateOfGameRestriction	= 0.0f;			// 2008-04-08 by cmkwon, 기본값	
	if(this->GPGetApplyRateByGamePlayingTime(&fDropRateOfGameRestriction)
		&& fDropRateOfGameRestriction <= 0.0f)
	{
		bNoInsertItem		= TRUE;
	}

	for (i = 0; i < pQuestInfo->EndPayItemVector.size(); i++)
	{
		if(bNoInsertItem)
		{// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 보상 아이템 없음
			break;
		}

		QUEST_PAY_ITEM &tmpQestPayItem = pQuestInfo->EndPayItemVector[i];

		if (!IS_SAME_UNITKIND(tmpQestPayItem.ToUnitKind, m_character.UnitKind))
		{
			// 해당 unitkind가 다름
			continue;
		}

		int nPayItemCount = 0;
		if (tmpQestPayItem.PerItem != 0)
		{
			ITEM_GENERAL *pItemGeneral = 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 (!m_ItemManager.InsertItemBaseByItemNum(tmpQestPayItem.ItemNum, nPayItemCount, IUT_QUEST))
		{
			g_pFieldGlobal->WriteSystemLogEX(TRUE,
				"FATAL ERROR@CFieldIOCPSocket::ProcessQuestResult(): cannot insert item %d to %s\r\n",
				tmpQestPayItem.ItemNum, GetCharacterString(&m_character, string()));
			continue;
		}
		
		// 2007-01-16 by dhjin, 퀘스트 보상 아이템 리스트
		this->ADDString(&szCompensationItemList, tmpQestPayItem.PerItem);		// 2007-04-18 by cmkwon, 소스 ItemNum도 추가
		szCompensationItemList += ".";
		this->ADDString(&szCompensationItemList, tmpQestPayItem.ItemNum);
		szCompensationItemList += ".";
		o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemNum	= tmpQestPayItem.ItemNum;		// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 번호)
		this->ADDString(&szCompensationItemList, nPayItemCount);
		szCompensationItemList += "|";
		o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemCount	= nPayItemCount;			// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 수)
		o_pQuestResult->QuestPayInfoListCount++;
	}

	for (i = 0; i < pQuestInfo->EndRandomPayItemVector.size(); i++)
	{
		if(bNoInsertItem)
		{// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 보상 아이템 없음
			break;
		}

		QUEST_RANDOM_PAY_ITEM &randomPayItem = pQuestInfo->EndRandomPayItemVector[i];
		ITEM_GENERAL *pPerItemGeneral = m_ItemManager.GetFirstItemGeneralByItemNum(randomPayItem.PerItemNum);
		if (pPerItemGeneral == NULL)
		{
			continue;
		}
		int nPayCount = pPerItemGeneral->CurrentCount;

		for (int k = 0; k < nPayCount; k++)
		{
			int nRand = RAND100();
			int nTotalProb = 0;
			for (int j = 0; j < COUNT_RANDOM_PAY_ITEM; j++)
			{
				nTotalProb += randomPayItem.ItemWithCountProb[j].Prob100;
				if (nRand < nTotalProb)
				{
// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 아래와 같이 수정
// 					m_ItemManager.InsertItemBaseByItemNum(randomPayItem.ItemWithCountProb[j].ItemNum,
// 														randomPayItem.ItemWithCountProb[j].Count, IUT_QUEST);
// 					// 2007-01-16 by dhjin, 퀘스트 보상 아이템 리스트
// 					this->ADDString(&szCompensationItemList, randomPayItem.ItemWithCountProb[j].ItemNum);
// 					szCompensationItemList += ".";
// 					o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemNum	= randomPayItem.ItemWithCountProb[j].ItemNum;		// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 번호)
// 					this->ADDString(&szCompensationItemList, randomPayItem.ItemWithCountProb[j].Count);
// 					szCompensationItemList += "|";
// 					o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemCount	= randomPayItem.ItemWithCountProb[j].Count;			// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 수)
// 					o_pQuestResult->QuestPayInfoListCount++;
					
					// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 퀘스트 보상 아이템에 드랍율 적용 
					int nPayItemCount = max(1, (int)(randomPayItem.ItemWithCountProb[j].Count * fDropRateOfGameRestriction));
					m_ItemManager.InsertItemBaseByItemNum(randomPayItem.ItemWithCountProb[j].ItemNum, nPayItemCount, IUT_QUEST);
					// 2007-01-16 by dhjin, 퀘스트 보상 아이템 리스트
					this->ADDString(&szCompensationItemList, randomPayItem.ItemWithCountProb[j].ItemNum);
					szCompensationItemList += ".";
					o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemNum	= randomPayItem.ItemWithCountProb[j].ItemNum;		// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 번호)
					this->ADDString(&szCompensationItemList, nPayItemCount);
					szCompensationItemList += "|";
					o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemCount	= nPayItemCount;			// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 수)
					o_pQuestResult->QuestPayInfoListCount++;
					break;
				}
			}
		}
	}

// 2008-04-08 by cmkwon, 게임 제한 시스템 수정 - 현재 사용하지 않는 명령어 부분임. 다시 사용한다면 체크 많이 필요함
// 	for (i = 0; i < pQuestInfo->EndPayMixItemVector.size(); i++)
// 	{
// 		ITEM_MIXING_INFO &payMixItemInfo = pQuestInfo->EndPayMixItemVector[i];
// 
// 		int nTotalItemCountToInsert = 0;
// 
// 		while (TRUE)
// 		{
// 			BOOL bSourceItemCheckOK = TRUE;
// 			int j = 0;
// 
// 			// 아이템 삭제
// 			for (j = 0; j < payMixItemInfo.NumOfSourceItems; j++)
// 			{
// 				ITEM_GENERAL *pSourceItemGeneral = m_ItemManager.GetFirstItemGeneralByItemNum(payMixItemInfo.SourceItem[j].ItemNum);
// 
// 				if (pSourceItemGeneral == NULL
// 					|| pSourceItemGeneral->CurrentCount < payMixItemInfo.SourceItem[j].Count)
// 				{
// 					bSourceItemCheckOK = FALSE;
// 					break;
// 				}
// 			}
// 
// 			if (bSourceItemCheckOK)
// 			{
// 				for (j = 0; j < payMixItemInfo.NumOfSourceItems; j++)
// 				{
// 					ITEM_GENERAL *pSourceItemGeneral = m_ItemManager.GetFirstItemGeneralByItemNum(payMixItemInfo.SourceItem[j].ItemNum);
// 
// 					if (pSourceItemGeneral != NULL)
// 					{
// 						if (IS_COUNTABLE_ITEM(pSourceItemGeneral->Kind))
// 						{
// 							m_ItemManager.UpdateItemCountByPointer(pSourceItemGeneral, -payMixItemInfo.SourceItem[j].Count, IUT_QUEST);
// 						}
// 						else
// 						{
// 							SendString128(STRING_128_USER_ERR, STRMSG_S_F2NOTIFY_0062);
// 						}
// 					}
// 				}
// 
// 				// 확률 계산 및 적용
// 				Prob10K_t prob = RAND10K();
// 				if (prob <= payMixItemInfo.MixingProbability)
// 				{
// 					// 성공
// 					nTotalItemCountToInsert++;
// 				}
// 				else
// 				{
// 					// 실패, do nothing
// 					SendString128(STRING_128_ADMIN_CMD, "PayMixItem %d < %d", (int)payMixItemInfo.MixingProbability, (int)prob);
// 				}
// 			}
// 			else
// 			{
// 				// 더 이상 처리 할 수 없는 경우
// 				break;
// 			}
// 		} // end - while(TRUE)
// 
// 		// countable 아이템이 중복되어서 들어가는 경우 최소화하기 위해 각각 따로 넣지 않고
// 		// 한번에 모아서 넣는다. 원래는 nTotalItemCountToInsert++; 하는 곳에서 하나씩 추가함. 20041027, kelovon
// 		if (nTotalItemCountToInsert > 0)
// 		{
// 			m_ItemManager.InsertItemBaseByItemNum(payMixItemInfo.TargetItemNum, nTotalItemCountToInsert, IUT_QUEST);
// 			// 2007-01-16 by dhjin, 퀘스트 보상 아이템 리스트
// 			this->ADDString(&szCompensationItemList, payMixItemInfo.TargetItemNum);
// 			szCompensationItemList += ".";
// 			o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemNum	= payMixItemInfo.TargetItemNum;		// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 번호)
// 			this->ADDString(&szCompensationItemList, nTotalItemCountToInsert);
// 			szCompensationItemList += "|";
// 			o_QuestPayItemInfo[o_pQuestResult->QuestPayInfoListCount].ItemCount	= nTotalItemCountToInsert;			// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송 (아이템 수)
// 			o_pQuestResult->QuestPayInfoListCount++;
// 		}
// 	}

	if (pQuestInfo->EndPayBonusStat > 0)
	{
		// 보너스 스탯만 변경함		
		m_character.BonusStat		+= pQuestInfo->EndPayBonusStat;
		m_character.BonusStatPoint	+= pQuestInfo->EndPayBonusStat;
		this->SendStat_UpdateDB(TRUE, FALSE, TRUE);		// 2010-05-12 by cmkwon, 인피1차 발동류 적용 이후 퀘스트 보상 보너스 스탯 버그 수정(K0002932) - 
		this->UpdateDBtoBonusStatPoint();
		pMsgQuestCompensation.BonusStatOfCompensation = pQuestInfo->EndPayBonusStat;	// 2007-01-16 by dhjin, 퀘스트 완료 보상 보너스 스탯
		o_pQuestResult->BonusStatOfCompensation		  = pQuestInfo->EndPayBonusStat;						// 2007-07-09 by dhjin, 퀘스트 완료 보상 정보 클라이언트로 전송(보너스 스탯)
	}

	if (pQuestInfo->EndPayLevel != 0)
	{
		ChangeLevel(pQuestInfo->EndPayLevel);
	}

	if (pQuestInfo->EndPayExperience != 0)
	{
// 2006-11-16 by cmkwon, 베트남 때문에 아래와 같이 수정함
//		ChangeExperience(pQuestInfo->EndPayExperience, FALSE);
// 2007-01-29 by cmkwon, 미션 경험치도 베트남 정부 적책을 적용해야한다.
//		ChangeExperience(pQuestInfo->EndPayExperience, FALSE, FALSE);
// 2007-03-06 by cmkwon, 실제 경험치 변화량을 클라이언트에 주기 위해 아래와 같이 수정함
//		ChangeExperience(pQuestInfo->EndPayExperience, FALSE);
//		pMsgQuestCompensation.ExpOfCompensation = m_pQuestInfo->EndPayExperience;	// 2007-01-16 by dhjin, 퀘스트 완료 보상 경험치
		Experience_t changeExp					= ChangeExperience(pQuestInfo->EndPayExperience, FALSE, FALSE);		// 2011-09-02 by hskim, 파트너 시스템 2차
		pMsgQuestCompensation.ExpOfCompensation	= changeExp;	// 2007-03-06 by cmkwon, 실제 변화된 경험치
		*o_pnExpOfCompensation					= changeExp;	// 2007-03-06 by cmkwon, 클라이언트에 전송 될 변수임
	}

	if (pQuestInfo->EndPayPropensity != 0)
	{
		m_character.Propensity += pQuestInfo->EndPayPropensity;
		SendCharacterInfo(T_FC_CHARACTER_CHANGE_PKPOINT);
		CheckAndUpdateStatus();

		// DB에 저장
		QPARAM_CHARACTER_CHANGE_PKPOINT *pQChangePKPointWinner = new QPARAM_CHARACTER_CHANGE_PKPOINT;
		pQChangePKPointWinner->CharacterUniqueNumber = m_character.CharacterUniqueNumber;
		pQChangePKPointWinner->Propensity = m_character.Propensity;
		pQChangePKPointWinner->PKWinPoint = m_character.PKWinPoint;
		pQChangePKPointWinner->PKLossPoint = m_character.PKLossPoint;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_ChangePKPoint, this, m_character.AccountUniqueNumber, pQChangePKPointWinner);
	}

	////////////////////////////////////////////////////////
	// 퀘스트 수행 시 없어지는 아이템
	////////////////////////////////////////////////////////
	for (i = 0; i < pQuestInfo->EndDeleteItemVector.size(); i++)
	{
		ITEM_W_COUNT tmpItemWCount = pQuestInfo->EndDeleteItemVector[i];

		ITEM_GENERAL *pItemToDel = m_ItemManager.GetFirstItemGeneralByItemNum(tmpItemWCount.ItemNum);
		if (pItemToDel == NULL)
		{
			// 없어도 상관없음
//			g_pFieldGlobal->WriteSystemLogEX(TRUE,
//				"FATAL ERROR@CFieldIOCPSocket::ProcessQuestResult(): no such item %d\r\n",
//				tmpItemWCount.ItemNum);
			continue;
		}

		if (IS_COUNTABLE_ITEM(pItemToDel->Kind))
		{
			m_ItemManager.UpdateItemCountByPointer(pItemToDel, -tmpItemWCount.Count, IUT_QUEST);
		}
		else
		{
			m_ItemManager.DeleteItemFromCharacterByUID(pItemToDel->UniqueNumber, IUT_QUEST);
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2005-07-12 by cmkwon, 세력 변경 퀘스트
	if(QUEST_END_TYPE_SELECT_INFLUENCE == pQuestInfo->QuestEndType)
	{
		this->ChangeCharacterInfluenceType(i_nQuestResultParam);		// m_character에 적용
	}

	// 2005-08-17 by cmkwon, 세력 변경 퀘스트 이후에 처리해야함
	if (0 == pQuestInfo->TargetDeadByMonsterUniquenumber		// 몬스터에 의해 죽는 퀘스트 완료 조건이 있다면 워프는 지급되지 않는다, // 2005-08-30 by cmkwon
		&& pQuestInfo->EndPayWarpMapIndex != 0)
	{
		WarpToQuestMap(pQuestInfo->EndPayWarpMapIndex);
	}

	if(false == pQuestInfo->TargetMonsterVector.empty())
	{// 몬스터 카운트 벡터가 비어있지 않다면 DB에서 삭제 해야한다.
		QPARAM_DELETE_QUEST_MONSTER_COUNT *pDelMonCount = new QPARAM_DELETE_QUEST_MONSTER_COUNT;
		pDelMonCount->CharacterUniqueNumber		= this->GetCharacter()->CharacterUniqueNumber;
		pDelMonCount->QuestIndex				= pQuestInfo->QuestIndex;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuestMonsterCount, this, this->GetCharacter()->AccountUniqueNumber, pDelMonCount);
	}

	CAtumLogSender::SendLogMessageQUESTCOMPENSATION(this, &pMsgQuestCompensation, szCompensationItemList);

	//////////////////////////////////////////////////////////////////////////
	// 2008-12-09 by dhjin, 미션마스터
	if(pQuestInfo->QuestPartyType)
	{
		this->MissionMasterQuestResult(pQuestInfo);
		this->m_VecMissionMasterIOCPSocket.clear();
	}
	
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			void CFieldIOCPSocket::OnGetAllQuest(mtmapQuestIndex2FieldCharacterQuest *i_pmtmapCharacterQuest)
/// \brief		
/// \author		cmkwon
/// \date		2005-10-19 ~ 2005-10-19
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
void CFieldIOCPSocket::OnGetAllQuest(mtmapQuestIndex2FieldCharacterQuest *i_pmtmapCharacterQuest)
{
	if(i_pmtmapCharacterQuest->empty()){			return;}

	mt_auto_lock mtA(&m_mapQuest);
// 2007-12-17 by dhjin, 게임 시작 루틴 DB값 설정과 Client전송 부분 분리
//	///////////////////////////////////////////////////////////////////////////////
//	// 2005-10-25 by cmkwon
//	// DB에서 로딩된 퀘스트를 CFieldIOCPSocket::m_mapQuest에 하나씩 할당하고 클라이언트로 퀘스트를 전송한다.
//	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(i_pmtmapCharacterQuest->begin());
	for(; cqitr != i_pmtmapCharacterQuest->end(); cqitr++)
	{
		CFieldCharacterQuest	*pFCharQuest = &cqitr->second;
		CQuest					*pQuestInfo = pFCharQuest->GetQuestInfo();
// 2007-12-17 by dhjin, 게임 시작 루틴 DB값 설정과 Client전송 부분 분리
//		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++;
		m_mapQuest.insertNoLock(pFCharQuest->QuestIndex, *pFCharQuest);
	}
// 2007-12-17 by dhjin, 게임 시작 루틴 DB값 설정과 Client전송 부분 분리
//	if (pPutAllQuest->NumOfQuest > 0)
//	{		
//		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_PUT_ALL_QUEST) + pPutAllQuest->NumOfQuest*sizeof(MEX_QUEST_INFO));
//	}
// 
// 
//	///////////////////////////////////////////////////////////////////////////////
//	// 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 = i_pmtmapCharacterQuest->begin();
//	for(; cqitr != i_pmtmapCharacterQuest->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));
//	}
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::AddCharacterQuestMonsterCount(int i_monUniqueNumber, BOOL i_bTopAttacker)
/// \brief		
///					// 2009-01-13 by cmkwon, 미션 보상을 파티원 모두에게 주기 명령어 추가 - 인자 추가(, BOOL i_bAttacker=TRUE)
/// \author		cmkwon
/// \date		2005-10-25 ~ 2005-10-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::AddCharacterQuestMonsterCount(int i_monUniqueNumber, BOOL i_bTopAttacker, BOOL i_bAttacker/*=TRUE*/)
{
	if(FALSE == IsValidCharacter(FALSE))
	{// 2009-01-13 by cmkwon, 미션 보상을 파티원 모두에게 주기 명령어 추가 - 체크 추가
		return FALSE;
	}

	mt_auto_lock mtA(&m_mapQuest);

	CFieldCharacterQuest *pFCharQuest = this->GetCharacterQuestInProgress();
	if(NULL == pFCharQuest
		|| QUEST_STATE_IN_PROGRESS != pFCharQuest->QuestState)
	{
		return FALSE;
	}
	// start 2011-12-05 by shcho, 캐나다 서버 서버 크래쉬 문제 - 원인을 찾기 위해 로그 남기기
	// 퀘스트를 받는다.
	// 받은 값을 체크한다. 포인터 주소도 찍어준다.
	// 락이 걸려 있는데 찍어도 상관 없을까? 흠...
	// 쓰레기 값이면 죽을수 있다.
	// g_pFieldGlobal->WriteSystemLogEX(TRUE, "[CHECK] CFieldIOCPSocket::AddCharacterQuestMonsterCount!!# pointer:[0x%x] DropItemToAllAttackCharacter(%d) QuestIndex(%d) QuestName(%s)\r\n",
	//	pFCharQuest->GetQuestInfo(),pFCharQuest->GetQuestInfo()->DropItemToAllAttackCharacter, pFCharQuest->GetQuestInfo()->QuestIndex, pFCharQuest->GetQuestInfo()->QuestName); // 퀘스트인포의 주소, 최고데미지판별값(죽은 원인인듯?), 퀘스트 인덱스, 퀘스트 이름 
	
	if(NULL == pFCharQuest->GetQuestInfo())
	{	// 퀘스트 클래스 자체가 NULL일 경우 실패로 처리 추가
	//	g_pFieldGlobal->WriteSystemLogEX(TRUE, "[CHECK] CFieldIOCPSocket::AddCharacterQuestMonsterCount!!# pFCharQuest->GetQuestInfo() is NULL!! pointer:[0x%x]\r\n",
	//	pFCharQuest->GetQuestInfo()); // 퀘스트인포의 주소, 최고데미지판별값(죽은 원인인듯?), 퀘스트 인덱스, 퀘스트 이름 
		return FALSE;
	}
	// end 2011-12-05 by shcho, 캐나다 서버 서버 크래쉬 문제 - 원인을 찾기 위해 로그 남기기

	if(FALSE == pFCharQuest->GetQuestInfo()->DropItemToAllAttackCharacter
		&& FALSE == i_bTopAttacker)
	{// 2006-08-25 by cmkwon, 모든 유저에게 지급되는 것이 아니고 최고 데미지 캐릭터가 아니면 리턴
		return FALSE;
	}

	if(pFCharQuest->GetQuestInfo()->IsPartyQuest()
		&& NULL == m_pFieldParty)
	{// 2006-03-24 by cmkwon, 파티퀘스트 일때에는 파티중 일때만 추가 된다.
		return FALSE;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2009-01-13 by cmkwon, 미션 보상을 파티원 모두에게 주기 명령어 추가 - 파티원 모두에게 주는 보상이 아니면 공격자에게만 보상이 주어진다.
	if(FALSE == pFCharQuest->GetQuestInfo()->IsDropItemToAllPartyMembers
		&& FALSE == i_bAttacker)
	{
		return FALSE;
	}

	CharacterQuestMonsterCount *pMonCount = pFCharQuest->AddMonsterCountByMonsterUniqueNumber(i_monUniqueNumber);
	if(pMonCount)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2005-10-25 by cmkwon, DB에 저장
		QPARAM_UPDATE_QUEST_MONSTER_COUNT *pUpdateMonCount = new QPARAM_UPDATE_QUEST_MONSTER_COUNT;
		pUpdateMonCount->CharacterUniqueNumber	= this->GetCharacter()->CharacterUniqueNumber;
		pUpdateMonCount->QuestIndex				= pFCharQuest->QuestIndex;
		pUpdateMonCount->MonsterUniqueNumber	= pMonCount->MonsterUniqueNumber;
		pUpdateMonCount->Count					= pMonCount->Count;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateQuestMonsterCount, this, this->GetCharacter()->AccountUniqueNumber, pUpdateMonCount);

		///////////////////////////////////////////////////////////////////////////////
		// 2005-10-25 by cmkwon, 클라이언트로 전송
		INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_UPDATE_MONSTER_COUNT, T_FC_QUEST_UPDATE_MONSTER_COUNT, pSMonCount, SendBuf);
		pSMonCount->QuestIndex			= pFCharQuest->QuestIndex;
		pSMonCount->MonsterUniqueNumber	= pMonCount->MonsterUniqueNumber;
		pSMonCount->Count				= pMonCount->Count;
		this->SendAddData(SendBuf, MSG_SIZE(MSG_FC_QUEST_UPDATE_MONSTER_COUNT));
	}	
	mtA.auto_unlock_cancel();				// auto_unlock
	
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::IsQuestStateInProgressByQuestIndex(int i_quesIndex)
/// \brief		
/// \author		cmkwon
/// \date		2005-10-25 ~ 2005-10-25
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::IsQuestStateInProgressByQuestIndex(int i_quesIndex)
{
	mt_auto_lock mtA(&m_mapQuest);
	CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(i_quesIndex);
	if(pFCharQuest
		&& QUEST_STATE_IN_PROGRESS == pFCharQuest->QuestState)
	{
		return TRUE;
	}

	return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			BOOL CFieldIOCPSocket::CheckQuestCompetionRequirementsByQuestIndex(int i_quesIndex, MSG_FC_QUEST_REQUEST_SUCCESS *i_pRequestSuccess)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-24 ~ 2006-03-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
BOOL CFieldIOCPSocket::CheckQuestCompetionRequirementsByQuestIndex(int i_quesIndex, MSG_FC_QUEST_REQUEST_SUCCESS *i_pRequestSuccess)
{
	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 = m_mapQuest.findNoLock_Ptr(i_quesIndex);
	if (NULL == pFCharQuest)
	{
		return FALSE;
	}

	if (QUEST_STATE_IN_PROGRESS != pFCharQuest->QuestState)
	{
		return FALSE;
	}
	
	if (NULL == pFCharQuest->GetQuestInfo())
	{		
		return FALSE;
	}

	ProcessResult proR = this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, i_pRequestSuccess, FALSE, 0, 0, 0, TRUE);
	if(RES_RETURN_TRUE != proR)
	{
		return FALSE;
	}

	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CheckQuestStartByQuestIndex(int *o_pnErrParam1, MSG_FC_QUEST_REQUEST_START *i_pQuestRequestStart, BOOL i_bProcessPartyMembers/*=TRUE*/)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-27 ~ 2006-03-27
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CheckQuestStartByQuestIndex(int *o_pnErrParam1, MSG_FC_QUEST_REQUEST_START *i_pQuestRequestStart, BOOL i_bProcessPartyMembers/*=TRUE*/)
{
	*o_pnErrParam1		= i_pQuestRequestStart->QuestIndex;

	if(FALSE == this->IsValidCharacter())
	{// 2005-12-06 by cmkwon, 죽은 상태에서는 퀘스트 시작 불가		
		return ERR_INVALID_CHARACTER;
	}

// 2006-11-16 by cmkwon, 시스템 변경으로 필요 없음
//	if(FALSE == this->IsValidGameUser())
//	{// 2006-06-14 by cmkwon, 베트남 정액제 체크 - 퀘스트 시작
//		return ERR_INVALID_GAMEUSER;
//	}

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		return ERR_PROTOCOL_QUEST_SERVICE_PAUSED;
	}

	CQuest *pQuestInfo = ms_pFieldIOCP->m_mapQuestInfoFromScript.findEZ(i_pQuestRequestStart->QuestIndex);
	if (pQuestInfo == NULL)
	{
		return ERR_PROTOCOL_NO_SUCH_QUEST_INFO;
	}

	// lock
	mt_auto_lock igLock(&m_ItemManager.m_mapItemGeneral);		// lock m_ItemManager.m_mapItemGeneral - @CheckQuestCompetionRequirements, @ProcessQuestResult
	mt_auto_lock mtA(&m_mapQuest);

	// 2005-07-19 by hblee, 진행중인 퀘스트가 있는지 체크.
	if (NULL != GetCharacterQuestInProgress())
	{
		return ERR_PROTOCOL_QUEST_IS_IN_PROGRESS;
	}	

	// 필요 조건 확인
	Err_t err = CheckQuestStartRequirements(pQuestInfo, i_pQuestRequestStart, i_bProcessPartyMembers);
	if (ERR_NO_ERROR != err)
	{
		return err;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 미션맵이동 워프 가능 체크 추가
	if(0 != pQuestInfo->StartMapIndex)
	{
		CFieldMapProject *pFMPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pQuestInfo->StartMapIndex);
		if (NULL == pFMPro)
		{
			SendString128(STRING_128_ADMIN_CMD, "No such MapIndex(%d) !!", pQuestInfo->StartMapIndex);
			return ERR_PROTOCOL_NO_SUCH_MAP_SERVED;
		}
		Err_t errCode = this->IsEnableWarp(pFMPro->GetMapInfluenceType(), pFMPro->IsConflictAreaMap(), pFMPro->m_nQuestIndexForWarp, TRUE);
		if(ERR_NO_ERROR != errCode)
		{
			SendString128(STRING_128_ADMIN_CMD, "can't warp to Map(%d)!!, error(%d)", pQuestInfo->StartMapIndex, errCode);
			return ERR_PROTOCOL_CANNOT_WARP;
		}
	}
	// 2013-03-25 by jhseol, 인피에서 퀘스트로 다수의 유저가 입장 가능한 버그 수정 - 시작맵 0인데 아레나 서버이면 에러를 리턴
	else if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendString128(STRING_128_ADMIN_CMD, "Arena server can't start the quest(%d).", pQuestInfo->QuestIndex);
		return ERR_ARENA_STATE;
	}
	// end 2013-03-25 by jhseol, 인피에서 퀘스트로 다수의 유저가 입장 가능한 버그 수정 - 시작맵 0인데 아레나 서버이면 에러를 리턴

	// 전송할 MSG를 준비
	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_START_RESULT, T_FC_QUEST_REQUEST_START_RESULT, pStartResult, pStartResultBuf);
	pStartResult->MexQuestInfo.QuestIndex			= i_pQuestRequestStart->QuestIndex;
	pStartResult->MexQuestInfo.QuestState			= QUEST_STATE_IN_PROGRESS;
	pStartResult->MexQuestInfo.QuestPlayTimeStamp	= GetTotalPlayTimeInSeconds();
	pStartResult->fVCNInflDistributionPercent		= ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_VCN);
	pStartResult->fANIInflDistributionPercent		= ms_pFieldIOCP->GetInfluenceTypeDistirbutionPercent(INFLUENCE_TYPE_ANI);
	if(pQuestInfo->IsCityWar)
	{
		STRNCPY_MEMSET(pStartResult->MexQuestInfo.szCityWarServerGroupName, g_pFieldGlobal->GetServerGroupName(), SIZE_MAX_SERVER_NAME);
	}

	if(QUEST_START_TYPE_COUPON == pQuestInfo->QuestStartType)
	{
		return ERR_PROTOCOL_QUEST_COUPON_USE_ERROR;		// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - 수정됨

// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - 삭제됨
//		mt_auto_lock mtACou(&ms_pFieldIOCP->m_pCouponManager->m_mtlock);
//		{
//			SCOUPON tmCoupon;
//			MEMSET_ZERO(&tmCoupon, sizeof(SCOUPON));
//
//			if(FALSE == ms_pFieldIOCP->m_pCouponManager->GetCouponByNumber(&tmCoupon, i_pQuestRequestStart->szCouponNumber))
//			{				
//				return ERR_PROTOCOL_QUEST_COUPON_INVALID_NUMBER;
//			}
//
//			if(FALSE != tmCoupon.bUsedFlag)
//			{
//				return ERR_PROTOCOL_QUEST_COUPON_ALREADY_USED;
//			}
//			
//			ATUM_DATE_TIME atimeCur(TRUE);
//			if(tmCoupon.atimeExpireTime <= atimeCur)
//			{
//				return ERR_PROTOCOL_QUEST_COUPON_EXPIRED;
//			}
//
//			if(FALSE == ms_pFieldIOCP->m_pCouponManager->UseCoupon(tmCoupon.nCouponUniqueNumber, m_character.AccountName))
//			{
//				return ERR_PROTOCOL_QUEST_COUPON_USE_ERROR;
//			}
//
//			// 퀘스트 완료 조건 만족 시
//			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, pQuestInfo, 0, pSuccessResult
//											, (QUEST_PAY_ITEM_INFO*)(pSuccessResultBuf+MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT))))
//			{
//				return ERR_PROTOCOL_QUEST_RESULT_PROCESS_FAILED;
//			}
//
//			// send log
//			CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, pQuestInfo->QuestIndex);
//
//			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));
//			return ERR_NO_ERROR;
//		}
	}

	MapIndex_t	warpMapIndex = 0;
	BOOL		bPartyWarp = FALSE;
	CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(i_pQuestRequestStart->QuestIndex);
	if (pFCharQuest)
	{// 퀘스트가 이미 존재한다

		if (QUEST_STATE_COMPLETED == pFCharQuest->QuestState)
		{
			return ERR_PROTOCOL_QUEST_ALREADY_COMPLETED;
		}

		// 상태 변경
		if (QUEST_STATE_IN_PROGRESS != pFCharQuest->QuestState)
		{
			pFCharQuest->QuestState					= QUEST_STATE_IN_PROGRESS;

			// Update DB
			QPARAM_UPDATE_QUEST *pQUpdateQuest		= new QPARAM_UPDATE_QUEST;
			pQUpdateQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
			pQUpdateQuest->QuestIndex				= i_pQuestRequestStart->QuestIndex;
			pQUpdateQuest->QuestState				= pFCharQuest->QuestState;
			pQUpdateQuest->QuestProgressTimeInSecond	= this->GetTotalPlayTimeInSeconds();	// 2006-08-31 by cmkwon, 퀘스트 진행 시간 저장
			ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateQuestState, this, m_character.AccountUniqueNumber, pQUpdateQuest);
		}
	}
	else
	{
		CharacterQuest *pQInsertQuest = new CharacterQuest;
		pQInsertQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
		pQInsertQuest->QuestIndex				= pQuestInfo->QuestIndex;
		pQInsertQuest->QuestState				= QUEST_STATE_IN_PROGRESS;
		pQInsertQuest->QuestParam1				= 0;
		pQInsertQuest->QuestTimeStamp.SetCurrentDateTime();
		pQInsertQuest->QuestPlayTimeStamp		= GetTotalPlayTimeInSeconds();
		
		if(pQuestInfo->IsCityWar)
		{// 도시점령전 퀘스트에는 서버군 ID를 저장한다.
			pQInsertQuest->QuestParam1			= g_pFieldGlobal->GetMGameServerID();
		}
		else if(QUEST_END_TYPE_LEVEL_UP == pQuestInfo->QuestEndType)
		{// 종료 타입이 QUEST_END_TYPE_LEVEL_UP이면 현재 레벨을 저장한다.
			pQInsertQuest->QuestParam1			= m_character.Level;
		}
		m_mapQuest.insertNoLock(pQuestInfo->QuestIndex, CFieldCharacterQuest(pQInsertQuest, pQuestInfo));

		// Insert to DB
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_InsertQuest, this, m_character.AccountUniqueNumber, pQInsertQuest);

		// Process Start Action
		ProcessQuestStartAction(&warpMapIndex, &bPartyWarp, pQuestInfo);
	}

	// Send MSG
	pStartResult->MexQuestInfo.QuestState = QUEST_STATE_IN_PROGRESS;
	SendAddData(pStartResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_START_RESULT));
	mtA.auto_unlock_cancel();
	igLock.auto_unlock_cancel();			// 

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(i_bProcessPartyMembers)
	{
		CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(warpMapIndex);

		if(pFParty)
		{
			if(pQuestInfo->IsPartyQuest())
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2006-10-16 by cmkwon, 파티 퀘스트일때 파티원들의 퀘스트도 시작된다, 파티원의 워프는 여기서 처리하지 않고 아래에서 처리된다.
				CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
				MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
				// 2007-06-26 by cmkwon, 파티 경험치 관련 수정 - 살아 있는 캐릭터만 처리
				int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel, TRUE);

				for(int i=0; i<nMemCount; i++)
				{
					if(ArrayPartyMember[i]
						&& ArrayPartyMember[i] != this)
					{
						int nErrP1		= ERR_NO_ERROR;
						ArrayPartyMember[i]->CheckQuestStartByQuestIndex(&nErrP1, i_pQuestRequestStart, FALSE);
					}
				}
			}

			if(pMapProject
				&& pQuestInfo->IsPartyWarp())
			{
				m_bQuestRequestWarp					= TRUE;							// 2006-10-16 by cmkwon
				m_beforeMapChannIdxQuestRequestWarp	= m_character.MapChannelIndex;	// 2006-10-16 by cmkwon, 현재 MapChannelIndex

// 2006-10-16 by cmkwon, 파티원의 워프 처리는 CFieldIOCPSocket::OnWarpDone()에서 처리함
//				CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
//				MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
//				int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel);
//
//				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]->WarpToQuestMap(warpMapIndex);
//					}
//				}
			}
		}

		if(pMapProject)
		{
			// 2006-01-20 by cmkwon, 파티원을 워프시키고 한 후에 자신이 워프
			// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 체크 에러 추가
			EventResult_t evRet = WarpToQuestMap(warpMapIndex);
			if(EVENT_RESULT_CONTINUE != evRet)
			{
				g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::CheckQuestStartByQuestIndex# can't warp !! %s MapIndex(%d) EvRet(%d) \r\n"
					, GetCharacterString(GetCharacter(), string()), warpMapIndex, evRet);
				return ERR_PROTOCOL_CANNOT_WARP;
			}
		}
	}

// 2006-10-16 by cmkwon, 위와 같이 수정함
//	if(i_bProcessPartyMembers
//		&& pQuestInfo->IsPartyQuest()
//		&& pFParty)
//	{// 2006-03-27 by cmkwon, 파티 퀘스트 일 경우 가능한 파티원들도 퀘스트 시작 처리함
//
//		mt_auto_lock pmlock(&pFParty->m_ListPartyMember);
//		CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
//		MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
//		int nMemCount = pFParty->GetAllMembers(ArrayPartyMember);
//		pmlock.auto_unlock_cancel();
//
//		for(int i=0; i<nMemCount; i++)
//		{
//			if(ArrayPartyMember[i]
//				&& ArrayPartyMember[i] != this)
//			{
//				int nErrP1		= ERR_NO_ERROR;
//				ArrayPartyMember[i]->CheckQuestStartByQuestIndex(&nErrP1, i_pQuestRequestStart, FALSE);
//			}
//		}
//	}
//
//	if(warpMapIndex)
//	{
//		CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(warpMapIndex);
//		if(pMapProject)
//		{
//			if(i_bProcessPartyMembers
//				&& pQuestInfo->IsPartyWarp()
//				&& pFParty)
//			{// 파티원도 워프
//				CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
//				MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
//				int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel);
//
//				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]->WarpToQuestMap(warpMapIndex);
//					}
//				}
//			}
//			
//			// 2006-01-20 by cmkwon, 파티원을 워프시키고 한 후에 자신이 워프
//			WarpToQuestMap(warpMapIndex);
//		}
//	}
	return ERR_NO_ERROR;
}




ProcessResult CFieldIOCPSocket::Process_FC_QUEST_CANCEL_QUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize = 0;
	MSG_FC_QUEST_CANCEL_QUEST	*pCancelQuest;

	nRecvTypeSize = sizeof(MSG_FC_QUEST_CANCEL_QUEST);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_QUEST_CANCEL_QUEST, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pCancelQuest = (MSG_FC_QUEST_CANCEL_QUEST*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_START, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}

	// check: 아직 구현 안 되었음, 기획 나오면 구현하기, 20031030, kelovon
	assert(0);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_SUCCESS(const char* pPacket, int nLength, int &nBytesUsed)
{
	int								nRecvTypeSize = 0;
	MSG_FC_QUEST_REQUEST_SUCCESS	*pRequestSuccessQuest;

	nRecvTypeSize = sizeof(MSG_FC_QUEST_REQUEST_SUCCESS);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x14037);
		return RES_RETURN_FALSE;
	}
	pRequestSuccessQuest = (MSG_FC_QUEST_REQUEST_SUCCESS*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if(FALSE == this->IsValidCharacter(FALSE))
	{// 2005-12-06 by cmkwon
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}

	// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 퀘스트 시작/완료 불가
	if(g_pFieldGlobal->GetIsJamboreeServer())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_JAMBOREE_NO_SUCH_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////
	// check: 아직 완전 구현 안 되었음, 기획 나오면 구현하기, 20031127, kelovon
	//        퀘스트 완료를 위한 필요 조건이 불명확하므로 이를 정해야 함
	//        현재는 퀘스트 시작을 위한 필요 조건만이 정의되어 있다
	///////////////////////////////////////////////////////////////////////////

	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 = m_mapQuest.findNoLock_Ptr(pRequestSuccessQuest->QuestIndex);
	if (NULL == pFCharQuest)
	{
		CQuest * pQuestInfo = ms_pFieldIOCP->GetQuestInfo(pRequestSuccessQuest->QuestIndex);
		if(pQuestInfo
			&& pQuestInfo->IsPartyQuest())
		{// 2006-03-28 by cmkwon, 파티퀘스트 일 경우만 워프가 처리된다.

			if(0 == pQuestInfo->TargetDeadByMonsterUniquenumber
				&& pQuestInfo->EndPayWarpMapIndex != 0)
			{
				WarpToQuestMap(pQuestInfo->EndPayWarpMapIndex);
			}
			return RES_RETURN_TRUE;
		}

		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_NO_SUCH_CHARACTER_QUEST, pRequestSuccessQuest->QuestIndex);
		return RES_BREAK;
	}

	if (QUEST_STATE_IN_PROGRESS != pFCharQuest->QuestState)
	{
		CQuest * pQuestInfo = ms_pFieldIOCP->GetQuestInfo(pRequestSuccessQuest->QuestIndex);
		if(pQuestInfo
			&& pQuestInfo->IsPartyQuest())
		{// 2006-03-28 by cmkwon, 파티퀘스트 일 경우만 워프가 처리된다.

			if(0 == pQuestInfo->TargetDeadByMonsterUniquenumber
				&& pQuestInfo->EndPayWarpMapIndex != 0)
			{
				WarpToQuestMap(pQuestInfo->EndPayWarpMapIndex);
			}
			return RES_RETURN_TRUE;
		}
		
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_QUEST_NOT_IN_PROGRESS, pFCharQuest->QuestState);
		return RES_BREAK;
	}
	
	if (NULL == pFCharQuest->GetQuestInfo())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, ERR_PROTOCOL_NO_SUCH_QUEST_INFO, pRequestSuccessQuest->QuestIndex);
		return RES_BREAK;
	}

	return this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, pRequestSuccessQuest);
// 2005-07-07 by cmkwon, CheckQuestRequestSuccessAndSendResult()함수내에서 처리
//	// check: 완료 조건 구현하기!, 20040220, kelovon
//	Err_t errQuestCompletion = CheckQuestCompetionRequirements(&refCharacQuest, pQuestInfo, pRequestSuccessQuest->SpentTimeInSeconds);
//	if (errQuestCompletion != ERR_NO_ERROR)
//	{// 퀘스트 완료 조건 불만족 시
//
//		// 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		= pQuestInfo->QuestIndex;
//		pSuccessResult->IsSuccessful	= FALSE;
//		SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT));
//
//		// check: 필요 없을 듯. 삭제 가능. 20040220, kelovon
//		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS, errQuestCompletion, pQuestInfo->QuestIndex);
//		return RES_BREAK;
//	}
//	
//	// 퀘스트 완료 조건 만족 체크
//	if (FALSE == ProcessQuestResult(pQuestInfo))
//	{
//		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				= refCharacQuest.QuestIndex;
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuest, this, m_character.AccountUniqueNumber, pQDeleteQuest);
//
//		m_mapQuest.deleteLock(refCharacQuest.QuestIndex);
//	}
//	else
//	{
//		// Update Field
//		refCharacQuest.QuestState				= QUEST_STATE_COMPLETED;
//
//		// Update DB
//		QPARAM_UPDATE_QUEST *pQUpdateQuest		= new QPARAM_UPDATE_QUEST;
//		pQUpdateQuest->CharacterUniqueNumber	= m_character.CharacterUniqueNumber;
//		pQUpdateQuest->QuestIndex				= refCharacQuest.QuestIndex;
//		pQUpdateQuest->QuestState				= refCharacQuest.QuestState;
//		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_UpdateQuestState, this, m_character.AccountUniqueNumber, pQUpdateQuest);
//	}
//	
//	///////////////////////////////////////////////////////////////////////////////
//	// 완료한 퀘스트 로그에 남기기
//	CAtumLogSender::SendLogMessageQUESTCOMPLETION(this, pQuestInfo->QuestIndex);		// send log
//
//	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT, T_FC_QUEST_REQUEST_SUCCESS_RESULT, pSuccessResult, pSuccessResultBuf);
//	pSuccessResult->QuestIndex		= pQuestInfo->QuestIndex;
//	pSuccessResult->IsSuccessful	= TRUE;
//	SendAddData(pSuccessResultBuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_RESULT));
//	return RES_RETURN_TRUE;
}


/**************************************************************************************************************
**
**	퀘스트 포기 신호 처리. (F->C)
**
**	Create Info : ??. ??. ??
**
**	Update Info : 포기 가능한 퀘스트 체크 처리 추가.	2010. 09. 06. by hsLee.
**
***************************************************************************************************************/
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_DISCARD_QUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_DISCARD_QUEST,
									MSG_FC_QUEST_DISCARD_QUEST, msgDiscardQuest);

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_DISCARD_QUEST, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}

	// 포기 가능한 퀘스트인지 체크.
	CQuest* pGiveUpQuest = ms_pFieldIOCP->GetQuestInfo(msgDiscardQuest->QuestIndex);
	if ( pGiveUpQuest )
	{
		if ( pGiveUpQuest->QuestKind == QUEST_KIND_SCENARIO && pGiveUpQuest->IsDiscardable == FALSE )
		{
			SendErrorMessage ( T_FC_QUEST_DISCARD_QUEST , ERR_PROTOCOL_QUEST_IMPOSSIBLE_GIVEUP );
			return RES_BREAK;
		}
	}

	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_DISCARD_QUEST_OK, T_FC_QUEST_DISCARD_QUEST_OK, msgDiscardOK, msgDiscardOKBuf);
	msgDiscardOK->QuestIndex = msgDiscardQuest->QuestIndex;

	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 = m_mapQuest.findNoLock_Ptr(msgDiscardQuest->QuestIndex);
	if (pFCharQuest == NULL || pFCharQuest->QuestState != QUEST_STATE_IN_PROGRESS)
	{
		msgDiscardOK->IsDiscarded = FALSE;
		SendAddData(msgDiscardOKBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));
		return RES_BREAK;
	}
	
	CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
	if (pQuestInfo == NULL)
	{
		msgDiscardOK->IsDiscarded = FALSE;
		SendAddData(msgDiscardOKBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));
		return RES_BREAK;
	}

// 2006-08-02 by cmkwon, 제한 시간 퀘스트 실패도 같은 프로토콜로 처리중이미로 서버는 체크하지 않는다
// 	if(FALSE == pQuestInfo->IsDiscardable)
// 	{// 2006-07-20 by cmkwon, 포기 불가 퀘스트
// 		msgDiscardOK->IsDiscarded = FALSE;
// 		SendAddData(msgDiscardOKBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));
// 		return RES_BREAK;
// 	}

	if(pQuestInfo->IsCityWar)
	{
		if(pFCharQuest->QuestParam1 != g_pFieldGlobal->GetMGameServerID())
		{
			SendErrorMessage(T_FC_QUEST_DISCARD_QUEST, ERR_PROTOCOL_QUEST_CITYWAR_MGAMESERVERID_NOT_MATCHED, pFCharQuest->QuestParam1, g_pFieldGlobal->GetMGameServerID());
			return RES_BREAK;
		}

		CCityWar *pCityWar = ms_pFieldIOCP->m_cityWarManager.GetCityWarPtrByQuestIndex(pQuestInfo->QuestIndex);
		if(pCityWar)
		{
			if(CITYWAR_STATE_STARTED == pCityWar->GetCityWarState())
			{
				SendErrorMessage(T_FC_QUEST_DISCARD_QUEST, ERR_PROTOCOL_QUEST_CANNOT_CITYWAR_QUEST);
				return RES_BREAK;
			}
		}
	}

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

	// S_PAY_ITEM 아이템 지우기
	for (int i = 0; i < pQuestInfo->StartPayItemVector.size(); i++)
	{
		QUEST_PAY_ITEM *pPayItem = &pQuestInfo->StartPayItemVector[i];

		ITEM *pPayItemInfo = ms_pFieldIOCP->GetItemInfo(pPayItem->ItemNum);
		if (pPayItemInfo == NULL) { continue; }

		if (IS_SAME_UNITKIND(pPayItem->ToUnitKind, m_character.UnitKind))
		{
			// DeleteItemFromCharacterByItemNum 내부에서 lock 해결
			m_ItemManager.DeleteItemFromCharacterByItemNum(
								pPayItem->ItemNum,
								pPayItem->Count,
								IUT_QUEST, ITEM_IN_CHARACTER);
		}
	}

	// C_REQ_ITEM 아이템 지우기, ITEMKIND_QUEST만 지우기
	for (i = 0; i < pQuestInfo->TargetMonsterItemVector.size(); i++)
	{
		ITEM_W_COUNT_MAP_AREA *pTargetReqItem = &pQuestInfo->TargetMonsterItemVector[i];

		ITEM_GENERAL *pItemGReqItem = m_ItemManager.GetFirstItemGeneralByItemNum(pTargetReqItem->ItemWithCount.ItemNum);
		if(NULL == pItemGReqItem)
		{
			continue;
		}
		
		if (ITEMKIND_QUEST == pItemGReqItem->Kind)
		{
			// DeleteItemFromCharacterByItemNum 내부에서 lock 해결
			m_ItemManager.DeleteItemFromCharacterByPointer(pItemGReqItem, IUT_QUEST, ITEM_IN_CHARACTER);
		}
	}

	if(FALSE == pFCharQuest->IsEmptyMonsterCount())
	{// 퀘스트 몬스터 카운트가 비어 있지 않다면 DB에서도 삭제해야 한다.
		QPARAM_DELETE_QUEST_MONSTER_COUNT *pDelMonCount = new QPARAM_DELETE_QUEST_MONSTER_COUNT;
		pDelMonCount->CharacterUniqueNumber		= this->GetCharacter()->CharacterUniqueNumber;
		pDelMonCount->QuestIndex				= pQuestInfo->QuestIndex;
		ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteQuestMonsterCount, this, this->GetCharacter()->AccountUniqueNumber, pDelMonCount);
	}

	// 퀘스트 지우기 - Field
	m_mapQuest.deleteNoLock(pFCharQuest->QuestIndex);
	
	// send msg
	msgDiscardOK->IsDiscarded = TRUE;
	SendAddData(msgDiscardOKBuf, MSG_SIZE(MSG_FC_QUEST_DISCARD_QUEST_OK));

	mqLock.auto_unlock_cancel();
	igLock.auto_unlock_cancel();


	///////////////////////////////////////////////////////////////////////////////
	// 2005-08-02 by cmkwon
	// EndPayWarpWapIndex가 0이 아닐 때 미션을 취소하면 그맵으로 워프를 시킨다.
	if(0 != pQuestInfo->EndPayWarpMapIndex)
	{
		this->WarpToQuestMap(pQuestInfo->EndPayWarpMapIndex);
	}
	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MOVE_QUEST_MAP(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2005-07-29 ~ 2005-07-29
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_MOVE_QUEST_MAP(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_MOVE_QUEST_MAP,
									MSG_FC_QUEST_MOVE_QUEST_MAP, pRMsg);

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_MOVE_QUEST_MAP, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}

	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest
	CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(pRMsg->QuestIndex0);
	if (NULL == pFCharQuest)
	{
		SendErrorMessage(T_FC_QUEST_MOVE_QUEST_MAP, ERR_PROTOCOL_NO_SUCH_CHARACTER_QUEST, pRMsg->QuestIndex0);
		return RES_BREAK;
	}

	if(pFCharQuest->QuestState != QUEST_STATE_IN_PROGRESS)
	{
		SendErrorMessage(T_FC_QUEST_MOVE_QUEST_MAP, ERR_PROTOCOL_QUEST_GENERAL_ERROR, pRMsg->QuestIndex0);
		return RES_BREAK;
	}

	CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
	if (pQuestInfo == NULL)
	{
		SendErrorMessage(T_FC_QUEST_MOVE_QUEST_MAP, ERR_PROTOCOL_NO_SUCH_QUEST_INFO, pRMsg->QuestIndex0);
		return RES_BREAK;
	}

	int iWarpMapIndex = pQuestInfo->StartMapIndex;		// 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정

	if(0 == pQuestInfo->StartMapIndex)
	{
		// start 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
		if( IS_CITY_MAP_INDEX(m_character.MapChannelIndex.MapIndex) )
		{
			iWarpMapIndex = INFLUENCE_GARDEN_MAP_INDEX;		
		}
		else
		{
			return RES_BREAK;								// 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
		}
		// end 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정

		//return RES_BREAK;								// 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
	}

	if(pQuestInfo->IsPartyQuest()
		&& NULL == m_pFieldParty)
	{// 2006-03-24 by cmkwon, 파티퀘스트는 파티 중 일때만 미션맵으로 이동 가능
		SendErrorMessage(T_FC_QUEST_MOVE_QUEST_MAP, ERR_PROTOCOL_NO_SUCH_PARTY, pRMsg->QuestIndex0);
		return RES_BREAK;
	}
	mqLock.auto_unlock_cancel();

	if(INFLUENCE_CITY_MAP_INDEX == iWarpMapIndex )		// 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
	{// 2006-02-28 by cmkwon, 도시맵으로 워프는 항상 혼자만 처리
		WarpToCityMap();
		return RES_RETURN_TRUE;
	}

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(pQuestInfo->StartPartyWarpFlag
		&& pFParty)
	{// 2006-02-28 by cmkwon, 파티원도 워프 처리

		m_bQuestRequestWarp					= TRUE;				// 2006-10-16 by cmkwon
		m_beforeMapChannIdxQuestRequestWarp	= m_character.MapChannelIndex;	// 2006-10-16 by cmkwon, 현재 MapChannelIndex

// 2006-10-16 by cmkwon, 파티원의 워프 처리는 CFieldIOCPSocket::OnWarpDone()에서 처리함
//		CFieldMapProject *pMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pQuestInfo->StartMapIndex);
//		if (pMapProject)
//		{
//			CFieldIOCPSocket *ArrayPartyMember[SIZE_MAX_PARTY_MEMBER];
//			MEMSET_ZERO(ArrayPartyMember, sizeof(ArrayPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
//			int nMemCount = pFParty->GetMembersInSameMap(ArrayPartyMember, m_pCurrentFieldMapChannel);
//			for(int i=0; i<nMemCount; i++)
//			{
//				if(ArrayPartyMember[i]
//					&& ArrayPartyMember[i] != this
//					&& ArrayPartyMember[i]->m_character.MapChannelIndex.IsSameMapChannelIndex(this->GetCharacter()->MapChannelIndex)
//					&& SIZE_CHARACTER_VISIBLE_SIDE > D3DXVec3Length(&(ArrayPartyMember[i]->GetCharacter()->PositionVector - this->GetCharacter()->PositionVector))
//					&& ERR_NO_ERROR == ArrayPartyMember[i]->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp))
//				{
//					ArrayPartyMember[i]->WarpToQuestMap(pQuestInfo->StartMapIndex);
//				}
//			}
//		}
	}
		
	// 2006-01-20 by cmkwon, 파티원을 워프시키고 한 후에 자신이 워프
	// 2010-02-01 by cmkwon, 거래시 미션맵이동 워프 버그 수정 - 체크 에러 추가
	EventResult_t evRet = WarpToQuestMap(iWarpMapIndex);		// 2012-03-09 by hskim, 출격 시 비행 모드로 남는 버그 수정
	if(EVENT_RESULT_CONTINUE != evRet)
	{
		g_pFieldGlobal->WriteSystemLogEX(TRUE, "[ERROR] CFieldIOCPSocket::Process_FC_QUEST_MOVE_QUEST_MAP# can't warp !! %s %d \r\n"
			, GetCharacterString(GetCharacter(), string()), evRet);
		return RES_BREAK;
	}
	
	return RES_RETURN_TRUE;	
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_SUCCESS_CHECK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-24 ~ 2006-03-24
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_SUCCESS_CHECK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_REQUEST_SUCCESS_CHECK,
									MSG_FC_QUEST_REQUEST_SUCCESS_CHECK, pRMsg);

	// 퀘스트 기능 일시 정지 상태 확인
	if (!ms_pFieldIOCP->m_ServicePauseManager.GetQuestServiceState())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_QUEST_SERVICE_PAUSED);
		return RES_BREAK;
	}

	// 2008-04-15 by cmkwon, 대회서버(JamboreeServer)는 시스템 수정 - 퀘스트 시작/완료 불가
	if(g_pFieldGlobal->GetIsJamboreeServer())
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_JAMBOREE_NO_SUCH_CHARACTER);
		return RES_BREAK;
	}

	mt_auto_lock mqLock(&m_mapQuest);							// lock m_mapQuest
	CFieldCharacterQuest *pFCharQuest = m_mapQuest.findNoLock_Ptr(pRMsg->QuestIndex);
	if (NULL == pFCharQuest)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_NO_SUCH_CHARACTER_QUEST, pRMsg->QuestIndex);
		return RES_BREAK;
	}

	if(pFCharQuest->QuestState != QUEST_STATE_IN_PROGRESS)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_QUEST_GENERAL_ERROR, pRMsg->QuestIndex);
		return RES_BREAK;
	}

	CQuest *pQuestInfo = pFCharQuest->GetQuestInfo();
	if (pQuestInfo == NULL)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_NO_SUCH_QUEST_INFO, pRMsg->QuestIndex);
		return RES_BREAK;
	}

	if(FALSE == pQuestInfo->IsPartyQuest())
	{// 2006-03-24 by cmkwon, 현재는 파티퀘스트만 처리한다.
		return RES_BREAK;
	}
	mqLock.auto_unlock_cancel();

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if(NULL == pFParty)
	{// 2006-03-24 by cmkwon, 파티퀘스트는 파티 중 일때만 
		SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_NO_SUCH_PARTY, pRMsg->QuestIndex);
		return RES_BREAK;
	}

	CFieldIOCPSocket *arrPartyMember[SIZE_MAX_PARTY_MEMBER];
	MEMSET_ZERO(arrPartyMember, sizeof(arrPartyMember[0]) * SIZE_MAX_PARTY_MEMBER);
	int nMemCount = pFParty->GetAllMembers(arrPartyMember);
	for(int i=0; i < nMemCount; i++)
	{
		if(arrPartyMember[i]
			&& this != arrPartyMember[i]
			&& arrPartyMember[i]->IsValidCharacter(FALSE)
			&& arrPartyMember[i]->IsQuestStateInProgressByQuestIndex(pQuestInfo->QuestIndex))
		{
			if(FALSE == arrPartyMember[i]->CheckQuestCompetionRequirementsByQuestIndex(pQuestInfo->QuestIndex, pRMsg))
			{
				SendErrorMessage(T_FC_QUEST_REQUEST_SUCCESS_CHECK, ERR_PROTOCOL_REQ_PARTYMEMBERS_SOMEONE_NOT_COMPLETION, arrPartyMember[i]->GetCharacter()->ClientIndex);
				return RES_BREAK;
			}
		}
	}
	
	INIT_MSG_WITH_BUFFER(MSG_FC_QUEST_REQUEST_SUCCESS_CHECK_RESULT, T_FC_QUEST_REQUEST_SUCCESS_CHECK_RESULT, pSMsg, Sendbuf);
	pSMsg->QuestIndex		= pRMsg->QuestIndex;
	pSMsg->IsSuccessful		= TRUE;
	pSMsg->QuestResult		= 0;
	pFParty->SendMsgToMembersMap(Sendbuf, MSG_SIZE(MSG_FC_QUEST_REQUEST_SUCCESS_CHECK_RESULT), m_pCurrentFieldMapChannel);

	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_PARTY_WARP_ACK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-10-16 ~ 2006-10-16
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_QUEST_REQUEST_PARTY_WARP_ACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_QUEST_REQUEST_PARTY_WARP_ACK,
									MSG_FC_QUEST_REQUEST_PARTY_WARP_ACK, pRMsg);

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

	CFieldIOCPSocket *pCallerFISock = ms_pFieldIOCP->GetFieldIOCPSocketByCharacterUniqueNumber(pRMsg->callerCharacterUID);
	if(NULL == pCallerFISock
		|| FALSE == pCallerFISock->IsValidCharacter(FALSE))
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, ERR_INVALID_PEER_CHARACTER);
		return RES_BREAK;
	}

	if(FALSE == pRMsg->warpMapChannIndex.IsSameMapChannelIndex(pCallerFISock->m_character.MapChannelIndex))
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED);
		return RES_BREAK;
	}

	DWORD curTick = timeGetTime();
	if(curTick - pCallerFISock->m_dwLastQuestRequestWarpTick > TERM_QUEST_REQUEST_WARP_EFFECTIVE_TIME+5000)
	{// 2006-10-16 by cmkwon, 유효 경과 시간 체크

		SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, ERR_EXPIRED_ITEM);
		return RES_BREAK;
	}

	CFieldMapProject *pFMapPro = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pRMsg->warpMapChannIndex.MapIndex);
	if(NULL == pFMapPro)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, ERR_PROTOCOL_NO_SUCH_MAP_SERVED);
		return RES_BREAK;
	}

	Err_t err = this->IsEnableWarp(pFMapPro->GetMapInfluenceType(), pFMapPro->IsConflictAreaMap(), pFMapPro->m_nQuestIndexForWarp);
	if(ERR_NO_ERROR != err)
	{
		SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, err);
		return RES_BREAK;
	}

	// 2014-04-29 by bckim, 버닝타입맵에 고레벨 유져 입장 제한
	if( ms_pFieldIOCP->IsBurningMap(pRMsg->warpMapChannIndex.MapIndex) )
	{
		BURNING_MAP_INFO* tempBurnigMapInfo = ms_pFieldIOCP->GetBurningMapInfo(pRMsg->warpMapChannIndex.MapIndex);
		if( NULL != tempBurnigMapInfo )
		{
			if ( FALSE == IS_IN_RANGE(tempBurnigMapInfo->ReqMinLv, m_character.Level,tempBurnigMapInfo->ReqMaxLv))
			{
				SendErrorMessage(T_FC_QUEST_REQUEST_PARTY_WARP_ACK, err);
				return RES_BREAK;
			}
		}
	}
	// End. 2014-04-29 by bckim, 버닝타입맵에 고레벨 유져 입장 제한

	WarpToMap(pRMsg->warpMapChannIndex);
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(102) : %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);

	return RES_RETURN_TRUE;	
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			Err_t CFieldIOCPSocket::CheckAttachableItem(INT NewPosition, ITEM_GENERAL *i_pItemGen)
/// \brief		
/// \author		cmkwon
/// \date		2006-03-30 ~ 2006-03-30
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
Err_t CFieldIOCPSocket::CheckAttachableItem(INT NewPosition, ITEM_GENERAL *i_pItemGen)
{
	switch(NewPosition)
	{

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_ATTACHMENT:	// 2006-03-30 by cmkwon, 무제한 악세사리 - 부착물
	case POS_ACCESSORY_UNLIMITED :
		{

		}
		break;

	// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
	//case POS_PET:			// 2006-03-30 by cmkwon, 시간제한 악세사리
	case POS_ACCESSORY_TIME_LIMIT :
		{
			ITEM *pItemInfo = i_pItemGen->ItemInfo;

// 2006-06-14 by cmkwon, 아직은 필요 없다 - 프리미엄 카드가 사용되지 않고 있다
// 			if(m_ItemManager.IsExistPremiumCard())
// 			{
// 				if(pItemInfo->IsExistDesParam(DES_DROP_EXP)
// 					|| pItemInfo->IsExistDesParam(DES_DROP_SPI)
// 					|| pItemInfo->IsExistDesParam(DES_DROP_ITEM))
// 				{
// 					return ERR_CANNOT_ATTACHED_USING_PREMIUM_CARD;
// 				}
// 			}

			// 2008-11-26 by cmkwon, 사용 후 시간(절대시간) 제한 아이템 구현 - 아래와 같이 수정 함.
			//if(i_pItemGen->ItemInfo->Time <= 1000*i_pItemGen->UsingTimeStamp)
			if(CAtumSJ::GetTimeSecondByItemKind8ItemAttribute(i_pItemGen->ItemInfo) <= i_pItemGen->UsingTimeStamp)
			{
				m_ItemManager.DeleteItemFromCharacterByPointer(i_pItemGen, IUT_EXPIRE_CARD_ITEM);
				return ERR_EXPIRED_ITEM;
			}
		}
		break;
	}
	return ERR_NO_ERROR;
}


BOOL CFieldIOCPSocket::CheckItemWindowPosition(INT NewPosition, ITEM* itemInfo)
{
	if (NewPosition < POS_ITEMWINDOW_OFFSET )
	{
		///////////////////////////////////////////////////////////////////////////////////////
		// start 2011-09-20 by hskim, 파트너 시스템 2차
		if( POS_HIDDEN_ITEM == NewPosition )
		{
			return FALSE;
		}
		// end 2011-09-20 by hskim, 파트너 시스템 2차
		///////////////////////////////////////////////////////////////////////////////////////

		if ( itemInfo->Position != NewPosition )
		{
			return FALSE;
		}

		if (itemInfo->Kind == ITEMKIND_INGOT || itemInfo->Kind == ITEMKIND_ENERGY
			|| itemInfo->Kind == ITEMKIND_BULLET || itemInfo->Kind == ITEMKIND_CARD
			|| itemInfo->Kind == ITEMKIND_ENCHANT)
		{
			return FALSE;
		}
	}

	return TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_ITEM_CHANGE_WINDOW_POSITION(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_ITEM_CHANGE_WINDOW_POSITION, 
									MSG_FC_ITEM_CHANGE_WINDOW_POSITION, pChangeWindowPosition);

	if(FALSE == IsValidCharacter())
	{// 2006-03-31 by cmkwon
		SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

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

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_ITEM_CHANGE_WINDOW_POSITION 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2007-10-02 by cmkwon, 베트남 2차패스워드 수정 - 시간제한 악세사리 아이템은 장착/해제 허용
		// 2010-06-15 by shcho&hslee 펫시스템 - 선언 변경.
		if(/*POS_PET*/ POS_ACCESSORY_TIME_LIMIT != pChangeWindowPosition->FromItemWindowIndex
			&& /*POS_PET*/ POS_ACCESSORY_TIME_LIMIT != pChangeWindowPosition->ToItemWindowIndex)
		{
			SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_SECPASS_LOCKED);
			return RES_BREAK;
		}
	}

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

	// 2010-05-12 by cmkwon, 거래 이용한 아이템 메모리 버그 수정(K0002953) - 거래 도중에는 아이템 장착/해제 불가
	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_ITEM_CHANGE_WINDOW_POSITION, ERR_ITEM_TRADING);
		return RES_BREAK;
	}

	return ProcessItemChangeWindowPosition(pChangeWindowPosition);
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_ENTER_BUILDING_OK(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize		= 0;
	MSG_FC_EVENT_ENTER_BUILDING_OK		*pEnterBuildingOK = NULL;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_ENTER_BUILDING_OK);

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

	pEnterBuildingOK = (MSG_FC_EVENT_ENTER_BUILDING_OK*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (m_pCurrentFieldMapChannel == NULL)
	{
		// check: 다시보기... 20040228, kelovon
		return RES_BREAK;
	}

	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pEnterBuildingOK->BuildingIndex);
	if(NULL == pBuildingNPC)
	{
		return RES_BREAK;
	}

	// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 상점 열때 거래 중 체크
	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_EVENT_ENTER_BUILDING_OK, ERR_ITEM_TRADING, pEnterBuildingOK->BuildingIndex, m_peerTraderCharacterUniqueNumber);
		return RES_BREAK;
	}
	// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 상점 열때 개인상점 체크
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_EVENT_ENTER_BUILDING_OK, ERR_USING_BAZAAR, pEnterBuildingOK->BuildingIndex, m_peerTraderCharacterUniqueNumber);
		return RES_BREAK;
	}

	// 현재 들어가 있는 건물 저장
	m_pCurrentBuildingNPC = pBuildingNPC;

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

	switch (pBuildingNPC->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 == pBuildingNPC->BuildingKind)
			{
				///////////////////////////////////////////////////////////////////////////////
				// 2010-01-26 by cmkwon, 캐쉬 아이템 한정판매 시스템 구현 - T_FC_EVENT_ENTER_BUILDING_OK, 한정판매 아이템 리스트 업데이트
				ms_pFieldIOCP->LimitedEUpdateShopItemW(pEnterBuildingOK->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, 웹 캐시 상점
			}

			if (pEnterBuildingOK->SendShopItemList)
			{
				map<UINT, CShopInfo*>::iterator itr
					=  m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.find(pEnterBuildingOK->BuildingIndex);
				if (itr == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapShopInfo.end())
				{
					SendErrorMessage(T_FC_EVENT_ENTER_BUILDING_OK, ERR_PROTOCOL_NO_SUCH_SHOP, pEnterBuildingOK->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:
		{
			if (pEnterBuildingOK->SendShopItemList)
			{
				SendAddDataBuffer(m_pCurrentFieldMapChannel->m_pFieldMapProject->m_buffGetWarpTargetMapListOK);
			}
		}
		break;
	case BUILDINGKIND_LABORATORY:
	case BUILDINGKIND_FACTORY:
	case BUILDINGKIND_AUCTION:
	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_LUCKY_OPTION_MACHINE:		// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	case BUILDINGKIND_MYSTERY_SHOP:		// 2012-07-09 by hskim, 미스터리 머신 구현 
		{
			// do nothing
		}
		break;
	case BUILDINGKIND_STORE:
		{
			// 상점 진입 시 client에서 MSG_FC_STORE_GET_ITEM를 요청하기로 함! 20040803, kelovon
		}
		break;
	case BUILDINGKIND_ARENA:
	case BUILDINGKIND_INFINITY:			// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
		{// 2007-04-25 by dhjin, ARENA 상점

			// 2008-03-07 by dhjin, 아레나 통합 - 아레나 서버와 연결이 안되어 있으면 오류를 보낸다.
			if(FALSE == g_pFieldGlobal->IsArenaServer()
				&& FALSE == g_pFieldGlobal->GetField2ArenaFieldWinSocket()->IsConnected()
				)
			{
				SendErrorMessage(T_FC_EVENT_ENTER_BUILDING_OK, ERR_NOT_CONNECT_TO_ARENASERVER);
				return RES_BREAK;
			}

			// 2007-07-11 by cmkwon, 아레나블럭 시스템 구현 - T_FC_EVENT_ENTER_BUILDING_OK
			int nRemainMinute = 0;
			if(ms_pFieldIOCP->m_arenaBlockManager.IsExistChatBlockList(&nRemainMinute, m_character.CharacterName))
			{
				SendErrorMessage(T_FC_EVENT_ENTER_BUILDING_OK, ERR_ARENA_BLOCKED, nRemainMinute);
				return RES_BREAK;
			}
		}
		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;
	// 2010-08-31 by shcho&jskim 아이템용해 시스템 - 
	case BUILDINGKIND_DISSOLUTION:	
		{
			// do nothing
		}
		break;
	// END 2010-08-31 by shcho&jskim 아이템용해 시스템 - 
	// 2013-05-09 by hskim, 세력 포인트 개선
	case BUILDINGKIND_INFLBUFF_SHOP:
		{
			// do nothing
		}
		break;
	// 2013-05-09 by hskim, 세력 포인트 개선
	// 2014-01-03 by jhseol&bckim, 파괴경매장 - 경매장 이용중인 유저 리스트 추가
#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG	// - 경매장 이용중인 유저 리스트 추가
	case BUILDINGKIND_DESTROY_AUCTION:
		{
			// 경매장 이용 유져 관리 
			if( ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.end() 
				!= ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.find(m_character.CharacterUniqueNumber))
			{
				ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.deleteLock(m_character.CharacterUniqueNumber);
			}

			ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.insertLock(m_character.CharacterUniqueNumber, this);
			//임시값 확인 
			int tmsize = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.size();			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 사이즈  (%d) 리스트 (%s)\r\n",tmsize,m_character.CharacterName);
		}
		break;
#endif	//#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG
	// end 2014-01-03 by jhseol&bckim, 파괴경매장 - 경매장 이용중인 유저 리스트 추가
	default:
		{
			SendErrorMessage (T_FC_EVENT_ENTER_BUILDING_OK, ERR_PROTOCOL_NO_SUCH_SHOP, pBuildingNPC->BuildingKind);
			return RES_BREAK;
		}
		break;
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_LEAVE_BUILDING(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize		= 0;
	BYTE								SendBuf[SIZE_MAX_PACKET];
	MSG_FC_EVENT_LEAVE_BUILDING			*pLeave;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_LEAVE_BUILDING);

	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_EVENT_LEAVE_BUILDING_OK, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1403C);
		return RES_RETURN_FALSE;
	}
	pLeave = (MSG_FC_EVENT_LEAVE_BUILDING*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

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

	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pLeave->BuildingIndex);
	if(NULL == pBuildingNPC)
	{
		return RES_BREAK;
	}
	switch(pBuildingNPC->BuildingKind)
	{
	case BUILDINGKIND_STORE:
		{
			// ResetAllItemGeneralsInStore 내부에서 lock 해결
			m_ItemManager.ResetAllItemGeneralsInStore();
			m_ItemManager.SetUsingFieldStore(FALSE);		// 2009-09-23 by cmkwon, 필드창고 캐쉬 아이템 구현 - T_FC_EVENT_LEAVE_BUILDING_OK, 필드창고 이용 관련 초기화
			m_ItemManager.SetUsingStore(FALSE);				// 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
		}
		break;
	case BUILDINGKIND_1ST_WEAPONSHOP:
	case BUILDINGKIND_2ND_WEAPONSHOP:
	case BUILDINGKIND_SKILL_SHOP:
	case BUILDINGKIND_AUCTION:
	case BUILDINGKIND_CITY_OCCUPY_INFO:
	case BUILDINGKIND_CASH_SHOP:
	case BUILDINGKIND_TUNING_COLOR:			// 2005-11-11 by cmkwon, 추가함
	case BUILDINGKIND_PARTSSHOP:			// 2012-02-29 by hskim, 상점 타이틀 넣기 - 파츠상점
	case BUILDINGKIND_GEARSHOP:				// 2012-02-29 by hskim, 상점 타이틀 넣기 - 기어상점
	case BUILDINGKIND_CARDSHOP:				// 2012-02-29 by hskim, 상점 타이틀 넣기 - 카드상점
		// do nothing
		break;
	case BUILDINGKIND_COMPONENTSHOP:
	case BUILDINGKIND_PETSHOP:
	case BUILDINGKIND_ANTIQUESHOP:
	case BUILDINGKIND_CITYWARP:
	case BUILDINGKIND_PUBLICOFFICE:
	case BUILDINGKIND_ACTIONHOUSE:
	case BUILDINGKIND_RACETRACK:
	case BUILDINGKIND_REFINERY:
	case BUILDINGKIND_LABORATORY:
	case BUILDINGKIND_FACTORY:
	case BUILDINGKIND_MILITARYACADEMY:
	case BUILDINGKIND_ARENA:
	case BUILDINGKIND_WARPOINT_SHOP:
	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_INFINITY_SHOP:	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 상점
	case BUILDINGKIND_LUCKY_OPTION_MACHINE:			// 2010-04-20 by cmkwon, 신규 러키 머신 구현 - 
	case BUILDINGKIND_DISSOLUTION:		// 2010-08-31 by shcho&jskim 아이템용해 시스템 -
	case BUILDINGKIND_TRIGGER_CRYSTAL:	// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
	case BUILDINGKIND_MYSTERY_SHOP:	// 2012-07-09 by hskim, 미스터리 머신 구현
	case BUILDINGKIND_INFLBUFF_SHOP:	// 2013-05-09 by hskim, 세력 포인트 개선

		// not implemented yet
		break;
	// 2014-01-03 by jhseol&bckim, 파괴경매장 - 경매장 이용중인 유저 리스트 삭제
#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG	// - 경매장 이용중인 유저 리스트 삭제
	case BUILDINGKIND_DESTROY_AUCTION:
		{
			ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.deleteLock(m_character.CharacterUniqueNumber);
			//임시값 확인 
			int tmsize = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.size();			
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 사이즈(LEAVE)  (%d) 리스트 (%s)\r\n",tmsize,m_character.CharacterName);
		}
		break;
#endif	//#ifdef SC_DESTROY_AUCTION_JHSEOL_BCKIM_SSJUNG
	// end 2014-01-03 by jhseol&bckim, 파괴경매장 - 경매장 이용중인 유저 리스트 삭제

	default:
		{
			SendErrorMessage (T_FC_EVENT_LEAVE_BUILDING_OK, ERR_PROTOCOL_NO_SUCH_SHOP, pBuildingNPC->BuildingKind);
			return RES_BREAK;
		}
		break;
	}

	*(MessageType_t*)SendBuf = T_FC_EVENT_LEAVE_BUILDING_OK;
	MSG_FC_EVENT_LEAVE_BUILDING_OK *pLeaveOK = (MSG_FC_EVENT_LEAVE_BUILDING_OK*)(SendBuf + SIZE_FIELD_TYPE_HEADER);
	pLeaveOK->PositionVector	= m_character.PositionVector;
	pLeaveOK->TargetVector		= m_character.TargetVector*1000.0f;
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_LEAVE_BUILDING_OK));

	// 현재 들어가 있는 건물 초기화
	m_pCurrentBuildingNPC = NULL;
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_REQUEST_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize	= 0;
	MSG_FC_EVENT_REQUEST_WARP	*pRecvMsgRequestWarp = NULL;

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

	EVENTINFO *pEventInfo
		= m_pCurrentFieldMapChannel->GetTileEventInfoW(&m_character.PositionVector);

	if (pEventInfo
		&& pEventInfo->m_bEventType == EVENT_TYPE_WARP)
	{
		CFieldMapProject *pFieldMapProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pEventInfo->m_EventwParam3);
		
		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_EVENT_REQUEST_WARP#, 세력별 도시맵 처리
		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_EVENT_REQUEST_WARP, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pEventInfo->m_nObejctMonsterUnitKind);
			return RES_BREAK;			
		}

		if (pFieldMapProject == NULL)
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_WARP, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, pEventInfo->m_EventwParam3);
			return RES_BREAK;
		}
		
		// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 접근 가능 유저 체크
		if(FALSE == pFieldMapProject->IsWarpableUser(m_character.CharacterUniqueNumber, m_character.Race))
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_WARP, ERR_CONFERENCEROOM_PERMISSION_DENIED, pEventInfo->m_EventwParam3);
			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_EVENT_REQUEST_WARP, ERR_CANNOT_WARP_TO_OUTPOST, pEventInfo->m_EventwParam3, 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_EVENT_REQUEST_WARP, 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_EVENT_REQUEST_WARP, 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_EVENT_REQUEST_WARP, 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_EVENT_REQUEST_WARP, 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_EVENT_REQUEST_WARP, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 6);
					return RES_BREAK;
				}
			}

		}

		Err_t nErr = this->IsEnableWarp(pFieldMapProject->GetMapInfluenceType(), pFieldMapProject->IsConflictAreaMap(), pFieldMapProject->m_nQuestIndexForWarp, FALSE, pFieldMapProject);		// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
		if(ERR_NO_ERROR != nErr)
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_WARP, nErr, ERR_PROTOCOL_REQ_QUEST_NOT_MATCHED, pEventInfo->m_EventwParam3);
			return RES_BREAK;
		}

		if(FALSE == pFieldMapProject->IsMultiMapChannel(m_character.InfluenceType))
		{
			WarpToMap(pFieldMapProject->GetFirstFieldMapChannel(TRUE)->m_MapChannelIndex, pEventInfo->m_EventwParam2);
			// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
			char szSystemLog[1024];
			sprintf(szSystemLog, "[Notify] WarpToMap(103) : %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);
		}
		else
		{
			SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK|BODYCON_EVENT_SELECTCHANNEL_MASK);
			SendAllChannelState(pFieldMapProject, pEventInfo);
		}
	}
	else
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_WARP, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO);		// 2007-10-15 by cmkwon, 추가함
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_REQUEST_OBJECT_EVENT(const char* pPacket, int nLength, int &nBytesUsed)
{
	int									nRecvTypeSize	= 0;
	MSG_FC_EVENT_REQUEST_OBJECT_EVENT	*pObjectEvent	= NULL;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_REQUEST_OBJECT_EVENT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1402A);
		return RES_RETURN_FALSE;
	}
	pObjectEvent = (MSG_FC_EVENT_REQUEST_OBJECT_EVENT*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

//	// ObjectIndex의 범위 확인
//	if (pObjectEvent->ObjectIndex >= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.size())
//	{
//		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO,
//			pObjectEvent->ObjectIndex,
//			m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.size());
//		return RES_BREAK;
//	}
//
//	OBJECTINFOSERVER &tmpObjectInfo
//		= m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo[pObjectEvent->ObjectIndex];
//	// EVENT 확인
//	if (EVENT_TYPE_NOEVENT == tmpObjectInfo.m_EventInfo.m_bEventType)
//	{
//		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO,
//			pObjectEvent->ObjectIndex, 0, "EVENT가 아님");
//		return RES_BREAK;
//	}
//	EVENTINFO *pEventInfo = &tmpObjectInfo.m_EventInfo;
//
//	// 거리 확인
//	if (D3DXVec3Length(&(tmpObjectInfo.m_vPos-m_character.PositionVector)) >= tmpObjectInfo.m_usObjSizeforClient*2.5f)
//	{
//		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_TOO_FAR_TO_DO,
//			D3DXVec3Length(&(tmpObjectInfo.m_vPos-m_character.PositionVector)),
//			tmpObjectInfo.m_usObjSizeforClient*2.5f);
//		return RES_BREAK;
//	}

// 2004-11-23 by cmkwon
//	vectorObjectInfoServer::iterator it(m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.begin());
//	while(it != m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.end())
//	{
//		if(pObjectEvent->ObjectType == it->m_dwObjType)
//		{
//			D3DXVECTOR3	tmVec3 = A2DX(pObjectEvent->ObjectPosition);
//			if(D3DXVec3Length(&(tmVec3 - it->m_vPos)) < 10.0f)
//			{
//				break;
//			}
//		}
//		it++;
//	}
//
//	if (it == m_pCurrentFieldMapChannel->m_pFieldMapProject->m_vectorObjectInfo.end())
//	{
//		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_TOO_FAR_TO_DO,
//			pObjectEvent->ObjectType, 0);
//		return RES_BREAK;
//	}
//	EVENTINFO *pEventInfo = &it->m_EventInfo;

	EVENTINFO tmpEventInfo;		// 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차

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

	// 2007-12-14 by cmkwon, 캐릭터모드에서 바로 워프 시스템 구현 - 체크 추가
	if((EVENT_TYPE_CHARACTERMODE_WARP == pEventInfo->m_bEventType || EVENT_TYPE_CHARACTERMODE_DIRECTLY_WARP == pEventInfo->m_bEventType)
		&& FALSE == m_character.CharacterMode)
	{// 2006-07-19 by cmkwon, 캐릭터모드 워프시 캐릭터모드 체크
		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_TOO_FAR_TO_DO,
			pObjectEvent->ObjectType, 0);
		return RES_BREAK;
	}

	if (pEventInfo->m_bEventType == EVENT_TYPE_WARP
		|| EVENT_TYPE_CHARACTERMODE_WARP == pEventInfo->m_bEventType
		|| EVENT_TYPE_CHARACTERMODE_DIRECTLY_WARP == pEventInfo->m_bEventType)	// 2007-12-14 by cmkwon, 캐릭터모드에서 바로 워프 시스템 구현 - 체크 추가
	{
		if (COMPARE_BODYCON_BIT(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK))
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_BODYCONDITION);
			return RES_BREAK;
		}

		// 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차
		if( NULL != m_pCurrentFieldMapChannel )
		{
			if( IS_TYLENT_JUNGLE_MAP_INDEX(m_pCurrentFieldMapChannel->m_MapChannelIndex.MapIndex) && IS_STONES_RUIN_MAP_INDEX(pEventInfo->m_EventwParam3) )
			{
				if( COMPARE_INFLUENCE(m_character.InfluenceType, INFLUENCE_TYPE_VCN) )
				{
					if( TRUE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl(INFLUENCE_TYPE_ANI) )
					{
						memcpy(&tmpEventInfo, pEventInfo, sizeof(tmpEventInfo));
						pEventInfo = &tmpEventInfo;

						pEventInfo->m_EventwParam2 = 15;		// 고민하지말고 맵 바뀌면 깔끔하게 '모선전 진행시 스톤즈 루인 진입 불가' 관련 루틴 다 삭제하삼 by hskim 2012-08-01
						pEventInfo->m_EventwParam3 = INFLUENCE_CITY_MAP_INDEX;
					}
				}
			}
		}
		// end 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차

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

		///////////////////////////////////////////////////////////////////////////////
		// 2009-10-12 by cmkwon, 프리스카 제거 방안 적용 - CFieldIOCPSocket::Process_FC_EVENT_REQUEST_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_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED, pEventInfo->m_nObejctMonsterUnitKind);
			return RES_BREAK;			
		}

		if (NULL == pFieldMapProject)
		{// 맵 데이터 에러
			SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, pEventInfo->m_EventwParam3);
			return RES_BREAK;
		}

		if(IS_TUTORIAL_MAP_INDEX(m_character.MapChannelIndex.MapIndex))
		{// 2005-08-02 by cmkwon, 튜토리얼맵에서 워프시에는 무조건 세력별 도시맵으로 워프시킨다.

			WarpToCityMap();
			return RES_BREAK;
		}

		// 2012-11-29 by jhseol, OX이벤트 맵 워프제한
		if( FALSE == ms_pFieldIOCP->IsMapWarpPossible(pFieldMapProject->m_nMapIndex) )
		{
			SendString128(STRING_128_USER_NOTICE, STRMSG_121129_0001);
			SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED, pFieldMapProject->m_nMapIndex, 0);
			if( INFLUENCE_GARDEN_MAP_INDEX == pEventInfo->m_EventwParam3 )
			{
				WarpToCityMap();
			}
			return RES_BREAK;
		}
		// end 2012-11-29 by jhseol, OX이벤트 맵 워프제한

		// 2013-01-21 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);
			if( INFLUENCE_GARDEN_MAP_INDEX == pEventInfo->m_EventwParam3 )
			{
				WarpToCityMap();
			}
			return RES_BREAK;
		}
#endif
		// end 2013-01-21 by jhseol, NGC 전전기지 트리거 시스템 - 워프제한
		
		// 2007-08-30 by cmkwon, 회의룸 시스템 구현 - 접근 가능 유저 체크
		if(FALSE == pFieldMapProject->IsWarpableUser(m_character.CharacterUniqueNumber, m_character.Race))
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_CONFERENCEROOM_PERMISSION_DENIED, pEventInfo->m_EventwParam3);
			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_EVENT_REQUEST_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_EVENT_REQUEST_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_EVENT_REQUEST_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_EVENT_REQUEST_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_EVENT_REQUEST_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_EVENT_REQUEST_OBJECT_EVENT, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP, pEventInfo->m_EventwParam3, 6);
					return RES_BREAK;
				}
			}
			
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2005-06-22 by cmkwon, Warp is possible check
		Err_t nErr = this->IsEnableWarp(pFieldMapProject->GetMapInfluenceType(), pFieldMapProject->IsConflictAreaMap(), pFieldMapProject->m_nQuestIndexForWarp, FALSE, pFieldMapProject);		// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템
		if(ERR_NO_ERROR != nErr)
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, nErr, ERR_PROTOCOL_REQ_QUEST_NOT_MATCHED, pEventInfo->m_EventwParam3);
			return RES_BREAK;
		}

		if (pFieldMapProject->BelongsToServer())
		{
			// 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차
			if( INFLUENCE_GARDEN_MAP_INDEX == pEventInfo->m_EventwParam3 && IS_TYLENT_JUNGLE_MAP_INDEX(pFieldMapProject->m_nMapIndex) )
			{
				memcpy(&tmpEventInfo, pEventInfo, sizeof(tmpEventInfo));
				pEventInfo = &tmpEventInfo;

				pEventInfo->m_EventwParam2 = 300;		// 추후에 맵개선이 되면 '모선전 진행시 스톤즈 루인 진입 불가' 부분은 모두 삭제 처리한다.
			}
			// end 2012-08-01 by hskim, 모선전 개선 - 모선전 진행시 스톤즈 루인 진입 불가 2차

			///////////////////////////////////////////////////////////////////
			// 같은 필드 서버로의 워프인 경우
			if (FALSE == pFieldMapProject->IsMultiMapChannel(m_character.InfluenceType))
			{
				CFieldMapChannel *pFMChann = pFieldMapProject->GetFirstFieldMapChannel(TRUE);
				if(FALSE == pFMChann->IsCheckUserCountForWarp(this))
				{
					SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED,
						ERR_PROTOCOL_CHANNEL_USER_OVERFLOW, pFMChann->GetNumClients());
					return RES_BREAK;
				}
				WarpToMap(pFMChann->m_MapChannelIndex, pEventInfo->m_EventwParam2);
				// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
				char szSystemLog[1024];
				sprintf(szSystemLog, "[Notify] WarpToMap(104) : %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);
			}
			else
			{
				SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK|BODYCON_EVENT_SELECTCHANNEL_MASK);
				SendAllChannelState(pFieldMapProject, pEventInfo);
			}

			return RES_RETURN_TRUE;
		}
		else
		{
			///////////////////////////////////////////////////////////////////
			// 다른 필드 서버로의 워프인 경우

			// event 처리
			EventResult_t ret = HandleEvent(pEventInfo);

			// event result에 대한 작업
			if (ret == EVENT_RESULT_BREAK)
			{
#ifdef _DEBUG
				DBGOUT(STRMSG_S_F2NOTIFY_0067,
					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_EVENT_REQUEST_WARP, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO, eventType, ret);
#ifdef _DEBUG
				SendString128(STRING_128_DEBUG_L1, STRMSG_S_F2NOTIFY_0068);
				g_pFieldGlobal->WriteSystemLogEX(FALSE, STRERR_S_F2NOTIFY_0004,
					m_character.AccountName, m_character.CharacterName, m_pCurrentFieldMapChannel->m_pFieldMapProject->m_nMapIndex,
					pEventInfo->m_EventwParam3, pEventInfo->m_EventwParam2);
#else
				Close(0x14026);
#endif
			}
			else
			{
				// error
				SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO, pEventInfo->m_bEventType, ret);
				return RES_BREAK;
			}
		}
	}
	else if(EVENT_TYPE_OBJ_QUEST_OBJECT == pEventInfo->m_bEventType)
	{
		///////////////////////////////////////////////////////////////////////////////
		// 2005-08-17 by cmkwon, 모든 워프타겟인덱스 퀘스트를 체크한다.
		this->CheckSuccessAllQuestByWarpTargetIndex(m_character.MapChannelIndex.MapIndex, pEventInfo->m_EventwParam1);
	}
// 2005-02-15 by cmkwon, 지금은 사용 안됨
//	else if (pEventInfo->m_bEventType == EVENT_TYPE_ENTER_BUILDING)
//	{
//		// P2P PK 중이면 상점 못들어감
//		if (!IS_VALID_CLIENT_INDEX(m_peerP2PPKClientIndex))
//		{
//			SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK);
//
//			// building에서 나왔을 때 target vector 결정
//			D3DXVec3Normalize(&m_character.TargetVector, &-m_character.TargetVector);
//
//			// building에서 나왔을 때 position vector 결정
//			D3DXVECTOR3 vTmp = m_character.PositionVector + (40 * m_character.TargetVector);
//			m_pCurrentFieldMapChannel->UpdateBlockPosition(m_character.PositionVector, vTmp, m_character.ClientIndex);
//			m_character.PositionVector = vTmp;
//
//			// MSG_FC_EVENT_ENTER_BUILDING 전송
//			INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, pMsgEnterBuildingBuf);
//			BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pEventInfo->m_EventwParam1);
//
//			pMsgEnterBuilding->BuildingNPCInfo = *pBuildingNPC;
//
//			SendAddData(pMsgEnterBuildingBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));
//		}
//	}
	else
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_OBJECT_EVENT, ERR_PROTOCOL_INVALID_MAP_EVENT_INFO);		// 2007-10-15 by cmkwon, 추가함
		return RES_BREAK;
	}

	return RES_RETURN_TRUE;
}
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_SELECT_CHANNEL(const char* pPacket, int nLength, int &nBytesUsed)
{
	int							nRecvTypeSize		= 0;
	MSG_FC_EVENT_SELECT_CHANNEL	*pMsgSelectChannel	= NULL;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_SELECT_CHANNEL);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL, ERR_PROTOCOL_INVALID_FIELD_DATA);
		return RES_BREAK;
	}
	pMsgSelectChannel = (MSG_FC_EVENT_SELECT_CHANNEL*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (m_character.ClientIndex != pMsgSelectChannel->ClientIndex)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL, ERR_PROTOCOL_INVALID_CLIENTINDEX,
							m_character.ClientIndex, pMsgSelectChannel->ClientIndex);

		return RES_BREAK;
	}

	CFieldMapProject *pMapProject
		= (CFieldMapProject*)ms_pFieldIOCP->GetMapProjectByMapIndex(pMsgSelectChannel->MapChannelIndex.MapIndex);
	if (pMapProject == NULL)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL, ERR_PROTOCOL_NO_SUCH_MAP_SERVED,
							pMsgSelectChannel->MapChannelIndex.MapIndex);

		return RES_BREAK;
	}

	CFieldMapChannel *pFMChann = pMapProject->GetFieldMapChannelByIndex(pMsgSelectChannel->MapChannelIndex.ChannelIndex);
	if (pFMChann == NULL)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL, ERR_PROTOCOL_NO_SUCH_CHANNEL,
							pMsgSelectChannel->MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}

	if(FALSE == pFMChann->IsCheckUserCountForWarp(this))
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED,
							ERR_PROTOCOL_CHANNEL_USER_OVERFLOW,	pFMChann->GetNumClients());
		return RES_BREAK;
	}

	// 워프 처리
	WarpToMap(pMsgSelectChannel->MapChannelIndex, pMsgSelectChannel->WarpTargetIndex);
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(105) : %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);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_SELECT_CHANNEL_WITH_PARTY(const char* pPacket, int nLength, int &nBytesUsed)
{
	int										nRecvTypeSize			= 0;
	MSG_FC_EVENT_SELECT_CHANNEL_WITH_PARTY	*pMsgSelectChannelParty	= NULL;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_SELECT_CHANNEL_WITH_PARTY)
					+ ((MSG_FC_EVENT_SELECT_CHANNEL_WITH_PARTY*)(pPacket + nBytesUsed))->nPartyMembers * sizeof(UINT);
	if(nLength - nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_INVALID_FIELD_DATA);
		Close(0x1402A);
		return RES_BREAK;
	}
	pMsgSelectChannelParty = (MSG_FC_EVENT_SELECT_CHANNEL_WITH_PARTY*)(pPacket + nBytesUsed);
	nBytesUsed += nRecvTypeSize;

	if (m_character.ClientIndex != pMsgSelectChannelParty->ClientIndex)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_INVALID_CLIENTINDEX,
							m_character.ClientIndex, pMsgSelectChannelParty->ClientIndex);

		return RES_BREAK;
	}

	CFieldMapProject *pMapProject
		= (CFieldMapProject*)ms_pFieldIOCP->GetMapProjectByMapIndex(pMsgSelectChannelParty->MapChannelIndex.MapIndex);
	if (pMapProject == NULL)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_NO_SUCH_MAP_SERVED,	pMsgSelectChannelParty->MapChannelIndex.MapIndex);
		return RES_BREAK;
	}

	CFieldMapChannel *pFMChann = pMapProject->GetFieldMapChannelByIndex(pMsgSelectChannelParty->MapChannelIndex.ChannelIndex);
	if (pFMChann == NULL)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_NO_SUCH_CHANNEL, pMsgSelectChannelParty->MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}

	if(FALSE == pFMChann->IsCheckUserCountForWarp(this))
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED,
							ERR_PROTOCOL_CHANNEL_USER_OVERFLOW,	pFMChann->GetNumClients());
		return RES_BREAK;
	}

	CFieldParty *pFParty = this->m_pFieldParty;			// 2006-07-04 by cmkwon
	if (pFParty == NULL
		|| pFParty->GetMasterCharacterUniqueNumber() != m_character.CharacterUniqueNumber)
	{
		SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_PARTY_MASTER_NOT_MATCHED);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2006-11-02 by cmkwon
	MAP_CHANNEL_INDEX beforeMapChannIndex = m_character.MapChannelIndex;
	
	// 마스터 워프
	WarpToMap(pMsgSelectChannelParty->MapChannelIndex, pMsgSelectChannelParty->WarpTargetIndex);
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(106) : %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*)pMsgSelectChannelParty) + sizeof(MSG_FC_EVENT_SELECT_CHANNEL_WITH_PARTY));
	for (int i = 0; i < pMsgSelectChannelParty->nPartyMembers; i++)
	{
		CFieldIOCPSocket *pMemberSock = ms_pFieldIOCP->m_mapCharacterUniqueNumber.findLock(ArrCharacterUniqueNumber[i]);
		if (NULL == pMemberSock
			|| FALSE == pMemberSock->IsValidCharacter()
			|| pMemberSock->m_pFieldParty != pFParty)
		{
// 2006-11-02 by cmkwon, 필요 없음
//			SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, ERR_PROTOCOL_NO_SUCH_PARTY_MEMBER);
			continue;
		}

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

		///////////////////////////////////////////////////////////////////////////////
		// 2006-11-02 by cmkwon, Warp is possible check
		Err_t err = pMemberSock->IsEnableWarp(pMapProject->GetMapInfluenceType(), pMapProject->IsConflictAreaMap(), pMapProject->m_nQuestIndexForWarp);
		if(ERR_NO_ERROR != err)
		{
			pMemberSock->SendErrorMessage(T_FC_EVENT_SELECT_CHANNEL_WITH_PARTY, err);
			continue;
		}

		// 워프 처리
		pMemberSock->WarpToMap(pMsgSelectChannelParty->MapChannelIndex, pMsgSelectChannelParty->WarpTargetIndex);
		// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
		char szSystemLog[1024];
		sprintf(szSystemLog, "[Notify] WarpToMap(107) : %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);
	}// END - for (int i = 0; i < pMsgSelectChannelParty->nPartyMembers; i++)

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_REQUEST_RACING_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	int			nRecvTypeSize = 0;
	MSG_FC_EVENT_REQUEST_RACING_WARP *pRvMsg = NULL;

	nRecvTypeSize = sizeof(MSG_FC_EVENT_REQUEST_RACING_WARP);
	if(nLength-nBytesUsed < nRecvTypeSize)
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_RACING_WARP, ERR_PROTOCOL_INVALID_FIELD_DATA);
		return RES_RETURN_FALSE;
	}
	pRvMsg = (MSG_FC_EVENT_REQUEST_RACING_WARP*)(pPacket+nBytesUsed);
	nBytesUsed += nRecvTypeSize;

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

	if(FALSE == m_pRacingFieldMapChannel->IsJoinedUser(this))
	{
		return RES_BREAK;
	}

	WarpToMap(m_pRacingFieldMapChannel->GetMapChannelIndex());	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST,
									MSG_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST, pRecvMsg);

	if (pRecvMsg->MapChannelIndex != m_pCurrentFieldMapChannel->m_MapChannelIndex)
	{
		SendErrorMessage(T_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST, ERR_PROTOCOL_MAP_CHANNEL_NOT_MATCHED, pRecvMsg->MapChannelIndex.MapIndex, pRecvMsg->MapChannelIndex.ChannelIndex);
		return RES_BREAK;
	}
	
	if(IS_OUTPOST_CITY_MAP_INDEX(pRecvMsg->MapChannelIndex.MapIndex))
	{
		if(FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
		{
			SendErrorMessage(T_FC_EVENT_GET_SHOP_WARP_TARGET_MAP_LIST, ERR_PROTOCOL_NOT_HAVE_GUILD, m_character.GuildUniqueNumber, pRecvMsg->MapChannelIndex.MapIndex);
			return RES_BREAK;
		}
	}
	

	SendAddDataBuffer(m_pCurrentFieldMapChannel->m_pFieldMapProject->m_buffGetWarpTargetMapListOK);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_REQUEST_SHOP_WARP(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_REQUEST_SHOP_WARP,
									MSG_FC_EVENT_REQUEST_SHOP_WARP, pRecvMsg);

	// 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, 필드이동금지아이템

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

	CFieldMapProject *pProject = m_pCurrentFieldMapChannel->m_pFieldMapProject;
// 2007-01-29 by cmkwon, 아래와 같이 수정함
//	list<WARP_TARGET_MAP_INFO_4_EXCHANGE>::iterator itr = pProject->m_listCityWarpTargetMapInfo.begin();
//
//	while (pProject->m_listCityWarpTargetMapInfo.end() != itr)
//	{
//		if (itr->MapIndex == pRecvMsg->MapIndex)
//		{
//			break;
//		}
//
//		itr++;
//	}
//
//	if (itr == pProject->m_listCityWarpTargetMapInfo.end())
//	{
//		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_COMMON_UNKNOWN_ERROR, 0, 0, STRMSG_S_F2NOTIFY_0069);
//		return RES_BREAK;
//	}
//	int nWarpFee = itr->Fee;
	WARP_TARGET_MAP_INFO_4_EXCHANGE *pWarpInfo = pProject->GetWarpInfoByTargetMapIndex(pRecvMsg->MapIndex);
	if(NULL == pWarpInfo)
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_COMMON_UNKNOWN_ERROR, pRecvMsg->MapIndex, 0, STRMSG_S_F2NOTIFY_0069);
		return RES_BREAK;
	}
	int nWarpFee = pWarpInfo->Fee;

	CFieldMapProject *pTargetProject = ms_pFieldIOCP->GetFieldMapProjectByMapIndex(pWarpInfo->MapIndex);
	if (pTargetProject == NULL)
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_PROTOCOL_NO_SUCH_MAP_SERVED, pWarpInfo->MapIndex);
		return RES_BREAK;
	}

	Err_t Err = CheckPossibleBurningMapWarp(pWarpInfo->MapIndex);
	if(ERR_NO_ERROR != Err)
	{
		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, Err, pWarpInfo->MapIndex);
		return RES_BREAK;
	}
	
	// 2012-11-29 by jhseol, OX이벤트 맵 워프제한
	if( FALSE == ms_pFieldIOCP->IsMapWarpPossible(pTargetProject->m_nMapIndex) )
	{
		SendString128(STRING_128_USER_NOTICE, STRMSG_121129_0001);
		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED, pTargetProject->m_nMapIndex, 0);
		return RES_BREAK;
	}
	// end 2012-11-29 by jhseol, OX이벤트 맵 워프제한
	
	//////////////////////////////////////////////////////////////////////////
	// 2007-09-20 by dhjin, 전진기지 도시 맵으로 워프 시 체크 
	if(IS_OUTPOST_CITY_MAP_INDEX(pTargetProject->m_nMapIndex))
	{

// 2007-10-06 by cmkwon, 부지도자는 여단 가입 상태와 상관이 없음 - 여단 체크 필요 없음
//		if(FALSE == IS_VALID_UNIQUE_NUMBER(m_character.GuildUniqueNumber))
//		{
//			SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_PROTOCOL_NOT_HAVE_GUILD);
//			return RES_BREAK;
//		}

		// 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(pTargetProject->m_nMapIndex != this->ms_pFieldIOCP->m_OutPostManager.GetOutPostCityMapIndexByGuildUID(m_character.GuildUniqueNumber))
			{	
				SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP);
				return RES_BREAK;
			}
		}
		else
		{
			///////////////////////////////////////////////////////////////////////////////
			// 2007-09-28 by cmkwon, 지도자,부지도자의 세력이 해당 전진기지의 소유세력과 같은지 체크
			BYTE byInflTy = ms_pFieldIOCP->m_OutPostManager.GetOutPostInfluenceByMapIndex(pTargetProject->m_nMapIndex);
			if(FALSE == COMPARE_INFLUENCE(m_character.InfluenceType, byInflTy))
			{
				SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP);
				return RES_BREAK;
			}
		}

		///////////////////////////////////////////////////////////////////////////////
		// 2007-09-28 by cmkwon, 전진기지전이 진행 중인지 체크
		if(ms_pFieldIOCP->m_OutPostManager.CheckOutPostWaring(pTargetProject->m_nMapIndex))
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_CANNOT_WARP_TO_OUTPOST_CITY_MAP);
			return RES_BREAK;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// 2008-07-21 by dhjin, 워프 에러 메세지 문제로 다음과 같이 수정
//  if(ERR_NO_ERROR != IsEnableWarp(pTargetProject->GetMapInfluenceType(), pTargetProject->IsConflictAreaMap(), pTargetProject->m_nQuestIndexForWarp))
//	{// 2005-12-12 by cmkwon, 워프가능 체크
//		SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED
//			, pTargetProject->m_nQuestIndexForWarp, pTargetProject->m_nMapIndex);
//		
//		return RES_BREAK;
//	}

	Err_t errCode = IsEnableWarp(pTargetProject->GetMapInfluenceType(), pTargetProject->IsConflictAreaMap(), pTargetProject->m_nQuestIndexForWarp, FALSE, pTargetProject);		// 2011-10-28 by hskim, EP4 [트리거 시스템] - 크리스탈 시스템 
	if(ERR_NO_ERROR != errCode)
	{// 2005-12-12 by cmkwon, 워프가능 체크
		if(ERR_REQ_WARP_COMPLETIONQUEST_NOT_MATCHED == errCode)
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, ERR_PROTOCOL_REQ_WARP_REQUIREMENTS_NOT_MATCHED
			, pTargetProject->m_nQuestIndexForWarp, pTargetProject->m_nMapIndex);
		}
		else 
		{
			SendErrorMessage(T_FC_EVENT_REQUEST_SHOP_WARP, errCode);
		}
		
		return RES_BREAK;
	}

	// 2007-10-06 by cmkwon, 부지도자 2명의 호칭을 다르게 설정 -
	//if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER))	// 2006-12-08 by dhjin, 부지도자 추가함
	if(FALSE == COMPARE_RACE(m_character.Race, RACE_INFLUENCE_LEADER|RACE_INFLUENCE_SUBLEADER_MASK))
	{// 2006-04-20 by cmkwon, 세력리더는 워프상점 무료 이용

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

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

		///////////////////////////////////////////////////////////////////////////////
		// 2007-09-03 by cmkwon, 멤버쉼 서비스 수정 - 모든 워프비용 50% 할인
		if(this->m_ItemManager.IsExistPremiumCard())
		{
			nWarpFee				= max(1, nWarpFee / (100/MEMBERSHIP_DISCOUNT_WARPFEE));
		}

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

		// 수수료 처리
		m_ItemManager.UpdateItemCountByPointer(pMoney, -nWarpFee, IUT_GENERAL);
	}

	// 워프
	if (FALSE == pTargetProject->IsMultiMapChannel(m_character.InfluenceType))
	{
		// 2007-09-11 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
		char szSystemLog[1024];
		sprintf(szSystemLog, "[Notify] WarpToMap(200) : %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);

		WarpToMap(pTargetProject->GetFirstFieldMapChannel(TRUE)->m_MapChannelIndex, pRecvMsg->TargetIndex);
	}
	else
	{
		SetBodyConditionBit(m_character.BodyCondition, BODYCON_EVENT_HANDLE_MASK|BODYCON_EVENT_SELECTCHANNEL_MASK);
		SendAllChannelState(pTargetProject, pRecvMsg->TargetIndex);
	}

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

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_EVENT_CHARACTERMODE_ENTER_BUILDING(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING,
									MSG_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, pRecvMsg);

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

// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 아래로 이동
// 	// 2007-07-09 by dhjin, 개인 상점 스킬 중에는 상점 이용 불가
// 	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
// 	{
// 		SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_USING_BAZAAR);
// 		return RES_BREAK;
// 	}

	BUILDINGNPC *pBuildingNPC = m_pCurrentFieldMapChannel->m_pFieldMapProject->m_mapBuilding2Building.findEZ(pRecvMsg->nBuildingIndex0);
	if(NULL == pBuildingNPC)
	{
		SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_COMMON_UNKNOWN_ERROR, pRecvMsg->nBuildingIndex0);
		return RES_BREAK;
	}

	// 2008-07-18 by cmkwon, 아이템 복사 버그 수정(개인상점과 거래동시에 이용 하는 것 막기) - 상점 열때 거래 중 체크
	if(IS_VALID_UNIQUE_NUMBER(m_peerTraderCharacterUniqueNumber))
	{
		SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_ITEM_TRADING, pBuildingNPC->BuildingIndex, m_peerTraderCharacterUniqueNumber);
		return RES_BREAK;
	}
	// 2007-07-09 by dhjin, 개인 상점 스킬 중에는 상점 이용 불가
	if(BAZAAR_STATE_NONE != m_bazaarManager.GetBazaarState())
	{
		SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_USING_BAZAAR, pBuildingNPC->BuildingIndex);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-09-13 by cmkwon, 베트남 2차패스워드 구현 - T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING 요청시 2차패스워드 체크
	if(FALSE == this->CheckSecondaryPasswordLock())
	{
		// 2007-10-02 by cmkwon, 베트남 2차패스워드 수정 - 보급 상점은 허가됨
		// 2007-10-05 by cmkwon, 베트남 2차패스워드 수정 - 워프 상점도 허가됨
		if(BUILDINGKIND_REFINERY != pBuildingNPC->BuildingKind
			&& BUILDINGKIND_CITYWARP != pBuildingNPC->BuildingKind)
		{
			SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_SECPASS_LOCKED);
			return RES_BREAK;
		}
	}

	// 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
	if(m_ItemManager.GetUsingStore())
	{
		SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_CANNOT_USE_STORE);
		return RES_BREAK;
	}
	if ( BUILDINGKIND_STORE == pBuildingNPC->BuildingKind )
	{
		m_ItemManager.SetUsingStore(TRUE);
	}
	// end 2013-04-12 by jhseol, 필드창고 사용으로 더블인첸트 버그 수정
	
	switch(pBuildingNPC->BuildingKind)		
	{
	case BUILDINGKIND_ARENA:
	case BUILDINGKIND_INFINITY:	// 2009-09-09 ~ 2010 by dhjin, 인피니티 - 
		{
			// 2008-03-07 by dhjin, 아레나 통합 - 아레나 서버와 연결이 안되어 있으면 오류를 보낸다.
			if(FALSE == g_pFieldGlobal->IsArenaServer()
				&& FALSE == g_pFieldGlobal->GetField2ArenaFieldWinSocket()->IsConnected()
				)
			{
				SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_NOT_CONNECT_TO_ARENASERVER);
				return RES_BREAK;
			}

			// 2007-07-11 by cmkwon, 아레나블럭 시스템 구현 - T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING
			int nRemainMinute = 0;
			if(ms_pFieldIOCP->m_arenaBlockManager.IsExistChatBlockList(&nRemainMinute, m_character.CharacterName))
			{
				SendErrorMessage(T_FC_EVENT_CHARACTERMODE_ENTER_BUILDING, ERR_ARENA_BLOCKED, nRemainMinute);
				return RES_BREAK;
			}
		}
		break;
		
		// 2014-03-18 by bckim, 마켓 ON/OFF
	case BUILDINGKIND_AUCTION:
		{
#ifdef SC_MARKET_JHSEOL_BCKIM_SSJUNG
			if ( FALSE == ms_pFieldIOCP->m_bMarketActivation )
			{
				SendString128(STRING_128_USER_NOTICE, STRMSG_130318_0003);
				return RES_BREAK;
			}			
#endif
		}
		break;
		// End. 2014-03-18 by bckim, 마켓 ON/OFF			
		
	default:
		{
		}
	}
	m_pCurrentBuildingNPC				= pBuildingNPC;

	INIT_MSG_WITH_BUFFER(MSG_FC_EVENT_ENTER_BUILDING, T_FC_EVENT_ENTER_BUILDING, pMsgEnterBuilding, SendBuf);
	pMsgEnterBuilding->BuildingNPCInfo				= *pBuildingNPC;
// 2006-02-08 by cmkwon
//	pMsgEnterBuilding->fCityWarTexRate				= m_pCurrentFieldMapChannel->CityWarGetTexPercent(pBuildingNPC->BuildingIndex, m_character.GuildUniqueNumber);
	pMsgEnterBuilding->fInflDistributionTexPercent	= ms_pFieldIOCP->GetInfluenceTypeDistirbutionTexPercent(m_character.InfluenceType);
	SendAddData(SendBuf, MSG_SIZE(MSG_FC_EVENT_ENTER_BUILDING));

	return RES_RETURN_TRUE;
}


///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2006-07-21 ~ 2006-07-21
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK,
									MSG_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, pRecvMsg);

	if(FALSE == this->IsValidCharacter())
	{// 2008-09-09 by cmkwon, 체크 추가, 죽은 상태에서는 세력소환 참가 불가
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	if(NULL == m_pCurrentFieldMapChannel)
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, ERR_COMMON_UNKNOWN_ERROR);
		return RES_BREAK;
	}

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

	SCALL_WARP_EVENT tmCallWarpEvent;
	MEMSET_ZERO(&tmCallWarpEvent, sizeof(SCALL_WARP_EVENT));
	Err_t errCode = ms_pFieldIOCP->CheckCallWarpEventRequestAck(&tmCallWarpEvent, pRecvMsg->dwCallWarpEventID0);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, errCode);
		return RES_BREAK;
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2008-09-09 by cmkwon, /세력소환 명령어 인자 리스트에 기어타입 추가 - 
	if(FALSE == tmCallWarpEvent.IsValidCharacter(this->GetCharacter()))
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, ERR_COMMON_UNKNOWN_ERROR);
		return RES_BREAK;
	}

	CFieldMapChannel *pFMapChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(tmCallWarpEvent.CallMapChannelIndex);
	if(NULL == pFMapChann)
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, ERR_COMMON_UNKNOWN_ERROR);
		return RES_BREAK;
	}

	if(pFMapChann == GetCurrentFieldMapChannel())
	{// 2006-07-24 by cmkwon, 현재 같은 MapChannel에 있다
		return RES_BREAK;
	}

	errCode = this->IsEnableWarp(pFMapChann->GetMapInfluenceTypeW(), FALSE);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, errCode);
		return RES_BREAK;
	}

	// 2006-11-17 by cmkwon, 이벤트 인원 설정 체크
	errCode = ms_pFieldIOCP->CheckCallWarpEventRequestAck(&tmCallWarpEvent, pRecvMsg->dwCallWarpEventID0, TRUE);
	if(ERR_NO_ERROR != errCode)
	{
		SendErrorMessage(T_FC_EVENT_CALL_WARP_EVENT_REQUEST_ACK, errCode);
		return RES_BREAK;
	}

	this->WarpToMap(tmCallWarpEvent.CallMapChannelIndex, &tmCallWarpEvent.vWarpPosition);
	// 2007-07-03 by cmkwon, Warp 버그 체크 로그 - 시스템로그 추가
	char szSystemLog[1024];
	sprintf(szSystemLog, "[Notify] WarpToMap(108) : %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);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_EVENT_CLICK_TELEPORT(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		dhjin
/// \date		2007-09-06 ~ 2007-09-06
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_CLICK_TELEPORT(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_CLICK_TELEPORT,
									MSG_FC_EVENT_CLICK_TELEPORT, pRecvMsg);

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

	CFieldMapChannel *pFMChann = ms_pFieldIOCP->GetFieldMapChannelByMapChannelIndex(MAP_CHANNEL_INDEX(pRecvMsg->MapIndex, 0));
	if(NULL == pFMChann)
	{
		return RES_BREAK;
	}

	// 2007-09-20 by cmkwon, 텔레포트 소환 관련 수정
	if(TELEPORT_STATE_READY != pFMChann->GetTelePortState())
	{
		// 2007-09-20 by cmkwon, 텔레포트 수정 - 에러코드 추가 필요
		return RES_BREAK;
	}

	// 2007-09-07 by dhjin, 지도자, 부지도자인지 체크한다.
	// 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))
	{
		SendErrorMessage(T_FC_EVENT_CLICK_TELEPORT, ERR_CHAT_PERMISSION_DENIED);
		return RES_BREAK;
	}

	CFieldMonster	*pFMon = pFMChann->GetFieldMonster(pRecvMsg->TargetIndex, 0);
	if(NULL == pFMon
		|| FALSE == pFMon->IsValidMonster()
		|| FALSE == IS_TELEPORT_MONSTER(pFMon->MonsterInfoPtr->Belligerence))
	{
		return RES_BREAK;
	}

	// 2007-09-07 by dhjin, 세력에 맞게 텔레포트가 클릭이 되었는지 체크
	if(IS_MAP_INFLUENCE_VCN(pFMChann->GetMapInfluenceTypeW()))
	{
		if(FALSE == IS_ANI_INFLUENCE_TYPE(m_character.InfluenceType)
			|| BELL_INFLUENCE_TELEPORT_ANI != pFMon->MonsterInfoPtr->Belligerence)
		{
			return RES_BREAK;
		}
	}
	else if(IS_MAP_INFLUENCE_ANI(pFMChann->GetMapInfluenceTypeW()))
	{
		if(FALSE == IS_VCN_INFLUENCE_TYPE(m_character.InfluenceType)
			|| BELL_INFLUENCE_TELEPORT_VCN != pFMon->MonsterInfoPtr->Belligerence)
		{
			return RES_BREAK;
		}
	}
	else
	{
		// 2007-09-20 by cmkwon, 텔레포트 수정 - 세력맵이 아닌다
		return RES_BREAK;
	}

	// 2007-09-20 by cmkwon, 텔레포트 수정 - 해당 세력의 모선전이 진행중일때만 처리
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.CheckBossMonsterSummoningByAttackInfl( (BELL_INFLUENCE_TELEPORT_VCN == pFMon->MonsterInfoPtr->Belligerence) ? INFLUENCE_TYPE_VCN : INFLUENCE_TYPE_ANI ))
	{
		// 2007-09-20 by cmkwon, 텔레포트 수정 - 에러코드 추가 필요
		return RES_BREAK;
	}
	
	// 2007-09-15 by dhjin, 텔레포트 빌딩 완료를 위해 틱을 돌린다.
	STELEPORT_INFO_BUILDING		TeleportInfoBuilding;
	TeleportInfoBuilding.bBuilded		= FALSE;
	TeleportInfoBuilding.MapIndex		= pRecvMsg->MapIndex;
	TeleportInfoBuilding.MapInfluence	= pFMChann->GetMapInfluenceTypeW();
	TeleportInfoBuilding.BuildStartTime.SetCurrentDateTime();
	if(FALSE == ms_pFieldIOCP->m_InflWarManager.InsertTelePortInfoBuing(&TeleportInfoBuilding))
	{
		// 2007-09-20 by cmkwon, 텔레포트 수정 - 에러코드 추가 필요
		return RES_BREAK;
	}
	
	// 2007-09-07 by dhjin, 텔레포트 빌딩 처리
	pFMChann->SetTelePortState(TELEPORT_STATE_BUILDING);

	//////////////////////////////////////////////////////////////////////////
	// 2008-03-28 by dhjin, 모선전 정보 표시 기획안 - 
	ms_pFieldIOCP->m_InflWarManager.SetMSWarInfo(pFMChann->GetMapChannelIndex().MapIndex, T_MSWARINFO_MODIFY_CHANGE_TELEPORT_STATE, MS_WAR_HP_RATE, TELEPORT_STATE_BUILDING, pFMon->MonsterInfoPtr->Belligerence);

	// 2007-09-07 by dhjin, 텔레포트 바디 컨디션 수정.
	CLEAR_BODYCON_BIT(pFMon->BodyCondition, BODYCON_MON_BUILDED);			// 2007-09-20 by cmkwon, 텔레포트 수정 - 
	SET_BODYCON_BIT(pFMon->BodyCondition,  BODYCON_MON_BUILDING);
	this->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pFMon, T_FN_MONSTER_CHANGE_BODYCONDITION);
	this->m_pCurrentFieldMapChannel->FieldSendMonsterChangeInfo(pFMon, T_FC_MONSTER_CHANGE_BODYCONDITION);
	m_pCurrentFieldMapChannel->m_ChangeBodyConMonsterIndex	=	pFMon->MonsterIndex;
	

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_EVENT_NOTIFY_MSG_GET(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-02-18 by cmkwon, 클라이언트 게임시작 준비가 완료 된 후 처음 보내는 프로토콜임
///				// 2008-02-18 by cmkwon, 향후 클라이언트가 준비 완료 되 후 처리해야하는 작업은 이곳에 추가한다
/// \author		cmkwon
/// \date		2007-11-28 ~ 2007-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_NOTIFY_MSG_GET(const char* pPacket, int nLength, int &nBytesUsed)
{
	// 2007-11-28 by cmkwon, No Body

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

	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_GetNotifyMsg, this, m_character.AccountUniqueNumber, NULL, NULL, m_character.CharacterUniqueNumber);

	///////////////////////////////////////////////////////////////////////////////	
	// 2008-02-18 by cmkwon, 게임 시작 동기화 수정 - CFieldIOCPSocket::CharacterGameStartRoutine() 함수에 있던것으로 이곳으로 옮김
 	ms_pFieldIOCP->SendInRangeCharacterOtherInfo(this, m_pCurrentFieldMapChannel);

  	// 2008-02-18 by cmkwon, 게임 시작 동기화 수정 - CFieldIOCPSocket::CharacterGameStartRoutine() 함수에 있던것으로 이곳으로 옮김, 주위에 있는 아이템의 정보를 얻어온다.
 	SendDropItemsAroundPosition(m_character.PositionVector);

	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_EVENT_NOTIFY_MSG_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		
/// \author		cmkwon
/// \date		2007-11-28 ~ 2007-11-28
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_NOTIFY_MSG_DELETE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_NOTIFY_MSG_DELETE,
									MSG_FC_EVENT_NOTIFY_MSG_DELETE, pRecvMsg);

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

	if(FALSE == IS_VALID_UID64(pRecvMsg->NotifyMsgUID))
	{
		SendErrorMessage(T_FC_EVENT_NOTIFY_MSG_DELETE, ERR_DB_INVALID_PARAMETER, 102);
		return RES_BREAK;
	}


	SNOTIFY_MSG notifyMsg;		MEMSET_ZERO(&notifyMsg, sizeof(notifyMsg));
	if(FALSE == this->CheckDeleteNotifyMsg(&notifyMsg, pRecvMsg->NotifyMsgUID))
	{
		SendErrorMessage(T_FC_EVENT_NOTIFY_MSG_DELETE, ERR_DB_INVALID_PARAMETER, 103);
		return RES_BREAK;
	}
	
	if(0 == notifyMsg.CharacterUID)
	{// 2007-11-28 by cmkwon, 0 인것은 모든 유저에게 전송되는 통지메시지로 관리자/운영자만 삭제가 가능하다.

		if(FALSE == COMPARE_RACE(m_character.Race, RACE_OPERATION|RACE_GAMEMASTER))
		{
			SendErrorMessage(T_FC_EVENT_NOTIFY_MSG_DELETE, ERR_DB_INVALID_PARAMETER, 104);
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-28 by cmkwon, 게임 로그를 남긴다.
	CAtumLogSender::SendLogMessageNotifyMsgDelete(&notifyMsg);

	///////////////////////////////////////////////////////////////////////////////
	// 2007-11-28 by cmkwon, DB 의 데이터를 삭제한다.
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DeleteNotifyMsg, this, m_character.AccountUniqueNumber, NULL, NULL, pRecvMsg->NotifyMsgUID);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
/// \fn			ProcessResult CFieldIOCPSocket::Process_FC_EVENT_COUPON_EVENT_USE_COUPON(const char* pPacket, int nLength, int &nBytesUsed)
/// \brief		// 2008-01-10 by cmkwon, 아이템 이벤트 시스템에 신 쿠폰 시스템 추가 - CFieldIOCPSocket::Process_FC_EVENT_COUPON_EVENT_USE_COUPON() 추가
/// \author		cmkwon
/// \date		2008-01-10 ~ 2008-01-10
/// \warning	
///
/// \param		
/// \return		
///////////////////////////////////////////////////////////////////////////////
ProcessResult CFieldIOCPSocket::Process_FC_EVENT_COUPON_EVENT_USE_COUPON(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE(pPacket, nLength, nBytesUsed, T_FC_EVENT_COUPON_EVENT_USE_COUPON,
									MSG_FC_EVENT_COUPON_EVENT_USE_COUPON, pRecvMsg);

	if(0 == strcmp("", pRecvMsg->CouponNumber))
	{
		SendErrorMessage(T_FC_EVENT_COUPON_EVENT_USE_COUPON, ERR_DB_INVALID_PARAMETER, 100);
		return RES_BREAK;
	}

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

	if(FALSE == this->FindCouponEvent(pRecvMsg->ItemEventUID))
	{// 2008-01-10 by cmkwon, 유효한 ItemEventUID 체크
		SendErrorMessage(T_FC_EVENT_COUPON_EVENT_USE_COUPON, ERR_INVALID_ITEMEVENT_UID, 120);
		return RES_BREAK;
	}

	QPARAM_CheckCouponEvent *pQParam = new QPARAM_CheckCouponEvent;
	MEMSET_ZERO(pQParam, sizeof(QPARAM_CheckCouponEvent));
	pQParam->ItemEventUID			= pRecvMsg->ItemEventUID;
	STRNCPY_MEMSET(pQParam->AccName, m_character.AccountName, SIZE_MAX_ACCOUNT_NAME);
	STRNCPY_MEMSET(pQParam->CouponNumber, pRecvMsg->CouponNumber, SIZE_MAX_COUPON_NUMBER);
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_CheckCouponEvent, this, m_character.AccountUniqueNumber, pQParam);
	return RES_RETURN_TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// 2010-03-08 by cmkwon, FieldIOCPSocket.cpp파일 2개로 나누기 - CFieldIOCPSocket::Process_FC_SHOP_GET_ITEMINFO#부터 다음 파일로 옮김.
// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼
ProcessResult CFieldIOCPSocket::Process_FI_GUILD_BOUNUEXP_RATE(const char* pPacket, int nLength, int &nBytesUsed)
{
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FI_GUILD_BONUS_EXP_RATE,
		MSG_FI_GUILD_BONUS_EXP_RATE, pRMsg);
	
	m_nGuildBonusExpRate = pRMsg->nBonusExpRate;
	
	//클라이언트로 변수 전송
	SendToClient_BonusExpRate();
	
	return RES_RETURN_TRUE;
}
// 2012-10-12 by jhjang 해피 아워 경험치 보너스 시스템 리뉴얼

///////////////////////////////////////////////////////////////////////////////
// 2013-11-25 by jhseol&bckim, 거래소 - 패킷 리시브 함수 구현
ProcessResult CFieldIOCPSocket::Process_FC_MARKET_BASE_INFO_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	m_nMarketRegistrationCount = 0;
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	// 임시 
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_BASE_INFO_HEAD, T_FC_MARKET_BASE_INFO_HEADER, pSendHeadMsg, pSendHeadBuf);
		pSendHeadMsg->nSellingTime = MARKET_SELLING_MINUTES;
		SendAddData(pSendHeadBuf, MSG_SIZE(MSG_FC_MARKET_BASE_INFO_HEAD));
	}

	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_BUY_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_BuyPage )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_BuyPage = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 원본 복사후 복사여부 확인
	m_CopyMarketListPtr.clear();
	ms_pFieldIOCP->m_pMarketDataManager->CopyMarketList(&m_CopyMarketListPtr);
	if ( TRUE == m_CopyMarketListPtr.empty() )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_DB_NO_SUCH_DATA, 100);
		
		
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 상태값이 유요한 것들만 추출
	ATUM_DATE_TIME tmCurrentTime(TRUE);
	MARKET_LIST tmMarketList;
	tmMarketList.reserve(m_CopyMarketListPtr.size());
	tmMarketList.clear();
	tmMarketList.assign(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end());
	m_CopyMarketListPtr.clear();
	// 추출 후 시간별 내림차순 정렬을 피하기 위해 뒤에서부터 검색
	// m_nMarketRegistrationCount = 0;
	MARKET_ITR itr = tmMarketList.end();
	while (itr != tmMarketList.begin())
	{
		itr--;
		if ( MARKET_STATE_SELL == (*itr)->MarketState 
			&& MARKET_SELLING_MINUTES > tmCurrentTime.GetTimeDiffTimeInMinutes((*itr)->RegistTime)
#ifdef SC_MARKET_NOT_USE_NORMAL_INFL
			&& (*itr)->MarketItemInfl == m_character.InfluenceType		// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )	// 동일세력 
#endif
			)
		{
			m_CopyMarketListPtr.push_back((*itr));
		}
		if ( (*itr)->CharacterUID == m_character.CharacterUniqueNumber && MARKET_STATE_DELETE != (*itr)->MarketState )
		{
			m_nMarketRegistrationCount++;
		}
	}
	/* ==>> 앞에서 부터 검색하게 되면 시간별 내림차순 정렬까지 해야함으로 리스크가 크다 그러므로 주석처리
	for ( ; itr != tmMarketList.end() ; itr++ )
	{
		if ( MARKET_STATE_SELL == (*itr)->MarketState && MARKET_SELLING_HOURS > tmCurrentTime.GetTimeDiffTimeInHours((*itr)->RegistTime) )
		{
			MARKET_INFO tmMarketInfo((*itr));
			m_CopyMarketListPtr.push_back((*itr));
		}
	}
	///////////////////////////////////////////////
	// 등록시간 별루 정렬
	// 위에서 역순으로 추출하면 정렬할 필요가 없다
	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_TIME_DOWN());
	m_nLatelyMarketListSortingType = MARKET_SORT_TIME_DOWN;
	<<== 여기까지 */

	///////////////////////////////////////////////
	// 추출결과 리스트 확인
	int nCopyMarketListSize = m_CopyMarketListPtr.size();
	if ( 0 >= nCopyMarketListSize )
	{
		SendErrorMessage(T_FC_MARKET_BASE_INFO_REQUEST, ERR_DB_NO_SUCH_DATA, 101);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 검색결과 보내기
	
	//SendAddMessageType(T_FC_MARKET_BASE_INFO_HEADER);
	//
	
//	typedef struct 
//	{
//		INT nSellingTime;
//	} MSG_FC_MARKET_BASE_INFO_HEAD;
	
// 	INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_BASE_INFO_HEAD, T_FC_MARKET_BASE_INFO_HEADER, pSendHeadMsg, pSendHeadBuf);
// 	pSendHeadMsg->nSellingTime = MARKET_SELLING_MINUTES;
// 	SendAddData(pSendHeadBuf, MSG_SIZE(MSG_FC_MARKET_BASE_INFO_HEAD));
	//


	// 헤더는 위에서 보냅니다.. 
	// 경매시간값을 
	itr = m_CopyMarketListPtr.begin();
	for ( int i = 0 ; i < MARKET_VIEW_LIST_COUNT ; i++, itr++ )
	{
		if ( itr == m_CopyMarketListPtr.end() )	// 항목이 8게 미만일때 해당
		{
			break;
		}
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_BASE_INFO_OK, T_FC_MARKET_BASE_INFO_OK, pSendOKMsg, pSendOKBuf);
		MARKET_INFO tmMarket(*itr);
		memcpy(&pSendOKMsg->MarketInfo, &tmMarket, sizeof(pSendOKMsg->MarketInfo));
		SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_MARKET_BASE_INFO_OK));
	}
	INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_BASE_INFO_DONE, T_FC_MARKET_BASE_INFO_DONE, pSendDoneMsg, pSendDoneBuf);
	pSendDoneMsg->ItemCount = nCopyMarketListSize;
	pSendDoneMsg->MaxPage = (nCopyMarketListSize / MARKET_VIEW_LIST_COUNT) + (0 == (nCopyMarketListSize % MARKET_VIEW_LIST_COUNT) ? 0 : 1);
	pSendDoneMsg->CurrentPage = 1;
	SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_BASE_INFO_DONE));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_SEARCH_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_SEARCH_REQUEST,
		MSG_FC_MARKET_SEARCH_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_BUY_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_BuyPage )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_BuyPage = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 원본 복사후 복사여부 확인
	m_CopyMarketListPtr.clear();
	ms_pFieldIOCP->m_pMarketDataManager->CopyMarketList(&m_CopyMarketListPtr);
	if ( TRUE == m_CopyMarketListPtr.empty() )
	{
		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_DB_NO_SUCH_DATA, 100);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 일괄 검색 push_back의 리스크를 줄이기 위해 한방에 모든조건을 검색!!
	ATUM_DATE_TIME tmCurrentTime(TRUE);
	MARKET_LIST tmMarketList;
	tmMarketList.reserve(m_CopyMarketListPtr.size());
	tmMarketList.clear();
	tmMarketList.assign(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end());
	m_CopyMarketListPtr.clear();
	MARKET_ITR itr = tmMarketList.begin();
	for ( ; itr != tmMarketList.end() ; itr++ )
	{
#ifdef SC_MARKET_NOT_USE_NORMAL_INFL
		if ( (*itr)->MarketItemInfl == m_character.InfluenceType )		// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )	// 동일세력 					 
#endif
		{
			
		if ( pRMsg->MoneyType == (*itr)->MoneyType
			&& MARKET_STATE_SELL == (*itr)->MarketState
			&& MARKET_SELLING_MINUTES > tmCurrentTime.GetTimeDiffTimeInMinutes((*itr)->RegistTime)	
			&& ( 0 == pRMsg->Kind		|| IsMarketItemKindSame(pRMsg->Kind, (*itr)->ItemKind) )
			&& ( 0 == pRMsg->ItemGear	|| IS_SAME_UNITKIND(pRMsg->ItemGear, (*itr)->ItemGear) )
			&& ( 0 == pRMsg->LevelMin	|| pRMsg->LevelMin <= (*itr)->ItemLevel )
			&& ( 0 == pRMsg->LevelMax	|| pRMsg->LevelMax >= (*itr)->ItemLevel )
			&& ( 0 == pRMsg->EnchantMin	|| pRMsg->EnchantMin <= (*itr)->EnchantCount )
			&& ( 0 == pRMsg->EnchantMax	|| pRMsg->EnchantMax >= (*itr)->EnchantCount )
			)
		{
			if ( 0 < strlen(pRMsg->Name) )	// 검색어가 있을경우
			{
				char *token;
				char seps[] = " ";
				char buffer[MARKET_ITEM_FULL_NAME];
				
				STRNCPY_MEMSET(buffer, pRMsg->Name, MARKET_ITEM_FULL_NAME);
				token = strtok(buffer, seps);
				if( NULL != token )
				{
					BYTE nFindNameIndex = 0;
					nFindNameIndex = SearchWord((*itr)->ItemName, token, nFindNameIndex);	// 1. 아이템 이블에서 검색해야 할 첫번째 단어를 찾는다
					while ( 0 < nFindNameIndex )			// 2. 단어가 포함되지 않으면 nFindNameIndex 가 0값을 가짐으로 반복문이 수행되지 안는다.
					{
						token = strtok(NULL, seps);			// 3. 그렇지 않고 단어가 포함되어 있으면 입력한 검색어 중 더 찾아야 봐야하는 다음 단어가 있는지 확인하고
						if ( NULL == token )				// 4. 더이상 찾을 단어가 없다면 검색해야할 모든 단어가 포함된 아이템 이므로 push_back
						{
							m_CopyMarketListPtr.push_back((*itr));	
							nFindNameIndex = 0;				// 5. 반복문 탈출조건인 nFindNameIndex 에 0값을 셋팅
						}
						else								// 6. 또 찾아야 하는 단어가 있다면
						{
							nFindNameIndex = SearchWord((*itr)->ItemName, token, nFindNameIndex);	// 7. 단어를 찾고 2번부터 반복
						}
					}
				}
			}
			else	// 검색어가 없을 경우 바로 push_back
			{
				m_CopyMarketListPtr.push_back((*itr));
			}
		}
		}	// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )	// 동일세력 					 
	}

	///////////////////////////////////////////////
	// 검색결과 리스트 확인
	int nCopyMarketListSize = m_CopyMarketListPtr.size();
// 	if ( 0 >= nCopyMarketListSize )	// 클라 요청으로 검색결과가 없어도 HEADER와 DONE을 보내기 위해 주석처리
// 	{
// 		SendErrorMessage(T_FC_MARKET_SEARCH_REQUEST, ERR_DB_NO_SUCH_DATA, 101);
// 		return RES_BREAK;
// 	}

	///////////////////////////////////////////////
	// 검색결과 가격 별루 정렬
	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_PRICE_UP());
	m_nLatelyMarketListSortingType = MARKET_SORT_PRICE_UP;

	///////////////////////////////////////////////
	// 검색결과 보내기
	SendAddMessageType(T_FC_MARKET_SEARCH_HEADER);
	itr = m_CopyMarketListPtr.begin();
	for ( int i = 0 ; i < MARKET_VIEW_LIST_COUNT ; i++, itr++ )
	{
		if ( itr == m_CopyMarketListPtr.end() )	// 항목이 8게 미만일때 해당
		{
			break;
		}
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_SEARCH_OK, T_FC_MARKET_SEARCH_OK, pSendOKMsg, pSendOKBuf);
		MARKET_INFO tmMarket(*itr);
		memcpy(&pSendOKMsg->MarketInfo, &tmMarket, sizeof(pSendOKMsg->MarketInfo));
		SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_MARKET_SEARCH_OK));
	}
	INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_SEARCH_DONE, T_FC_MARKET_SEARCH_DONE, pSendDoneMsg, pSendDoneBuf);
	pSendDoneMsg->ItemCount = nCopyMarketListSize;
	pSendDoneMsg->MaxPage = (nCopyMarketListSize / MARKET_VIEW_LIST_COUNT) + (0 == (nCopyMarketListSize % MARKET_VIEW_LIST_COUNT) ? 0 : 1);
	pSendDoneMsg->CurrentPage = 1;
	SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_SEARCH_DONE));
		return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_PAGING_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_PAGING_REQUEST,
		MSG_FC_MARKET_PAGING_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( 0 == pRMsg->MarketUID )	// 0값이면 순수 페이지 변경 요청. 반대로 0 값이 아니면 구매완료 후 페이지 갱신 요청이므로 텀체크를 하지 않는다.
	{
		if ( (MARKET_PACKET_RECV_TICK_BUY_PAGE/2) > GetTickCount() - m_nLatelyMarketPacketRecvTick_BuyPage )
		{
			SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
			return RES_BREAK;
		}
	}
	m_nLatelyMarketPacketRecvTick_BuyPage = GetTickCount();
	
	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 제외시킬 항목이 있는지 확인
	if ( 0 != pRMsg->MarketUID )
	{
		MARKET_ITR delitr = m_CopyMarketListPtr.begin();
		for( ; delitr != m_CopyMarketListPtr.end() ; delitr++ )
		{
			if ( pRMsg->MarketUID == (*delitr)->MarketUID )
			{
				m_CopyMarketListPtr.erase(delitr);
				break;
			}
		}
	}
	
	///////////////////////////////////////////////
	// 카피한 리스트 확인
	int nCopyMarketListSize = m_CopyMarketListPtr.size();
	if ( 0 >= nCopyMarketListSize )
	{
		SendAddMessageType(T_FC_MARKET_PAGING_HEADER);
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_PAGING_DONE, T_FC_MARKET_PAGING_DONE, pSendDoneMsg, pSendDoneBuf);
		SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_PAGING_DONE));
		return RES_RETURN_TRUE;
	}

	///////////////////////////////////////////////
	// 페이지에 있는 마지막 아이템을 구매했을경우 사라지는 페이지에 대한 예외처리 추가
	int nMaxPage = (nCopyMarketListSize / MARKET_VIEW_LIST_COUNT) + (0 == (nCopyMarketListSize % MARKET_VIEW_LIST_COUNT) ? 0 : 1);
	if ( nMaxPage < pRMsg->SelectPage )
	{
		pRMsg->SelectPage--;
	}
	if ( 0 >= pRMsg->SelectPage )
	{
		SendAddMessageType(T_FC_MARKET_PAGING_HEADER);
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_PAGING_DONE, T_FC_MARKET_PAGING_DONE, pSendDoneMsg, pSendDoneBuf);
		SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_PAGING_DONE));
		return RES_RETURN_TRUE;
	}

	///////////////////////////////////////////////
	// 올바른 페이지 번호인지 확인
	if ( FALSE == IS_IN_RANGE(1, pRMsg->SelectPage, nMaxPage) ) 
	{
		SendErrorMessage(T_FC_MARKET_PAGING_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 패이징 검색 결과 보내기
	int nIndex = 0;
	nIndex = MARKET_VIEW_LIST_COUNT*(pRMsg->SelectPage-1);
	SendAddMessageType(T_FC_MARKET_PAGING_HEADER);
	for ( int i = 0 ; i < MARKET_VIEW_LIST_COUNT ; i++ )
	{
		if ( nIndex+i >= nCopyMarketListSize )	// 마지막 패이지 일때만 해당
		{
			break;
		}
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_PAGING_OK, T_FC_MARKET_PAGING_OK, pSendOKMsg, pSendOKBuf);
		MARKET_INFO tmMarket(*m_CopyMarketListPtr[nIndex+i]);
		memcpy(&pSendOKMsg->MarketInfo, &tmMarket, sizeof(pSendOKMsg->MarketInfo));
		SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_MARKET_PAGING_OK));
	}
	INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_PAGING_DONE, T_FC_MARKET_PAGING_DONE, pSendDoneMsg, pSendDoneBuf);
	pSendDoneMsg->ItemCount = nCopyMarketListSize;
	pSendDoneMsg->MaxPage = nMaxPage;
	pSendDoneMsg->CurrentPage = pRMsg->SelectPage;
	SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_PAGING_DONE));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_SORT_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_SORT_REQUEST,
		MSG_FC_MARKET_SORT_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_BUY_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_BuyPage )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_BuyPage = GetTickCount();
	
	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 카피한 리스트 확인
	int nCopyMarketListSize = m_CopyMarketListPtr.size();
	if ( 0 >= nCopyMarketListSize )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_DB_NO_SUCH_DATA, 101);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 중복 정렬 요청여부 확인
	if ( pRMsg->SortingType == m_nLatelyMarketListSortingType )
	{
		SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, 100);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 정렬
	switch (pRMsg->SortingType)
	{
	case MARKET_SORT_PRICE_UP:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_PRICE_UP());		break;
	case MARKET_SORT_PRICE_DOWN:	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_PRICE_DOWN());	break;
	case MARKET_SORT_LEVEL_UP:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_LEVEL_UP());		break;
	case MARKET_SORT_LEVEL_DOWN:	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_LEVEL_DOWN());	break;
	case MARKET_SORT_ENCHANT_UP:	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_ENCHANT_UP());	break;
	case MARKET_SORT_ENCHANT_DOWN:	sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_ENCHANT_DOWN());	break;
	case MARKET_SORT_NAME_UP:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_NAME_UP());		break;
	case MARKET_SORT_NAME_DOWN:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_NAME_DOWN());		break;
	case MARKET_SORT_TIME_UP:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_TIME_UP());		break;
	case MARKET_SORT_TIME_DOWN:		sort(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_SORT_TIME_DOWN());		break;
	default:						SendErrorMessage(T_FC_MARKET_SORT_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, 101);	return RES_BREAK;
	}
	m_nLatelyMarketListSortingType = pRMsg->SortingType;
	
	///////////////////////////////////////////////
	// 정렬결과 보내기
	SendAddMessageType(T_FC_MARKET_SORT_HEADER);
	MARKET_ITR itr = m_CopyMarketListPtr.begin();
	for ( int i = 0 ; i < MARKET_VIEW_LIST_COUNT ; i++, itr++ )
	{
		if ( itr == m_CopyMarketListPtr.end() )	// 항목이 8게 미만일때 해당
		{
			break;
		}
		INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_SORT_OK, T_FC_MARKET_SORT_OK, pSendOKMsg, pSendOKBuf);
		MARKET_INFO tmMarket(*itr);
		memcpy(&pSendOKMsg->MarketInfo, &tmMarket, sizeof(pSendOKMsg->MarketInfo));
		SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_MARKET_SORT_OK));
	}
	INIT_MSG_WITH_BUFFER(MSG_FC_MARKET_SORT_DONE, T_FC_MARKET_SORT_DONE, pSendDoneMsg, pSendDoneBuf);
	pSendDoneMsg->ItemCount = nCopyMarketListSize;
	pSendDoneMsg->MaxPage = (nCopyMarketListSize / MARKET_VIEW_LIST_COUNT) + (0 == (nCopyMarketListSize % MARKET_VIEW_LIST_COUNT) ? 0 : 1);
	pSendDoneMsg->CurrentPage = 1;
	SendAddData(pSendDoneBuf, MSG_SIZE(MSG_FC_MARKET_SORT_DONE));
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_BUY_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP,101);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_BUY_REQUEST,
		MSG_FC_MARKET_BUY_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND,102);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_BUY_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_BuyPage )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_INTERVAL_SYSTEM_SECOND,103);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_BuyPage = GetTickCount();

#ifdef SC_MARKET_NOT_USE_NORMAL_INFL			// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )
	if ( INFLUENCE_TYPE_NORMAL == IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType) )			// 일반세력 이용불가 
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_REQ_CHOOSE_INFLUENCE_TYPE,104);
		return RES_BREAK;
	}
#endif		// End. 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 카피한 리스트에 있는지 확인
	MARKET_ITR itr = find_if(m_CopyMarketListPtr.begin(), m_CopyMarketListPtr.end(), MARKET_LIST_MarketUID_Find_Object(pRMsg->MarketUID));
	if(itr >= m_CopyMarketListPtr.end())
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, 105);
		return RES_BREAK;
	}

#ifdef SC_MARKET_NOT_USE_NORMAL_INFL		// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )
	// 동일세력간 거래인지 확인  
	if( (*itr)->MarketItemInfl != m_character.InfluenceType )  
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_REQ_INFLUENCE_NOT_MATCHED,106);
		return RES_BREAK;
	}
#endif	// End. 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )

	///////////////////////////////////////////////
	// 구매가 가능한 상태인지 확인
	ATUM_DATE_TIME tmCurrentTime(TRUE);
	if ( MARKET_STATE_SELL != (*itr)->MarketState || MARKET_SELLING_MINUTES < tmCurrentTime.GetTimeDiffTimeInMinutes((*itr)->RegistTime) )
	{
		SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP_ITEM, 107);
		return RES_BREAK;
	}

	if ( MARKET_MONEY_TYPE_SPI == (*itr)->MoneyType )
	{
		ITEM_GENERAL *pItemSPI = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER, ITEM_IN_CHARACTER);
		if ( NULL == pItemSPI )
		{	// SPI 아이템이 없을 경우 추가
			m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
			SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM_INFO, MONEY_ITEM_NUMBER);
			return RES_BREAK;
		}

		///////////////////////////////////////////////
		// 보유 SPI로 구매 금액 비교
		if ( pItemSPI->CurrentCount < (*itr)->Price )
		{
			SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NOT_ENOUGH_MONEY, pItemSPI->CurrentCount, (*itr)->Price, "SPI");
			return RES_BREAK;
		}
	}
	else if ( MARKET_MONEY_TYPE_WP == (*itr)->MoneyType )
	{
		///////////////////////////////////////////////
		// 보유 WP로 구매 금액 비교
		if ( m_character.WarPoint < (*itr)->Price )
		{
			SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_NOT_ENOUGH_MONEY, m_character.WarPoint, (*itr)->Price, "WP");
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////
	// 카운터블 아이템일 경우 최대 보유가능 수 체크
	BOOL bIsCountableAndHaveItem = FALSE;
	ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum((*itr)->ItemNum, ITEM_IN_CHARACTER);
	if ( NULL != pItemG )
	{
		//if ( IS_GENERAL_ITEM(pItemG->Kind) )
		if ( IS_COUNTABLE_ITEM(pItemG->Kind) )			
		{
			bIsCountableAndHaveItem = TRUE;
			if ( MAX_ITEM_COUNTS < pItemG->CurrentCount + (*itr)->ItemCount )
			{
				SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
				return RES_BREAK;
			}
		}
	}
	else
	{
		///////////////////////////////////////////////
		// 인벤토리 공간확인
		if (m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
		{
			SendErrorMessage(T_FC_MARKET_BUY_REQUEST, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
	}

	MARKET_INFO *pQParam = new MARKET_INFO((*itr));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Market_Buying, this, m_character.AccountUniqueNumber, pQParam, NULL, (INT64)bIsCountableAndHaveItem);
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_SELL_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_SELL_REQUEST,
		MSG_FC_MARKET_SELL_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_SELL_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_SellPage )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_SellPage = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

#ifdef SC_MARKET_NOT_USE_NORMAL_INFL			// 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )
	if ( INFLUENCE_TYPE_NORMAL == IS_NORMAL_INFLUENCE_TYPE(m_character.InfluenceType) )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_REQ_CHOOSE_INFLUENCE_TYPE);
		return RES_BREAK;
	}
#endif		// End. 2014-06-17 by bckim, 세력 불균형 ( 거래소 동일세력간에만 거래가 이루어지게 수정 )

	///////////////////////////////////////////////
	// 등록 가능 갯수를 초과하는지 확인
	if ( TRUE == m_ItemManager.IsExistPremiumCard() )
	{
		if ( (MARKET_SELL_ITEM_COUNT*2) <= m_nMarketRegistrationCount )		// 맴버쉽 유저는 2배 20개
		{
			SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_OVER_COUNT, m_nMarketRegistrationCount, 1);
			return RES_BREAK;
		}
	}
	else
	{
		if ( MARKET_SELL_ITEM_COUNT <= m_nMarketRegistrationCount )			// 일반 유저는 10개
		{
			SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_OVER_COUNT, m_nMarketRegistrationCount, 0);
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////
	// 판매 하려는 아이템을 보유중인지 확인
	ITEM_GENERAL *pItemG = m_ItemManager.GetItemGeneralByUID(pRMsg->ItemUID, ITEM_IN_CHARACTER);
	if ( NULL == pItemG )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM, pRMsg->ItemUID);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 거래가 가능한 아이템인지 체크
	// 2013-12-03 by bckim, 임시 주석 
	/*
	if ( COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_NO_TRANSFER|ITEM_ATTR_KILL_MARK_ITEM|ITEM_ATTR_ACCOUNT_POSSESSION) 
		|| POS_INVALID_POSITION >= pItemG->ItemWindowIndex )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_ITEM_CANNOT_TRANSFER, pItemG->ItemNum, pItemG->ItemWindowIndex);
		return RES_BREAK;
	}
	*/
	// End. 2013-12-03 by bckim, 임시 주석 
	
	///////////////////////////////////////////////
	// 이미 사용한 아이템인지 체크
	if ( ITEMKIND_ACCESSORY_TIMELIMIT == pItemG->Kind && pItemG->UsingTimeStamp != ITEM_NOT_USING )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_ALREADY_USE_ITEM);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 장착중인 아이템인지 확인
	if ( WEAR_ATTACHED == pItemG->Wear )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_ATTACHED_ITEM, 101);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 판매 하려는 화폐 타입이 올바른지 확인
	if ( MARKET_MONEY_TYPE_SPI != pRMsg->MoneyType && MARKET_MONEY_TYPE_WP != pRMsg->MoneyType )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pRMsg->MoneyType, 0, "MoneyType");
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 판매금액 확인
	if ( FALSE == IS_IN_RANGE(1, pRMsg->Price, MAX_ITEM_COUNTS) )
	{
		SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pRMsg->Price, 0, "Price");
		return RES_BREAK;
	}

	BOOL bIsCountableItem = FALSE;
	if ( TRUE == IS_COUNTABLE_ITEM(pItemG->Kind))
	{
		bIsCountableItem = TRUE;
		///////////////////////////////////////////////
		// 카운터블 아이템일 경우 판매수량 확인
		if ( FALSE == IS_IN_RANGE(1, pRMsg->Count, pItemG->CurrentCount) )
		{
			SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pRMsg->Count, pItemG->CurrentCount, "CountableCount");
			return RES_BREAK;
		}
	}
// 	else
// 	{
// 		///////////////////////////////////////////////
// 		// 카운터블 아이템이 아닐 경우 판매수량 확인
// 		if ( 1 != pRMsg->Count )
// 		{
// 			SendErrorMessage(T_FC_MARKET_SELL_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pRMsg->Count, pItemG->CurrentCount, "Count");
// 			return RES_BREAK;
// 		}
// 	}

	///////////////////////////////////////////////
	// 등록 가능 갯수 증가
	m_nMarketRegistrationCount++;

	MSG_FC_MARKET_SELL_REQUEST *pQParam = new MSG_FC_MARKET_SELL_REQUEST;
	MEMSET_ZERO(pQParam, sizeof(MSG_FC_MARKET_SELL_REQUEST));
	memcpy(pQParam, pRMsg, sizeof(MSG_FC_MARKET_SELL_REQUEST));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Market_ItemRegistration, this, m_character.AccountUniqueNumber, pQParam, NULL, (INT64)GetMarketItemKindByOriginItemKind(*pItemG->ItemInfo), (INT64)bIsCountableItem);
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_GET_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_MARKET_GET_REQUEST,
		MSG_FC_MARKET_GET_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_GET_REQUEST > GetTickCount() - m_nLatelyMarketPacketRecvTick_GetRequeste )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_GetRequeste = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 원본 리스트를 통해 판매현황에 있는 항목인지 확인
	MARKET_INFO *pMyKarKetItem = ms_pFieldIOCP->m_pMarketDataManager->GetpMarketInfo(pRMsg->MarketUID);
	if ( NULL == pMyKarKetItem )
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM);
		return RES_BREAK;
	}
	if ( m_character.CharacterUniqueNumber != pMyKarKetItem->CharacterUID )	// 내 소유가 맞는지 확인
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, 100);
		return RES_BREAK;
	}
	if ( MARKET_STATE_DELETE == pMyKarKetItem->MarketState )	// 회수 가능한 상태인지 확인
	{
		SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, 101);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 돈을 회수할때 최대치 확인
	if ( MARKET_STATE_SELL_DONE == pMyKarKetItem->MarketState )
	{
		if ( MARKET_MONEY_TYPE_SPI == pMyKarKetItem->MoneyType )
		{
			ITEM_GENERAL *pItemSPI = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER, ITEM_IN_CHARACTER);
			if ( NULL != pItemSPI )
			{	// 2014-07-24 by bckim, 거래소 금액회수 동기화 문제 보완
				//if ( MAX_ITEM_COUNTS < (pItemSPI->CurrentCount+pMyKarKetItem->Price-GetMarketSellChargeSPI(pMyKarKetItem->Price)) )
				if ( MAX_ITEM_COUNTS < (INT64)(pItemSPI->CurrentCount)+(INT64)(pMyKarKetItem->Price)-(INT64)(GetMarketSellChargeSPI(pMyKarKetItem->Price)) )
				{
					// 2014-07-24 by bckim, 거래소 금액회수 동기화 문제 보완
					//SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, pItemSPI->CurrentCount, pMyKarKetItem->Price, "SPI");
					SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER, pItemSPI->CurrentCount, pMyKarKetItem->Price, "SPI");
					return RES_BREAK;
				}
			}
		}
		else if ( MARKET_MONEY_TYPE_WP == pMyKarKetItem->MoneyType )
		{	// 2014-07-24 by bckim, 거래소 금액회수 동기화 문제 보완
			//if ( MAX_ITEM_COUNTS < (m_character.WarPoint+pMyKarKetItem->Price-GetMarketSellChargeWP(pMyKarKetItem->Price)) )
			if ( MAX_ITEM_COUNTS < (INT64)(m_character.WarPoint)+(INT64)(pMyKarKetItem->Price)-(INT64)(GetMarketSellChargeWP(pMyKarKetItem->Price)) )
			{
				// 2014-07-24 by bckim, 거래소 금액회수 동기화 문제 보완
				//SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER, m_character.WarPoint, pMyKarKetItem->Price, "WP");
				SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_NOTIFY_MAX_ITEM_COUNTS_OVER, m_character.WarPoint, pMyKarKetItem->Price, "WP");
				return RES_BREAK;
			}
		}
	}

	///////////////////////////////////////////////
	// 카운터블 아이템일 경우 최대 보유가능 수 체크
	BOOL bIsCountableAndHaveItem = FALSE;
	ITEM_GENERAL *pItemG = m_ItemManager.GetFirstItemGeneralByItemNum(pMyKarKetItem->ItemNum, ITEM_IN_CHARACTER);
	if ( NULL != pItemG )
	{
		if ( IS_COUNTABLE_ITEM(pItemG->Kind) )		// 2014-05-09 by bckim, 거래소 아이템 복사버그 수정  
		{
			bIsCountableAndHaveItem = TRUE;
			if ( MAX_ITEM_COUNTS < pItemG->CurrentCount + pMyKarKetItem->ItemCount )
			{
				SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_MAX_ITEM_COUNTS_OVER);
				return RES_BREAK;
			}
		}
	}
	else
	{
		///////////////////////////////////////////////
		// 인벤토리 공간확인
		if ( MARKET_STATE_SELL_DONE != pMyKarKetItem->MarketState )			// 판매된 물품의 금액회수일떄는 인벤토리 체크 안함. 
		{
		if (m_ItemManager.GetInventoryItemCounts() >= m_ItemManager.GetMaxInventoryCount())
		{
			SendErrorMessage(T_FC_MARKET_GET_REQUEST, ERR_PROTOCOL_INVENTORY_FULL_ITEM, 0, m_ItemManager.GetMaxInventoryCount());
			return RES_BREAK;
		}
		}
		
	}
	
	///////////////////////////////////////////////
	// 등록 가능 갯수 감소
	m_nMarketRegistrationCount = max(0, m_nMarketRegistrationCount-1);

	MSG_FC_MARKET_GET_REQUEST *pQParam = new MSG_FC_MARKET_GET_REQUEST;
	MEMSET_ZERO(pQParam, sizeof(MSG_FC_MARKET_GET_REQUEST));
	memcpy(pQParam, pRMsg, sizeof(MSG_FC_MARKET_GET_REQUEST));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Market_GetTradeItem, this, m_character.AccountUniqueNumber, pQParam, NULL, (INT64)bIsCountableAndHaveItem);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_MARKET_MY_LIST_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pMarketDataManager )
	{
		SendErrorMessage(T_FC_MARKET_MY_LIST_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_MARKET_MY_LIST_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 거래소 관련 2초 텀
	if ( MARKET_PACKET_RECV_TICK_MY_LIST_PAGE > GetTickCount() - m_nLatelyMarketPacketRecvTick_MyListPage )
	{
		SendErrorMessage(T_FC_MARKET_MY_LIST_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_MyListPage = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_MARKET_MY_LIST_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_MARKET_MY_LIST_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_Market_GetSaleList, this, m_character.AccountUniqueNumber, NULL);
	
	return RES_RETURN_TRUE;
}
// end 2013-11-25 by jhseol&bckim, 거래소 - 패킷 리시브 함수 구현

// 2014-01-03 by jhseol&bckim, 파괴경매장 - 패킷 리시브 함수선언
ProcessResult CFieldIOCPSocket::Process_FC_DESTROY_AUCTION_BASE_INFO_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pDestroyAuctionManager)
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 파괴경매장 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_DESTROY_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 파괴경매가 진행중인지 체크
	if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionInProgress || TRUE == ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr()->empty() )	
	{	// 2014-07-07 by bckim, 파괴경매가 시작되어도 등록된 물품이 없으면 시작 메세지를 보내지 않음. 		
		// 현재 경매진행중이 아니거나 등록된 물품이 없을때,
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_COUNTDOWN_NOT_ENOUGH_TIME);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 파괴경매장 관련 0.2초 텀
	if ( DESTROY_AUCTION_PACKET_RECV_TICK > GetTickCount() - m_nLatelyMarketPacketRecvTick_GetRequeste )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_GetRequeste = GetTickCount();

	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_BASE_INFO_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 경매물품 보내기
//	SendAddMessageType(T_FC_DESTROY_AUCTION_BASE_INFO_HEADER);
	INIT_MSG_WITH_BUFFER(MSG_FC_DESTROY_AUCTION_BASE_INFO_HEADER, T_FC_DESTROY_AUCTION_BASE_INFO_HEADER, pSendHeaderMsg, pSendHeaderBuf);
	pSendHeaderMsg->DAuctionEndTime = ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionEndTime();
	SendAddData(pSendHeaderBuf, MSG_SIZE(MSG_FC_DESTROY_AUCTION_BASE_INFO_HEADER));

	DESTROY_AUCTION_ITR itr = ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr()->begin();
	while( itr != ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr()->end() )
	{
		INIT_MSG_WITH_BUFFER(MSG_FC_DESTROY_AUCTION_BASE_INFO_OK, T_FC_DESTROY_AUCTION_BASE_INFO_OK, pSendOKMsg, pSendOKBuf);
		DESTROY_AUCTION_INFO tmDAuctionInfo(*itr);
		memcpy(&pSendOKMsg->DAuctionInfo, &tmDAuctionInfo, sizeof(pSendOKMsg->DAuctionInfo));
		SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_DESTROY_AUCTION_BASE_INFO_OK));
		itr++;
	}

	SendAddMessageType(T_FC_DESTROY_AUCTION_BASE_INFO_DONE);
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_DESTROY_AUCTION_TENDER_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pDestroyAuctionManager)
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_DESTROY_AUCTION_TENDER_REQUEST,
		MSG_FC_DESTROY_AUCTION_TENDER_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 파괴경매장 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_DESTROY_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 파괴경매가 진행중인지 체크
	if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionInProgress || TRUE == ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr()->empty() )	
	{	// 2014-07-07 by bckim, 파괴경매가 시작되어도 등록된 물품이 없으면 시작 메세지를 보내지 않음. 		
		// 현재 경매진행중이 아니거나 등록된 물품이 없을때,
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_COUNTDOWN_NOT_ENOUGH_TIME);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 파괴경매장 관련 0.2초 텀
	if ( DESTROY_AUCTION_PACKET_RECV_TICK > GetTickCount() - m_nLatelyMarketPacketRecvTick_GetRequeste )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_GetRequeste = GetTickCount();
	
	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 입찰가능한 금액을 소유중인지 확인
	ITEM_GENERAL *pItemSPI = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER, ITEM_IN_CHARACTER);
	if ( NULL == pItemSPI )
	{	// SPI 아이템이 없을 경우 추가
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM_INFO, MONEY_ITEM_NUMBER);
		return RES_BREAK;
	}
	if ( pItemSPI->CurrentCount < pRMsg->TenderPrice )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_NOT_ENOUGH_MONEY, pItemSPI->CurrentCount, pRMsg->TenderPrice, "SPI");
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 입찰조건 확인 1. 입찰권
	// 2014-07-04 by bckim, 무료지급 입찰권 속성 변경 
	//ITEM_GENERAL *pItemTenderItem = m_ItemManager.GetFirstItemGeneralByItemNum(DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED, ITEM_IN_CHARACTER);
	ITEM_GENERAL *pItemTenderItem = m_ItemManager.GetItemGeneralByItemNumFirstCreateTimeInCharacter(DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED, ITEM_IN_CHARACTER);
	// End. 2014-07-04 by bckim, 무료지급 입찰권 속성 변경 

	if ( NULL == pItemTenderItem )
	{	// 우선 기간제 입찰권이 있는지 확인 없으면 무제한 입찰권 확인
		pItemTenderItem = m_ItemManager.GetFirstItemGeneralByItemNum(DESTROY_AUCTION_TENDET_ITEM_NUM_UNLIMITED, ITEM_IN_CHARACTER);
		if ( NULL == pItemTenderItem )
		{
			//SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM, DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED, DESTROY_AUCTION_TENDET_ITEM_NUM_UNLIMITED, "BiddingRights");
			SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_CANNOT_BUY_ITEM,DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED, DESTROY_AUCTION_TENDET_ITEM_NUM_UNLIMITED, "BiddingRights");
// #if defined(TEST140)
// 			SendString128(STRING_128_USER_POPUP, "임시 경매입찰권 [%d]또는 [%d]이 필요합니다.", DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED, DESTROY_AUCTION_TENDET_ITEM_NUM_UNLIMITED);
// #endif
			return RES_BREAK;
		}
	}

	///////////////////////////////////////////////
	// 입찰조건 확인 2. 경매물품 상태
	mt_auto_lock mtA(ms_pFieldIOCP->m_pDestroyAuctionManager->GetDestroyAuctionListPtr());
	DESTROY_AUCTION_INFO *pDAuctionInfo = ms_pFieldIOCP->m_pDestroyAuctionManager->GetpDestroyAuctionInfo(pRMsg->DAuctionUID);
	if ( NULL == pDAuctionInfo )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_DB_NO_SUCH_DATA, pRMsg->DAuctionUID);
		return RES_BREAK;
	}
	if ( pDAuctionInfo->CharacterUID == m_character.CharacterUniqueNumber )	// 현재 자신이 최고 입찰자 이다. 초과입찰 금지
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_NO_SUCH_REQUEST_TYPE, pDAuctionInfo->CharacterUID, m_character.CharacterUniqueNumber, "CUID");
		return RES_BREAK;
	}
	if ( pDAuctionInfo->Price >= pRMsg->TenderPrice )						// 상회 입찰자가 있다.
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_TENDER_REQUEST, ERR_PROTOCOL_TRADE_ERROR, pDAuctionInfo->Price, pRMsg->TenderPrice, "Price");
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 입찰 정보 변경
	ms_pFieldIOCP->m_pDestroyAuctionManager->UpdateDestroyAuctionTenderInfo(pRMsg);

	///////////////////////////////////////////////
	// 입찰 로그 남기기
	INIT_MSG_WITH_BUFFER(MSG_FL_LOG_DESTROY_AUCTION_TENDER, T_FL_LOG_DESTROY_AUCTION_TENDER, pLogMsg, SendLogBuf);
	memcpy(&pLogMsg->DAuctionInfo, pDAuctionInfo, sizeof(DESTROY_AUCTION_INFO));
	pLogMsg->DAuctionInfo.AccountUID = m_character.AccountUniqueNumber;
	pLogMsg->DAuctionInfo.CharacterUID = m_character.CharacterUniqueNumber;
	pLogMsg->DAuctionInfo.Price = pRMsg->TenderPrice;
	g_pFieldGlobal->SendLogFieldServer2LogServer(SendLogBuf, MSG_SIZE(MSG_FL_LOG_DESTROY_AUCTION_TENDER));
	mtA.auto_unlock_cancel();

	///////////////////////////////////////////////
	// 입찰권 차감
	// 2014-07-04 by bckim, 무료지급 입찰권 속성 변경 
	//m_ItemManager.UpdateItemCountByPointer(pItemTenderItem, -1, IUT_AUCTION);
	if ( DESTROY_AUCTION_TENDET_ITEM_NUM_LIMITED == pItemTenderItem->ItemNum )  // 카운터블 아이템이 아님. (일반 파괴아이템 )
	{
		m_ItemManager.DeleteItemFromCharacterByPointer(pItemTenderItem,IUT_USE_ITEM);
	}
	else // 카운터블 아이템 ( 프리미엄 아이템 )
	{
	m_ItemManager.UpdateItemCountByPointer(pItemTenderItem, -1, IUT_AUCTION);
	}
	// End. 2014-07-04 by bckim, 무료지급 입찰권 속성 변경 	

	///////////////////////////////////////////////
	// 입찰 정보 파괴경매장 이용중인 모든 유저에게 실시간 전송
	mt_auto_lock mtB(&ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList);

	// 임시 값 확인 
	int tmsize = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.size();
	g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 전송대상 사이즈  (%d)\r\n",tmsize);

	for(mtmapUID2FieldIOCPSocket::iterator itr = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.begin() ; itr != ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.end() ;)
	{
		UID32_t temp = itr->first;
		CFieldIOCPSocket *tmp = itr->second;

		if ( NULL != itr->second && TRUE == itr->second->IsValidCharacter(FALSE))
		{
			INIT_MSG_WITH_BUFFER(MSG_FC_DESTROY_AUCTION_TENDER_OK, T_FC_DESTROY_AUCTION_TENDER_OK, pSendOKMsg, pSendOKBuf);
			memcpy(pSendOKMsg, pRMsg, sizeof(MSG_FC_DESTROY_AUCTION_TENDER_OK));
			itr->second->SendAddData(pSendOKBuf, MSG_SIZE(MSG_FC_DESTROY_AUCTION_TENDER_OK));
			// 임시 값 확인 
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 리스트 (%s)\r\n",itr->second->m_character.CharacterName);
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 리스트 (%d)\r\n",itr->first);
		}

		if(FALSE == itr->second->IsValidCharacter(FALSE))
		{
			// 임시 값 확인 
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 IsValidCharacter (%s)\r\n",itr->second->m_character.CharacterName);
			itr = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.erase(itr);
			// 임시 값 확인 
			int tmsize2 = ms_pFieldIOCP->m_mapEnterDestroyAuctionBuildingUserSocketList.size();
			g_pFieldGlobal->WriteSystemLogEX(TRUE, "파괴정보현황 전송대상 사이즈  (%d)\r\n",tmsize2);
			continue;
		}

		++itr;
	}

	///////////////////////////////////////////////
	// 변경된 입찰 정보 DB저장
	MSG_FC_DESTROY_AUCTION_TENDER_REQUEST *pQParam = new MSG_FC_DESTROY_AUCTION_TENDER_REQUEST;
	MEMSET_ZERO(pQParam, sizeof(MSG_FC_DESTROY_AUCTION_TENDER_REQUEST));
	memcpy(pQParam, pRMsg, sizeof(MSG_FC_DESTROY_AUCTION_TENDER_REQUEST));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DestroyAuction_UpdateBiddingInfo, this, m_character.AccountUniqueNumber, pQParam);

	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_DESTROY_AUCTION_GET_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pDestroyAuctionManager)
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_DESTROY_AUCTION_GET_REQUEST,
		MSG_FC_DESTROY_AUCTION_GET_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 파괴경매장 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_DESTROY_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
// 	///////////////////////////////////////////////
// 	// 파괴경매가 진행중인지 체크
// 	if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionInProgress )
// 	{
// 		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_COUNTDOWN_NOT_ENOUGH_TIME);
// 		return RES_BREAK;
// 	}
	
	///////////////////////////////////////////////
	// 파괴경매장 관련 0.2초 텀
	if ( DESTROY_AUCTION_PACKET_RECV_TICK > GetTickCount() - m_nLatelyMarketPacketRecvTick_GetRequeste )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_GetRequeste = GetTickCount();
	
	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// 회수가 가능한 상태인지 확인
#if defined(TEST140)
#else
	ATUM_DATE_TIME tmCurrentTime(TRUE);
	tmCurrentTime.AddDateTime(0,0,0,-(DESTROY_AUCTION_GET_POSSIBLE_TIME_HOUR),0,0);
	if ( tmCurrentTime > pRMsg->DAuctionGetPossibleTime || AUCTION_ITEM_STATE_END != pRMsg->DAuctionStatus )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_PROTOCOL_TIME_LIMIT_ERROR, pRMsg->DAuctionStatus);
		return RES_BREAK;
	}
#endif

	///////////////////////////////////////////////
	// 낙찰금액 소지여부 확인
	ITEM_GENERAL *pItemSPI = m_ItemManager.GetFirstItemGeneralByItemNum(MONEY_ITEM_NUMBER, ITEM_IN_CHARACTER);
	if ( NULL == pItemSPI )
	{	// SPI 아이템이 없을 경우 추가
		m_ItemManager.InsertItemBaseByItemNum(MONEY_ITEM_NUMBER, 0, IUT_GENERAL);
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_PROTOCOL_NO_SUCH_ITEM_INFO, MONEY_ITEM_NUMBER);
		return RES_BREAK;
	}
	if ( pItemSPI->CurrentCount < pRMsg->Price )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_GET_REQUEST, ERR_PROTOCOL_NOT_ENOUGH_MONEY, pItemSPI->CurrentCount, pRMsg->Price, "SPI");
		return RES_BREAK;
	}

	///////////////////////////////////////////////
	// DB로 아템 회수 요청하기
	MSG_FC_DESTROY_AUCTION_GET_REQUEST *pQParam = new MSG_FC_DESTROY_AUCTION_GET_REQUEST;
	MEMSET_ZERO(pQParam, sizeof(MSG_FC_DESTROY_AUCTION_GET_REQUEST));
	memcpy(pQParam, pRMsg, sizeof(MSG_FC_DESTROY_AUCTION_GET_REQUEST));
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DestroyAuction_GetAuctionItem, this, m_character.AccountUniqueNumber, pQParam);
	
	return RES_RETURN_TRUE;
}

ProcessResult CFieldIOCPSocket::Process_FC_DESTROY_AUCTION_MY_LIST_REQUEST(const char* pPacket, int nLength, int &nBytesUsed)
{
	///////////////////////////////////////////////
	// 매니저 포인터 확인
	if ( NULL == ms_pFieldIOCP->m_pDestroyAuctionManager)
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_PROTOCOL_NO_SUCH_SHOP);
		return RES_BREAK;
	}
	
	// 	DECLARE_MESSAGE_AND_CHECK_SIZE_SERVER(pPacket, nLength, nBytesUsed, T_FC_DESTROY_AUCTION_MY_LIST_REQUEST,
	// 		MSG_FC_DESTROY_AUCTION_MY_LIST_REQUEST, pRMsg);
	
	///////////////////////////////////////////////
	// 파괴경매장 이용중인지 체크
	if ( NULL == m_pCurrentBuildingNPC || BUILDINGKIND_DESTROY_AUCTION != m_pCurrentBuildingNPC->BuildingKind )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_COMMON_INVALID_BUILDINGKIND);
		return RES_BREAK;
	}
	
// 	///////////////////////////////////////////////
// 	// 파괴경매가 진행중인지 체크
// 	if ( FALSE == ms_pFieldIOCP->m_bDestroyAuctionInProgress )
// 	{
// 		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_COUNTDOWN_NOT_ENOUGH_TIME);
// 		return RES_BREAK;
// 	}
	
	///////////////////////////////////////////////
	// 파괴경매장 관련 0.2초 텀
	if ( DESTROY_AUCTION_PACKET_RECV_TICK > GetTickCount() - m_nLatelyMarketPacketRecvTick_GetRequeste )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_INTERVAL_SYSTEM_SECOND);
		return RES_BREAK;
	}
	m_nLatelyMarketPacketRecvTick_GetRequeste = GetTickCount();
	
	///////////////////////////////////////////////
	// 아레나 서버 체크
	if ( TRUE == g_pFieldGlobal->IsArenaServer() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_CANNOT_USE_ARENASERVER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// 캐릭터 유효성 체크
	if ( FALSE == IsValidCharacter() )
	{
		SendErrorMessage(T_FC_DESTROY_AUCTION_MY_LIST_REQUEST, ERR_INVALID_CHARACTER);
		return RES_BREAK;
	}
	
	///////////////////////////////////////////////
	// DB로 입찰현황 요청하기
	ms_pFieldIOCP->m_pAtumDBManager->MakeAndEnqueueQuery(QT_DestroyAuction_GetBiddingInfo, this, m_character.AccountUniqueNumber, NULL);
	
	return RES_RETURN_TRUE;
}
// end 2014-01-03 by jhseol&bckim, 파괴경매장 - 패킷 리시브 함수선언

// 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인
void CFieldIOCPSocket::CheckQuestUseItem(ItemNum_t i_nUseItemNum)
{
	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)
			{
				MSG_FC_QUEST_REQUEST_SUCCESS tmQuest;
				MEMSET_ZERO(&tmQuest, sizeof(MSG_FC_QUEST_REQUEST_SUCCESS));
				tmQuest.QuestIndex			= pQuestInfo->QuestIndex;
				this->CheckQuestRequestSuccessAndSendResult(pFCharQuest, &tmQuest, FALSE, 0, 0, 0, FALSE, FALSE, i_nUseItemNum);
				break;	// 2005-08-17 by cmkwon, 퀘스트를 하나만 체크하고 빠져 나간다
			}
		}
	}
}
// end 2014-01-28 by jhseol, 신규 퀘스트 스크립트 추가 - 아이템 사용 확인

// 2014-03-14 by jekim, 전투력 로그 추가
int CFieldIOCPSocket::GetCombatPower()
{

#if defined(SC_IMPROVED_BALANCE_OF_POWER_BCKIM_JWLEE)	// 2015-08-13 by bckim, 세력 균형 개선 
	
	if( m_character.Level < 100 )
	{
		return 0;	//	100 레벨미만의 캐릭터의 전투력은 측정하지 않음.
	}

	int power=0;
	if(IS_IGEAR(m_character.UnitKind)) power+=15;		// I +15
	else if(IS_AGEAR(m_character.UnitKind)) power+=15;	// A +15
	else if(IS_MGEAR(m_character.UnitKind)) power+=30;	// M +30
	else if(IS_BGEAR(m_character.UnitKind)) power+=20;	// B +20
	
	power+=(int)(m_character.Level/5);	
	
	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));
	mtmapUID2ItemGeneral::iterator itr = m_ItemManager.m_mapItemGeneral.begin();
	for(; m_ItemManager.m_mapItemGeneral.end() != itr; ++itr)
	{
		ITEM_GENERAL *pItemG = itr->second;
		if(NULL == pItemG) break;
		if(WEAR_ATTACHED != pItemG->Wear) continue;
		
		int EnchantCount=0;
		{
			mt_auto_lock mtA(&m_mapEnchant);
			mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(pItemG->UniqueNumber);
			if(itrEnchantList==m_mapEnchant.end()) EnchantCount=0; // 2014-03-20 by jekim, 전투력 로그 보완
			else EnchantCount=itrEnchantList->second.size(); // 2014-03-20 by jekim, 전투력 로그 보완
		}
		if(COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_LEGEND_ITEM))		// 2014-06-17 by bckim, 세력 불균형 ( 초심자 아이템 전투력 계산 제외 )
		{		//#define DES_BEGINNER_ITEM							249		// 2014-06-17 by bckim, 세력 불균형 ( 초심자 아이템 전투력 계산 제외 )
			if( FALSE == pItemG->ItemInfo->IsExistDesParam(DES_BEGINNER_ITEM) )  //  초심자 아이템이 아니면 측정 
			{
				EnchantCount+=10;
			}
		}
		power+=EnchantCount;
	}
	int playtime=m_atLoginDate.GetTimeDiffToCurrentTimeInSeconds()/60;
	if(playtime>5)playtime=5;
	return power*playtime;

#else	// 2015-08-13 by bckim, 세력 균형 개선 

	int power=0;
	if(IS_IGEAR(m_character.UnitKind)||IS_AGEAR(m_character.UnitKind)) power+=15;
	else if(IS_MGEAR(m_character.UnitKind)) power+=40;
	else if(IS_BGEAR(m_character.UnitKind)) power+=30;

	power+=(int)(m_character.Level/5);	

	mt_auto_lock igLock(&(m_ItemManager.m_mapItemGeneral));
	mtmapUID2ItemGeneral::iterator itr = m_ItemManager.m_mapItemGeneral.begin();
	for(; m_ItemManager.m_mapItemGeneral.end() != itr; ++itr)
	{
		ITEM_GENERAL *pItemG = itr->second;
		if(NULL == pItemG) break;
		if(WEAR_ATTACHED != pItemG->Wear) continue;

		int EnchantCount=0;
		{
			mt_auto_lock mtA(&m_mapEnchant);
			mtmapUID2EnchantVector::iterator itrEnchantList = m_mapEnchant.find(pItemG->UniqueNumber);
			if(itrEnchantList==m_mapEnchant.end()) EnchantCount=0; // 2014-03-20 by jekim, 전투력 로그 보완
			else EnchantCount=itrEnchantList->second.size(); // 2014-03-20 by jekim, 전투력 로그 보완
		}
		if(COMPARE_BIT_FLAG(pItemG->ItemInfo->ItemAttribute, ITEM_ATTR_LEGEND_ITEM))		// 2014-06-17 by bckim, 세력 불균형 ( 초심자 아이템 전투력 계산 제외 )
		{		//#define DES_BEGINNER_ITEM							249		// 2014-06-17 by bckim, 세력 불균형 ( 초심자 아이템 전투력 계산 제외 )
			if( FALSE == pItemG->ItemInfo->IsExistDesParam(DES_BEGINNER_ITEM) )  //  초심자 아이템이 아니면 측정 
			{
				EnchantCount+=10;
			}
		}
		power+=EnchantCount;
	}
	int playtime=m_atLoginDate.GetTimeDiffToCurrentTimeInSeconds()/60;
	if(playtime>5)playtime=5;
	return power*playtime;  

#endif


}
// end 2014-03-14 by jekim, 전투력 로그 추가

