#include "stdafx.h"
#include "gamesrv.h"
#include "GuildManager.h"
#include "Guild.h"
#include "Player.h"
#include "Guild_Common.h"

cGuildManager* cGuildManager::mpSingleton = NULL;

cGuildManager::cGuildManager()
: mGuildSelectLength(0)
, mGuildTotalLength(0)
, mGuildTotalOffset(0)
, mGuildSaveOffset(0)
, mMarkIndexGen(0)
, mAccumTime(0)
{
	mpSingleton = this;
}

cGuildManager::~cGuildManager()
{
	Release();
	mpSingleton = 0;
}

void cGuildManager::Release()
{
	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* p = (cGuild*)(i->mSecond);
		SAFE_DELETE( p );
	}
	mGuildMap.Clear();

	//
	mJoinMap.Clear();
}

bool cGuildManager::Init()
{
	mAccumTime = NETWORK2->GetAccumTime();
	return true;
}

cGuild* cGuildManager::GetGuild( unsigned long idx )
{
	return (cGuild*)mGuildMap.GetAt( idx );
}

wchar_t* cGuildManager::GetGuildName( unsigned long idx )
{
	cGuild* guild = GetGuild( idx );
	if ( guild != NULL )
		return guild->GetGuildName();
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::GetGuildName[%d], GuildCount[%d]", idx, mGuildMap.GetSize() );
	}
	return 0;
}

unsigned long cGuildManager::GetGuildMarkIndex( unsigned long idx )
{
	cGuild* guild = GetGuild( idx );
	if( guild != NULL )
	{
		return guild->GetGuildMarkIndex();
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::GetGuildMarkIndex[%d], GuildCount[%d]", idx, mGuildMap.GetSize() );
	}
	return 0;
}

/// select 수 확인
bool cGuildManager::CheckGuildLength()
{
	return ( mGuildSelectLength == mGuildMap.GetSize() );
}

bool cGuildManager::CheckGuildTotal()
{
	mGuildTotalOffset++;
	return ( mGuildTotalLength == mGuildTotalOffset );
}

/// 서버종료시 업데이트 검사
bool cGuildManager::CheckGuildSaveTotal()
{
	mGuildSaveOffset++;
	return ( mGuildMap.GetSize() == mGuildSaveOffset );
}

/// 길드 정보 추가
bool cGuildManager::VerifyGuildSelect( TB_GUILD* guild )
{
	cGuild* p = new cGuild;
	p->VerifySetInfo( guild );

	/// 최대 생성된 마크 인덱스 저장
	if( mMarkIndexGen < p->GetGuildMarkIndex() )
		mMarkIndexGen = p->GetGuildMarkIndex();

	return mGuildMap.Insert( guild->idx, p );
}

/// 길드 유저 정보 세팅
bool cGuildManager::VerifyGuildUser( unsigned long idx, TB_GUILD_USER* user )
{
	cGuild* guild = GetGuild( idx );
	return (guild != NULL) ? guild->VerifyAddPlayer( user ) : NULL;
}

/// 길드명 중복검사
bool cGuildManager::FindGuildName( wchar_t* name )
{
	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* p = (cGuild*)(i->mSecond);
		if ( p != NULL )
		{
			if ( wcsicmp( p->GetGuildName(), name ) == 0 )
				return true;
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::FindGuildName[%s], GuildCount[%d]", name, mGuildMap.GetSize() );
			continue;
		}
	}
	return false;
}

/// 프로세스
void cGuildManager::Process( unsigned long /*elasedTime*/, unsigned long accumTime )
{
	/// 접속정보 전채널 동기화
	if( accumTime - mAccumTime > CONNECT_UPDATETIME )
	{
		NETWORK2->PostGuildRequestConnect();
		mAccumTime = accumTime;
	}

	if( mGuildMap.GetSize() == 0 )
		return;

	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* p = (cGuild*)(i->mSecond);
		if ( p != NULL )
		{
			// 클라이언트 갱신 시간 계산
			if( accumTime - p->GetAccumTime() > GUILD_UPDATETIME )
			{
				/// 갱신 & 쏘기 
				SendGuildUpdateInfo( p );

				p->SetAccumTime( accumTime );
			}

			// DB 갱신 시간 계산
			if( accumTime - p->GetDBAccumTime() > GUILDDB_UPDATETIME )
			{
				SaveDBGuild( p );
				p->SetDBAccumTime( accumTime );
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::Process" );
			continue;
		}
	}
}

/// 길드 생성
bool cGuildManager::AddGuild( GUILD_CREATE* data, cPlayer* master )
{
	cGuild* p = new cGuild( );

	p->SetInfo( data->idx, data->characterIdx, data->name, data->masterName );
	p->AddPlayer( master, eGUILD_MASTER, NETWORK2->GetChannelNum() );
	p->SetMaster( master->GetObjectID(), master->GetName() );

	cGuild* guild = (cGuild*)mGuildMap.GetAt( data->idx );
	if( guild )
	{
		NETWORK2->PostServerEvent("cGuild::AddGuild[%d], GuildCount[%d]", data->idx, mGuildMap.GetSize() );
		return false;
	}

	return mGuildMap.Insert( data->idx, p );
}

/// 길드 삭제
bool cGuildManager::DeleteGuild( unsigned long idx )
{
	cGuildMap::cIterator i = mGuildMap.Find( idx );
	if( i != mGuildMap.End() )
	{
		cGuild* p = (cGuild*)(i->mSecond);
		SAFE_DELETE( p );
		mGuildMap.Erase(i);
	}
	else
	{
		NETWORK2->PostServerEvent("cGuild::DeleteGuild[%d], GuildCount[%d]", idx, mGuildMap.GetSize() );
		return false;
	}
	return true;
}

/// 신청정보 저장
bool cGuildManager::AddRequest( unsigned long recvIdx, unsigned long reqIdx )
{
	return ( mJoinMap.Insert( recvIdx, reqIdx ) );
}

void cGuildManager::DelRequest( unsigned long recvIdx )
{
	mJoinMap.Erase( recvIdx );
}

unsigned long cGuildManager::GetRequest( unsigned long recvIdx )
{
	cJoinMap::cIterator i = mJoinMap.Find( recvIdx );
	return ( i != mJoinMap.End() ) ? (unsigned long)(*i).mSecond : 0;
}

/// player 에게 길드정보 보내기
void cGuildManager::SendGuildInfo( ULONG_PTR socketContext, cPlayer* player, unsigned long idx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if ( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
		{
			HANDLE				handle = NULL;
			MSG_SYN_GUILD_LIST*	sendMsg = (MSG_SYN_GUILD_LIST*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_GUILD, NM_GUILD_LIST_SYN );
			unsigned long length  = sizeof(MSG_SYN_GUILD_LIST) - sizeof(sendMsg->table);

			TB_GUILD* info = guild->GetGuildInfo();

			/// 1. 길드 정보 복사
			sendMsg->data.idx			= info->idx;
			sendMsg->data.masterIndex	= info->masterIndex;
			sendMsg->data.position		= player->GetGuildPosition();
			sendMsg->data.markIndex		= info->markIdx;
			sendMsg->rowCount			= 0;

			wcscpy( sendMsg->data.masterName, info->masterName );
			wcscpy( sendMsg->data.name, info->name );
			wcscpy( sendMsg->data.notice, info->notice );

			sGuildUserInfo* user = sendMsg->table;
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i, ++user )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				user->characterIdx	= p->characterIdx;
				user->job			= p->job;
				user->level			= p->level;
				user->mapnum		= p->mapnum;
				user->position		= p->position;
				user->channelNum	= p->channelNum;
				wcscpy( user->name, p->name );

				sendMsg->rowCount++;
			}

			length += (sendMsg->rowCount * sizeof(sendMsg->table));
			NETWORK2->SendMsgRoot( handle, length );
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildInfo - Guild User Map EMPTY [%d]", idx );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildInfo1[%d,%d], GuildCount[%d]", player->GetObjectID(), idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
									mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
}

//
void cGuildManager::SendGuildInfo( cPlayer* player, unsigned long idx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if ( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
		{
			HANDLE				handle = NULL;
			MSG_SYN_GUILD_LIST*	sendMsg = (MSG_SYN_GUILD_LIST*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx(), NM_GUILD, NM_GUILD_LIST_SYN );
			if( sendMsg != NULL )
			{
				unsigned long length  = sizeof(MSG_SYN_GUILD_LIST) - sizeof(sendMsg->table);

				TB_GUILD* info = guild->GetGuildInfo();

				/// 1. 길드 정보 복사
				sendMsg->data.idx			= info->idx;
				sendMsg->data.masterIndex	= info->masterIndex;
				sendMsg->data.position		= player->GetGuildPosition();
				sendMsg->data.markIndex		= info->markIdx;
				sendMsg->rowCount			= 0;

				wcscpy( sendMsg->data.masterName, info->masterName );
				wcscpy( sendMsg->data.name, info->name );
				wcscpy( sendMsg->data.notice, info->notice );

				sGuildUserInfo* user = sendMsg->table;
				cGuildUserMap::cIterator i = mUserMap->Begin();
				cGuildUserMap::cIterator end = mUserMap->End();
				for( ; i != end; ++i, ++user )
				{
					TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
					user->characterIdx	= p->characterIdx;
					user->job			= p->job;
					user->level			= p->level;
					user->mapnum		= p->mapnum;
					user->position		= p->position;
					user->channelNum	= p->channelNum;
					wcscpy( user->name, p->name );

					sendMsg->rowCount++;
				}

				length += (sendMsg->rowCount * sizeof(sendMsg->table));
				NETWORK2->SendMsgRoot( handle, length );
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildInfo - Guild User Map EMPTY [%d]", idx );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildInfo2[%d,%d], GuildCount[%d]", player->GetObjectID(), idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("2: mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
									mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
}

// 길드에게 길드원 추가 정보 보내기
void cGuildManager::SendGuildUserAdd( cGuild* guild, long characterIdx, char level, long job, short mapnum, wchar_t* name, char position, DWORD channelNum )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		/// 길드 유저에게 보내주기
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user && user->GetObjectID() != (unsigned long)characterIdx )
				{
					/// 접속해 있는 유저면
					HANDLE	handle = NULL;
					MSG_SYN_GUILD_USERADD* sendMsg = (MSG_SYN_GUILD_USERADD*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_USERADD_SYN );
					if( sendMsg != NULL )
					{
						sGuildUserInfo* info = &sendMsg->user;
						info->characterIdx  = characterIdx;
						info->job			= job;
						info->level			= level;
						info->mapnum		= mapnum;
						info->position		= position;
						info->channelNum	= channelNum;
						wcscpy( info->name, name );

						NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_GUILD_USERADD) );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildUserAdd - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildUserAdd[%d,%d]", characterIdx, guild->GetGuildIndex() );
	}
}

/// 길드에게 길드원 탈퇴 정보 보내주기
void cGuildManager::SendGuildUserOut( cGuild* guild, unsigned long characterIdx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					/// 접속해 있는 유저면
					HANDLE	handle = NULL;
					MSG_SYN_GUILD_OUT* sendMsg = (MSG_SYN_GUILD_OUT*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_OUT_SYN );
					if( sendMsg != NULL )
					{
						sendMsg->characterIdx = characterIdx;
						NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_GUILD_OUT) );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildUserOut - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildUserOut[%d,%d]", characterIdx, guild->GetGuildIndex() );
	}
}

/// 길드에 추방 유저 정보 보내주기
void cGuildManager::SendGuildUserCut( cGuild* guild, unsigned long characterIdx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					/// 접속해 있는 유저면
					HANDLE	handle = NULL;
					MSG_SYN_GUILD_USERCUT* sendMsg = (MSG_SYN_GUILD_USERCUT*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_USERCUT_SYN );
					if( sendMsg != NULL )
					{
						sendMsg->characterIdx = characterIdx;
						NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_GUILD_USERCUT) );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildUserCut - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildUserCut[%d,%d]", characterIdx, guild->GetGuildIndex() );
	}
}

/// 길드직위 변경 및 갱신 정보 보내기
void cGuildManager::SendGuildChangePosition( cGuild* guild, unsigned long characterIdx, char position )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		TB_GUILD_USER* user = IsMyGuildUser( guild->GetGuildIndex(), characterIdx );
		if( user )
		{
			/// 새 길드장일 경우 기존 길드장 직위변경
			if( position == eGUILD_MASTER )
			{
				/// 기존 길드장 정보 변경 및 새 길드장 세팅
				cPlayer* master = OBJECTMANAGER->GetPlayer( guild->GetGuildMasterIndex() );
				if( master )
					master->ChangeGuildPosition( eGUILD_GENERAL );

				guild->SetMaster( characterIdx, user->name );
			}

			/// 해당 유저의 직위 변경
			user->position = position;
			cPlayer* player = OBJECTMANAGER->GetPlayer( characterIdx );
			if( player )
				player->ChangeGuildPosition( user->position );

			/// 직위 변경 갱신 보내기
			cGuildUserMap* mUserMap = guild->GetGuildUser();
			if( mUserMap != NULL )
			{
				cGuildUserMap::cIterator i = mUserMap->Begin();
				cGuildUserMap::cIterator end = mUserMap->End();
				for( ; i != end; ++i )
				{
					TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
					cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
					if( user )
					{
						/// 접속해 있는 유저면
						HANDLE	handle = NULL;
						MSG_SYN_GUILD_GIVEPOSITION* sendMsg = (MSG_SYN_GUILD_GIVEPOSITION*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_GIVEPOSITION_SYN );
						if( sendMsg != NULL )
						{
							sendMsg->characterIdx	= characterIdx;
							sendMsg->position		= position;
							NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_GUILD_GIVEPOSITION) );
						}
					}
				}
			}
			else
			{
				NETWORK2->PostServerEvent("cGuildManager::SendGuildChangePosition - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
			}
		}
		else
		{
			/// 에러
			NETWORK2->PostServerEvent("cGuildManager::SendGuildChangePosition[%d, %d, %d]", guild->GetGuildIndex(), characterIdx, position );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildChangePosition[%d]", guild->GetGuildIndex() );
	}
}

/// 해당 길드원들에게 갱신된 정보만 보내기
void cGuildManager::SendGuildUpdateInfo( cGuild* guild )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			// 1. 쏠 정보 구성
			long rowCount = 0;
			sGuildUserUpdate temp[50];
			memset( temp, 0, sizeof(temp) );

			sGuildUserUpdate* tempList = temp;
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				/// 갱신이 필요한 정보만 쏜다
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* guildUser = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( p->sendInfo == true )
				{
					p->sendInfo	= false;

					/// 유저가 존재하면 최신정보로 갱신
					if( guildUser != NULL )
					{
						p->level		= guildUser->GetLevel();
						p->job			= guildUser->GetJob();
						p->mapnum		= guildUser->GetMapNumber();
					}

					/// 메세지 구성
					tempList->characterIdx	= p->characterIdx;
					tempList->job			= p->job;
					tempList->level			= p->level;
					tempList->mapnum		= p->mapnum;
					tempList->channelNum	= p->channelNum;

					tempList++;
					rowCount++;
				}
			}

			/// 2. 클라이언트에 쏘기
			if( rowCount > 0 )
			{
				cGuildUserMap::cIterator ui = mUserMap->Begin();
				cGuildUserMap::cIterator uend = mUserMap->End();
				for( ; ui != uend; ++ui )
				{
					TB_GUILD_USER* p = (TB_GUILD_USER*)(ui->mSecond);
					cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
					if( user )
					{
						/// 접속해 있는 유저에게
						HANDLE	handle = NULL;
						MSG_SYN_GUILD_UPDATE* sendMsg = (MSG_SYN_GUILD_UPDATE*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_UPDATE_SYN );
						if( sendMsg != NULL )
						{
							unsigned long length = sizeof(MSG_SYN_GUILD_UPDATE) - sizeof(sendMsg->table);
							sendMsg->rowCount	 = rowCount;
							
							sGuildUserUpdate* data = temp;
							sGuildUserUpdate* table = sendMsg->table;
							for( int i = 0; i < rowCount; ++i, ++data, ++table )
							{
								*table = *data;
							}

							length += (sendMsg->rowCount * sizeof(sendMsg->table));
							NETWORK2->SendMsgRoot( handle, length );
						}
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildUpdateInfo - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildUpdateInfo[%d]", guild->GetGuildIndex() );
	}
}

/// 길드 공지
bool cGuildManager::SendGuildNotice( unsigned long idx, wchar_t* notice )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if( guild != NULL )
	{
		/// 공지 길이 확인
		int len = (int)wcslen( notice );
		if( len == 0 )
			return false;

		guild->SetNotice( notice );
        
		/// 공지 내용 쏘기
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					HANDLE		handle = NULL;
					MSG_SYN_GUILD_NOTICE* sendMsg = (MSG_SYN_GUILD_NOTICE*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILD_NOTICE_SYN );
					if( sendMsg != NULL )
					{
						wcscpy( sendMsg->notice, notice );
						NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildNotice - Guild User Map EMPTY [%d]", idx );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildNotice[%d]", idx );
		return false;
	}
	return true;
}

void cGuildManager::SendGuildMarkUpdate( cGuild* guild, unsigned long markIdx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( guild != NULL )
	{
		/// 마크 갱신보내기 
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					/// 각 유저의 마크 정보 변경
					user->ChangeGuildMarkIndex( markIdx );

					HANDLE		handle = NULL;
					MSG_SYN_GUILDMARK_UPDATE* sendMsg = (MSG_SYN_GUILDMARK_UPDATE*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_GUILD, NM_GUILDMARK_UPDATE_SYN );
					if( sendMsg != NULL )
					{
						sendMsg->markIndex = markIdx;
						NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_GUILDMARK_UPDATE) );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildMarkUpdate - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildMarkUpdate[%d], [%d]", guild->GetGuildIndex(), markIdx );
	}
}

/// 길드마크 정보 보내주기
bool cGuildManager::SendGuildMark( unsigned long idx, cPlayer* player )
{
	cGuild* guild = GetGuild( idx );
	if( guild != NULL )
	{
		TB_GUILD* info = guild->GetGuildInfo();

		HANDLE		handle = NULL;
		MSG_RES_GUILDMARK_SEND* sendMsg = (MSG_RES_GUILDMARK_SEND*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx(), NM_GUILD, NM_GUILDMARK_SEND_RES );
		if( sendMsg != NULL )
		{
			sendMsg->guildIndex = idx;
			sendMsg->markIndex = info->markIdx;
			memcpy( &sendMsg->mark, &info->mark, MARK_SIZE );
			NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_GUILDMARK_SEND) );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::GetGuild[%d,%d]-NM_GUILDMARK_SEND_RES", player->GetObjectID(), idx);
		return false;
	}
	return true;
}

/// 길드 채팅
void cGuildManager::SendGuildChat( cPlayer* hero, wchar_t* message, unsigned short number )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	if( hero->GetGuildIndex() == 0 )
		return;

	TB_INVENTORY*	inventory = hero->SelectInventory( number );
	cGuild* guild = GetGuild( hero->GetGuildIndex() );
	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					HANDLE		handle = NULL;
					MSG_SYN_CHAT_GUILD* sendMsg = (MSG_SYN_CHAT_GUILD*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_CHAT, NM_CHAT_GUILD_SYN );
					if( sendMsg != NULL )
					{
						wcscpy( sendMsg->Name, hero->GetName() );
						wcscpy( sendMsg->Message, message );

						if( hero->IsInventory( inventory ) == true )
							Inventory2sInventory( &sendMsg->inventory, inventory );

						NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SendGuildUpdateInfo - Guild User Map EMPTY [%d]", guild->GetGuildIndex() );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SendGuildUpdateInfo[%d]", guild->GetGuildIndex() );
	}
}

/// 전체 길드 정보 DB 저장
bool cGuildManager::SaveAllDB()
{
	bool retcode = false;

	if( mGuildMap.GetSize() == 0 )
		return retcode;

	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* p = (cGuild*)(i->mSecond);
		if ( p != NULL )
		{
			SaveDBGuild( p );
			retcode = true;
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::Process" );
			continue;
		}
	}
	return retcode;
}

// DB 에 길드 정보 저장
void cGuildManager::SaveDBGuild( cGuild* guild )
{	
	TB_GUILD*		info = guild->GetGuildInfo();

	HANDLE			handle		= NULL;
	GUILD_UPDATE*	guildUpdate = (GUILD_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_GUILD_UPDATE );
	if( guildUpdate != NULL )
	{
		guildUpdate->idx   = info->idx;
		wcscpy( guildUpdate->notice, info->notice );
		NETWORK2->SendSQL( handle, sizeof(GUILD_UPDATE) );
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SaveDBGuild[%d]", info->idx );
	}
}

// 플레이어 들어옴 : 맵이동
void cGuildManager::PlayerMapIn( cPlayer* hero )
{
	if( hero->GetGuildIndex() > 0 )
	{
		SendGuildInfo( hero, hero->GetGuildIndex() );

		GuildUpdateChannel( hero->GetGuildIndex(), hero->GetObjectID(), NETWORK2->GetChannelNum() );

		/// GAME SYN : 다른채널에 알림
		if( NETWORK2->PostGuildUpdateChannel( hero->GetGuildIndex(), hero->GetObjectID(), true ) == false )
		{
			NETWORK2->PostGuildEvent( hero->GetObjectID(), hero->GetGuildIndex(), hero->GetGuildPosition(), "FAIL - PostGuildUpdateChannel() connect" );
		}
	}
}

// 플레이어 나감 - 해당플레이어가 길드관련 연결정보가 있으면 끊어준다
// 신청자 : 맵아웃, 게임종료시 따로 처리하지 않는다
// 신청받는유저 : 맵아웃, 게임종료시 자동 거절 처리한다
void cGuildManager::PlayerMapOut( cPlayer* hero )
{
	unsigned long reqIdx = GetRequest( hero->GetObjectID() );
	if( reqIdx > 0 )
	{
		// 길드초대한 유저가 존재하면 알려준다
		cPlayer* requester = OBJECTMANAGER->GetPlayer( reqIdx );
		if( requester )
		{
			// 신청상태 풀기
			requester->SetGuildAddReq( false );

			// 게임을 나감으로써 자동 거절 처리
			HANDLE              handle = NULL;
			MSG_RES_GUILD_ADD* sendMsg = (MSG_RES_GUILD_ADD*)NETWORK2->GetMsgRoot( &handle, requester->GetConnectionIdx(), NM_GUILD, NM_GUILD_ADD_RES );
			if( sendMsg != NULL )
			{
				sendMsg->ErrorCode = ERROR_GUILD_ADD_REFUSE;
				NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_GUILD_ADD) );
			}
		}	

		/// 
		DelRequest( hero->GetObjectID() );

		///
		hero->EndRequestRejection( eREQREJCT_GUILD );
	}

	if( hero->GetGuildIndex() > 0 )
	{
		GuildUpdateChannel( hero->GetGuildIndex(), hero->GetObjectID(), 0 );

		/// GAME SYN : 다른채널에 알림
		if( NETWORK2->PostGuildUpdateChannel( hero->GetGuildIndex(), hero->GetObjectID(), false ) == false )
		{
			NETWORK2->PostGuildEvent( hero->GetObjectID(), hero->GetGuildIndex(), hero->GetGuildPosition(), "FAIL - PostGuildUpdateChannel() connect out" );
		}
	}
}

bool cGuildManager::GuildUpdateChannel( unsigned long idx, unsigned long characterIdx, DWORD channelNum )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			TB_GUILD_USER* user = (TB_GUILD_USER*)mUserMap->GetAt( characterIdx );
			if( user )
			{
				/// 접속 채널 번호 갱신 ( 0 이면 접속안함 )
				user->channelNum = channelNum;
				user->sendInfo = true;
			}
			else
			{
				NETWORK2->PostServerEvent("cGuildManager::GuildUpdateChannel - Not exist user [%d,%d]", idx, characterIdx );
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::GuildUpdateChannel - Guild User Map EMPTY [%d]", idx );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::GuildUpdateChannel[%d]", idx );
	}

	return true;
}

// 내 길드원인지 검사
TB_GUILD_USER* cGuildManager::IsMyGuildUser( unsigned long idx, unsigned long characterIdx )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if ( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if ( mUserMap != NULL )
			return (TB_GUILD_USER*)mUserMap->GetAt( characterIdx );
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::IsMyGuildUser[%d,%d], GuildCount[%d]", characterIdx, idx, mGuildMap.GetSize() );
	}
	return 0;
}

// 직위 변경 가능한지 검사
bool cGuildManager::CheckChangePosition( cPlayer* hero, unsigned long characterIdx, char newposition )
{
	// 내 길드원인지 검사
	TB_GUILD_USER* user = IsMyGuildUser( hero->GetGuildIndex(), characterIdx );
	if( user )
	{
		// 권한 검사
		char heroPosition = hero->GetGuildPosition();
		if( !(heroPosition == eGUILD_MASTER || heroPosition == eGUILD_SUBMASTER) )
			return false;

		// 해당 유저의 직위가 자신보다 낮아야함( 상대방이 동일한 길드장일수 없음!! )
		if( heroPosition == eGUILD_MASTER && !(heroPosition < user->position) )
		{
			NETWORK2->PostServerEvent("cGuildManager::CheckChangePosition[%d,%d,%d,%d,%d]", hero->GetObjectID(), heroPosition, characterIdx, user->position, newposition );
			return false;
		}

		// 해당유저의 직책이 자신보다 높거나, 변경직책이 자신보다 높을수 없다
		if( heroPosition == eGUILD_SUBMASTER && !(heroPosition < user->position && heroPosition < newposition) )
			return false;
			
		return true;
	}
	return false;
}

/// 갱신 요청 - 레벨업, 전직
bool cGuildManager::RequestUpdateUser( unsigned long idx, unsigned long characterIdx, char level, long job )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( idx );
	if( guild )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			TB_GUILD_USER* user = (TB_GUILD_USER*)mUserMap->GetAt( characterIdx );
			if( user )
			{
				/// 갱신 플래그 세우기
				user->sendInfo = true;

				/// 다른 채널에 쏘기
				if( NETWORK2->PostGuildUpdateInfo( guild->GetGuildIndex(), characterIdx, level, job ) == false )
				{
					NETWORK2->PostServerEvent("cGuildManager::RequestUpdateUser - send error [%d,%d,%d,%d]", 
												guild->GetGuildIndex(), characterIdx, level, job );
				}
			}
			else
				NETWORK2->PostServerEvent("cGuildManager::RequestUpdateUser - Guild User error [%d,%d]", idx, characterIdx );
		}
		else
			NETWORK2->PostServerEvent("cGuildManager::RequestUpdateUser - Guild User Map EMPTY [%d]", idx );
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::RequestUpdateUser[%d], GuildCount[%d]", idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
										mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
	return true;
}

//--------------------------------------------------------
// GAME SYN
bool cGuildManager::SynAddGuild( void* msg, DWORD channelNum )
{
	MSG_SYN_POSTGUILD_CREATE* pmsg = (MSG_SYN_POSTGUILD_CREATE*)msg;

	cGuild* p = new cGuild();
	p->SetInfo( pmsg->idx, pmsg->masterIndex, pmsg->name, pmsg->masterName );
	p->AddPlayer( pmsg->masterIndex, pmsg->level, pmsg->job, pmsg->mapnum, pmsg->masterName, pmsg->position, channelNum );
	p->SetMaster( pmsg->masterIndex, pmsg->masterName );

	cGuild* guild = (cGuild*)mGuildMap.GetAt( pmsg->idx );
	if( guild )
	{
		NETWORK2->PostServerEvent("cGuild::AddGuildPostSyn[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		return false;
	}

	return mGuildMap.Insert( pmsg->idx, p );
}

bool cGuildManager::SynAddGuildUser( void* msg, DWORD channelNum )
{
	MSG_SYN_POSTGUILD_USERADD* pmsg = (MSG_SYN_POSTGUILD_USERADD*)msg;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild )
	{
		if( guild->AddPlayer( pmsg->characterIdx, pmsg->level, pmsg->job, pmsg->mapnum, pmsg->name, pmsg->position, channelNum ) == true )
		{
			SendGuildUserAdd( guild, pmsg->characterIdx, pmsg->level, pmsg->job, pmsg->mapnum, pmsg->name, pmsg->position, channelNum );
		}
		else
		{
			NETWORK2->PostGuildEvent( pmsg->characterIdx, pmsg->idx, pmsg->position, "FAIL - SynAddGuildUser()" );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynAddGuildUser[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
									mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
	return true;
}

bool cGuildManager::SynCutGuilduser( void* msg )
{
	MSG_SYN_POSTGUILD_USERCUT* pmsg = (MSG_SYN_POSTGUILD_USERCUT*)msg;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild )
	{
		if( guild->DeletePlayer( pmsg->characterIdx ) == true )
		{
			/// 추방된 유저에게 알리기
			cPlayer* cutUser = OBJECTMANAGER->GetPlayer( pmsg->characterIdx );
			if( cutUser )
			{
				cutUser->ChangeGuild( 0, eGUILD_NONE, 0, 0 );

				// 추방 
				HANDLE			handle = NULL;
				if( NETWORK2->GetMsgRoot( &handle, cutUser->GetConnectionIdx(), NM_GUILD, NM_GUILD_CUT_SYN ) != false )
				{
					NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_GUILD_OUT) );
				}

				// 길드 신청 정보 있으면 삭제
				cutUser->SetGuildAddReq( false );
			}

			/// 다른유저들에게 알리기
			SendGuildUserCut( guild, pmsg->characterIdx );
		}
		else
		{
			NETWORK2->PostGuildEvent( pmsg->characterIdx, pmsg->idx, eGUILD_NONE, "FAIL - SynCutGuilduser()" );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynCutGuilduser[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
										mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
	return true;
}

bool cGuildManager::SynOutGuilduser( void* msg )
{
	MSG_SYN_POSTGUILD_USEROUT* pmsg = (MSG_SYN_POSTGUILD_USEROUT*)msg;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild )
	{
		if( guild->DeletePlayer( pmsg->characterIdx ) == true )
		{
			// 길드원들에게 쏘기
			SendGuildUserOut( guild, pmsg->characterIdx );
		}
		else
		{
			NETWORK2->PostGuildEvent( pmsg->characterIdx, pmsg->idx, eGUILD_NONE, "FAIL - SynOutGuilduser()" );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynOutGuilduser[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
									mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
	return true;
}

bool cGuildManager::SynUpdateMark( void* msg )
{
	MSG_SYN_POSTGUILD_UPDATEMARK* pmsg = (MSG_SYN_POSTGUILD_UPDATEMARK*)msg;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild )
	{
		// 길드 마크 정보 변경
		int size = sizeof(pmsg->mark);
		guild->UpdateMark( pmsg->markIndex, pmsg->mark, size );

		// 길드원들에게 변경된 마크인덱스 전송
		SendGuildMarkUpdate( guild, pmsg->markIndex );
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynUpdateMark[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
			mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}
	return true;
}

bool cGuildManager::SynUpdateGuildUserInfo( void* msg )
{
	MSG_SYN_POSTGUILD_UPDATE* pmsg = (MSG_SYN_POSTGUILD_UPDATE*)msg;

	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			TB_GUILD_USER* user = (TB_GUILD_USER*)mUserMap->GetAt( pmsg->characterIdx );
			if( user )
			{
				user->level  = pmsg->level;
				user->job    = pmsg->job;
				user->sendInfo = true;
			}
			else
			{
				NETWORK2->PostServerEvent("cGuildManager::SynUpdateGuildUserInfo - Guild User error [%d,%d]", pmsg->idx, pmsg->characterIdx );
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SynUpdateGuildUserInfo - Guild User Map EMPTY [%d]", pmsg->idx );
		}
	}	
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynUpdateGuildUserInfo[%d], GuildCount[%d]", pmsg->idx, mGuildMap.GetSize() );
		NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
									  mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
	}

	return true;
}

bool cGuildManager::SynGuildChat( void* msg )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;
	MSG_SYN_POSTGUILD_CHAT* pmsg = (MSG_SYN_POSTGUILD_CHAT*)msg;

	cGuild* guild = GetGuild( pmsg->idx );
	if( guild != NULL )
	{
		cGuildUserMap* mUserMap = guild->GetGuildUser();
		if( mUserMap != NULL )
		{
			cGuildUserMap::cIterator i = mUserMap->Begin();
			cGuildUserMap::cIterator end = mUserMap->End();
			for( ; i != end; ++i )
			{
				TB_GUILD_USER* p = (TB_GUILD_USER*)(i->mSecond);
				cPlayer* user = OBJECTMANAGER->GetPlayer( p->characterIdx );
				if( user )
				{
					HANDLE		handle = NULL;
					MSG_SYN_CHAT_GUILD* sendMsg = (MSG_SYN_CHAT_GUILD*)NETWORK2->GetMsgRoot( &handle, user->GetConnectionIdx(), NM_CHAT, NM_CHAT_GUILD_SYN );
					if( sendMsg != NULL )
					{
						wcscpy( sendMsg->Name, pmsg->Name );
						wcscpy( sendMsg->Message, pmsg->Message );
						memcpy( &sendMsg->inventory, &pmsg->inventory, sizeof(sInventory) );
						NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() );
					}
				}
			}
		}
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SynGuildChat - Guild User Map EMPTY [%d]", pmsg->idx );
		}
	}
	else
	{
		NETWORK2->PostServerEvent("cGuildManager::SynGuildChat[%d]", pmsg->idx );
	}

	return true;
}

bool cGuildManager::SynGuildNote( void* msg )
{
	MSG_SYN_POSTGUILD_NOTESEND* pmsg = (MSG_SYN_POSTGUILD_NOTESEND*)msg;

	TB_NOTE* note = pmsg->table;
	for( int i = 0; i < pmsg->rowCount; ++i, ++note )
	{
		if( note->retValue == 0 )
		{
			cPlayer* player = OBJECTMANAGER->GetPlayer( pmsg->characterIdx2[i] );
			if( player != NULL )
			{
				/// 현재 채널내에 존재하면 플레이어면,
				if( NOTEMAN->AddNote( pmsg->characterIdx2[i], note ) == true )
				{
					/// 추가된 내용 쏴주기
					HANDLE				handle = NULL;
					MSG_SYN_NOTE_SEND* sendMsg = (MSG_SYN_NOTE_SEND*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx(), NM_CHAT, NM_CHAT_NOTE_SEND_SYN );
					if( sendMsg != NULL )
					{
						sendMsg->table.Idx    = note->idx;
						sendMsg->table.Year   = note->registerDate.year;
						sendMsg->table.Month  = note->registerDate.month;
						sendMsg->table.Day    = note->registerDate.day;
						sendMsg->table.Hour   = note->registerDate.hour;
						sendMsg->table.Minute = note->registerDate.minute;
						wcscpy( sendMsg->table.CharacterName, note->characterName );
						wcscpy( sendMsg->table.Message, note->message );
						sendMsg->table.RemainTime = note->remainTime;

						NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_NOTE_SEND) );
					}
				}
				else
				{
					NETWORK2->PostServerEvent( "SynGuildNote - CHARACTER_IDX(%d), NOTE_IDX[(%d)", pmsg->characterIdx2[i], note->idx );
				}
			}
		}
	}

	return true;
}

/// 다른 채널의 길드원 접속 정보
bool cGuildManager::SynGuildConnect( void* msg, DWORD channelNum )
{
	MSG_SYN_POSTGUILD_CONNECT* pmsg = (MSG_SYN_POSTGUILD_CONNECT*)msg;

	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	/// 초기화 (자신의 채널을 제외한 다른정보는 모두 초기화)
	ClearGuildConnect();

	/// 접속정보 세팅
	sGuildConnect* info = pmsg->table;
	for( long i = 0; i < pmsg->rowCount; ++i, ++info )
	{
		cGuild* guild = GetGuild( info->guildIdx );
		if( guild )
		{
			cGuildUserMap* mUserMap = guild->GetGuildUser();
			if( mUserMap != NULL )
			{
				TB_GUILD_USER* user = (TB_GUILD_USER*)mUserMap->GetAt( info->characterIdx );
				if( user )
				{
					user->channelNum = channelNum;
					user->sendInfo = true;
				}
				else
				{
					NETWORK2->PostServerEvent("cGuildManager::SynGuildConnect - Guild User error [%d,%d]", info->guildIdx, info->characterIdx );
				}
			}
			else
			{
				NETWORK2->PostServerEvent("cGuildManager::SynGuildConnect - Guild User Map EMPTY [%d]", info->guildIdx );
			}
		}	
		else
		{
			NETWORK2->PostServerEvent("cGuildManager::SynGuildConnect[%d], GuildCount[%d]", info->guildIdx, mGuildMap.GetSize() );
			NETWORK2->PostServerEvent("1 : mGuildTotalLength[%d], mGuildTotalOffset[%d], mGuildSaveOffset[%d], mGuildSelectLength[%d]",
				mGuildTotalLength, mGuildTotalOffset, mGuildSaveOffset, mGuildSelectLength );
		}
	}
	return true;
}

/// 전체 길드원 접속 정보 보내기
bool cGuildManager::SendGuildConnect( DWORD reqChannelNum )
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;
	typedef tArray<sGuildConnect> cTempArray;
	cTempArray	tempArray;

	/// 현재 내 채널에 접속한 길드원들에 대한 정보를 추려서 전송한다
	DWORD channelNum = NETWORK2->GetChannelNum();

	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* guild = (cGuild*)(i->mSecond);
		if( guild )
		{
			cGuildUserMap* mUserMap = guild->GetGuildUser();
			if( mUserMap != NULL )
			{
				cGuildUserMap::cIterator ui = mUserMap->Begin();
				cGuildUserMap::cIterator uend = mUserMap->End();
				for( ; ui != uend; ++ui )
				{
					TB_GUILD_USER* p = (TB_GUILD_USER*)(ui->mSecond);
					if( p->channelNum == channelNum )
					{
						sGuildConnect data;
						data.guildIdx		= guild->GetGuildIndex();
						data.characterIdx	= p->characterIdx;
						tempArray.PushBack( data );
					}
				}
			}
		}
	}

	if( tempArray.GetSize() > 0 )
	{
		PerIoContext*              perIoContext = NETWORK2->GetIoContext( IOCP_REQUEST_WRITE );
		MSG_SYN_POSTGUILD_CONNECT* sendMsg      = (MSG_SYN_POSTGUILD_CONNECT*)perIoContext->buffer;
		sGuildConnect*             table        = sendMsg->table;
		unsigned long              length       = sizeof(MSG_SYN_POSTGUILD_CONNECT) - sizeof(sendMsg->table);

		sendMsg->Category = NM_GUILD;
		sendMsg->Protocol = NM_GUILDPOST_CONNECT_SYN;
		sendMsg->reqChannelNum = reqChannelNum;
		sendMsg->rowCount = tempArray.GetSize();

		for( long i = 0; i < sendMsg->rowCount; ++i, ++table )
		{
			sGuildConnect info = tempArray[i];
			*table = info;
		}

		length += (sendMsg->rowCount * sizeof(sendMsg->table));

		cSender* sender = g_gameSrv->GetSender( );
		if ( sender != NULL )
		{
			long cid = NETWORK2->GetCID();
			sender->PostGuildSync( cid, (char*)sendMsg, length );
		}

		///
		perIoContext->offset = length;
		NETWORK2->ReleaseIoContext( perIoContext );
	}
	return true;
}

void cGuildManager::ClearGuildConnect()
{
	typedef tPointerHashMap<unsigned long, void*> cGuildUserMap;

	DWORD channelNum = NETWORK2->GetChannelNum();

	cGuildMap::cIterator i = mGuildMap.Begin();
	cGuildMap::cIterator end = mGuildMap.End();
	for( ; i != end; ++i )
	{
		cGuild* guild = (cGuild*)(i->mSecond);
		if( guild )
		{
			cGuildUserMap* mUserMap = guild->GetGuildUser();
			if( mUserMap != NULL )
			{
				cGuildUserMap::cIterator ui = mUserMap->Begin();
				cGuildUserMap::cIterator uend = mUserMap->End();
				for( ; ui != uend; ++ui )
				{
					TB_GUILD_USER* p = (TB_GUILD_USER*)(ui->mSecond);
					if( p->channelNum != channelNum )
						p->channelNum = 0;
				}
			}
		}
	}

}
