#include #include #include #include #include #include #include #include "LogClient/LogClient.h" #include "DB_Commands.h" #include "StructPlayer.h" #include "SendMessage.h" #include "GameMessage.h" #include "StructItem.h" #include "StructSummon.h" #include "GameProc.h" #include "GameRule.h" bool DB_GetCommercialStorageInfo::onProcess( DBConnection & db ) { try { _CommandPtr cmd; if( db.CreateCommand( cmd ) == false ) throw XException( "DB_GetCommercialStorageInfo : CreateInstance(command) error" ); // 느린 쿼리 타임아웃 조정 cmd->CommandTimeout = 60; cmd->CommandType = adCmdStoredProc; cmd->CommandText = _bstr_t( "dbo.smp_check_purchased_item" ); // Store the name of current stored-procedure for debugging szStoredProcedureName = "dbo.smp_check_purchased_item"; cmd->Parameters->Append( cmd->CreateParameter( "IN_ACCOUNT_ID", adInteger, adParamInput, 4, m_pPlayer->GetAccountID() ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_CHARACTER_ID", adInteger, adParamInput, 4, m_pPlayer->GetPlayerUID() ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_TOTAL_ITEM_COUNT", adInteger, adParamOutput, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_NEW_ITEM_COUNT", adInteger, adParamOutput, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_PREMIUM_TICKET", adInteger, adParamOutput, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_PREMIUM_REST_TIME", adInteger, adParamOutput, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_STAMINA_REGEN_TIME", adInteger, adParamOutput, 4, 0 ) ); _variant_t vNull; vNull.vt=VT_ERROR; vNull.scode=DISP_E_PARAMNOTFOUND; cmd->Execute(&vNull,&vNull,adCmdStoredProc); if( cmd->Parameters->Item[ "OUT_TOTAL_ITEM_COUNT" ]->Value.vt != VT_NULL ) { ::TS_SC_COMMERCIAL_STORAGE_INFO msg; msg.total_item_count = cmd->Parameters->Item[ "OUT_TOTAL_ITEM_COUNT" ]->Value; msg.new_item_count = cmd->Parameters->Item[ "OUT_NEW_ITEM_COUNT" ]->Value; PendMessage( m_pPlayer, &msg ); } if( cmd->Parameters->Item[ "OUT_PREMIUM_TICKET" ]->Value.vt != VT_NULL ) { int bIsPremiumUser = cmd->Parameters->Item[ "OUT_PREMIUM_TICKET" ]->Value; int nRestSecond = cmd->Parameters->Item[ "OUT_PREMIUM_REST_TIME" ]->Value; // 계정 권한 DB가 있는 서버라면, 전 동기화 과정에서 이미 시크루트 처리 됨. if( !GameRule::bUseAccountAuthorityDB ) m_pPlayer->SetSetSecrouteFreePass( (bIsPremiumUser != 0), nRestSecond ); } // 로그인과 함께 처리되는 중일 경우에 필요한 추가 처리 if( m_bIsProcessingLogin ) { // 시크루트 귀환권 아이템 지급 후에 퀵슬롯 정보를 보내야 하기 때문에 여기서 전송 // (캐쉬 아이템 사용 가능 서버가 아닌 경우에는 SendLoginResult에서 보냄) // !! 클라이언트 세팅 정보를 보낼 때에는 client_info를 항상 먼저 보내야 한다. SendPropertyMessage( m_pPlayer, m_pPlayer->GetHandle(), "client_info", m_pPlayer->GetClientInfo() ); SendPropertyMessage( m_pPlayer, m_pPlayer->GetHandle(), "quick_slot", m_pPlayer->GetQuickSlot() ); SendPropertyMessage( m_pPlayer, m_pPlayer->GetHandle(), "current_key", m_pPlayer->GetCurrentKey() ); SendPropertyMessage( m_pPlayer, m_pPlayer->GetHandle(), "saved_key", m_pPlayer->GetSavedKey() ); // 시크루트 프리패스가 로그아웃 중에 종료됐을 경우 스테미너 회복 // (프리패스가 종료되지 않았거나 로그아웃 이전에 종료됐으면 OUT_STAMINA_REGEN_TIME이 0으로 나온다) // 여기서는 텐트 사용자인지, 프리패스 유저인지 모든게 분명함 int regen_rate = m_pPlayer->GetStaminaRegenRate(); if( m_pPlayer->IsUsingTent() || m_pPlayer->IsGaiaMember() ) { // 1. 텐트 사용자인데 시크루트 프리패스가 끝났을 경우 // OUT_STAMINA_REGEN_TIME 값이 세팅되어 오며, 현재 회복률로 로그아웃 시간 전체의 스태미너 회복 외에 // 시크루트 프리패스에 의해 추가 회복되었어야 할 시간이 더해짐으로써 적용됨 // 2. 텐트 사용 유무와 관계 없이 시크루트 프리패스 사용 중인 경우 // OUT_STAMINA_REGEN_TIME은 0으로 반환되어 전체 로그아웃 시간 동안 // 현재 스태미너 회복률(시크루트에 의해 2배 적용 됨)로 스태미너 회복 m_pPlayer->AddStamina( ( cmd->Parameters->Item[ "OUT_STAMINA_REGEN_TIME" ]->Value.intVal + m_pPlayer->GetLogoutDuration() ) * regen_rate ); } else { // 여기서는 로그아웃 상태의 스테미너는 회복시키면 안되지만 로그아웃 시점부터 // 시크루트 프리패스가 종료되는 시점까지의 스테미너는 회복시켜야 함 // 현재 스테미너 회복률은 시크루트 프리패스가 없는 상태이므로 당시의 회복률은 현재의 2배 m_pPlayer->AddStamina( cmd->Parameters->Item[ "OUT_STAMINA_REGEN_TIME" ]->Value.intVal * regen_rate * GameRule::SECROUTE_STAMINA_REGEN_BONUS_RATE ); } // 이벤트 지속효과 부여 처리 m_pPlayer->ProcEventState(); LOG::Log11N4S( LM_CHARACTER_ENTER, m_pPlayer->GetAccountID(), m_pPlayer->GetSID(), 0, 0, m_pPlayer->GetPCBangMode(), m_pPlayer->GetStamina(), m_pPlayer->GetGold().GetRawData(), m_pPlayer->GetLayer(), m_pPlayer->GetX(), m_pPlayer->GetY(), 0, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); LOG::Log11N4S( LM_CHARACTER_INFO, m_pPlayer->GetAccountID(), m_pPlayer->GetSID(), m_pPlayer->GetLevel(), m_pPlayer->GetJobLevel(), m_pPlayer->GetJobPoint(), m_pPlayer->GetJobId(), m_pPlayer->GetGold().GetRawData(), m_pPlayer->GetStorageGold().GetRawData(), m_pPlayer->GetChaos(), m_pPlayer->GetImmoralPoint(), m_pPlayer->GetEXP(), m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); } m_pPlayer->onEndQuery(); } catch( ... ) { throw; } return true; } void DB_GetCommercialStorageInfo::onFail( const _com_error & exception ) { std::string strMessage( GameContent::GetString( 103 ) ); strMessage += "(1)"; SendChatMessage( false, CHAT_NOTICE, "@NOTICE", m_pPlayer, strMessage.c_str() ); m_pPlayer->onEndQuery(); } bool DB_ReadCommercialStorageList::onProcess( DBConnection & db ) { try { _CommandPtr cmd; if( db.CreateCommand( cmd ) == false ) throw XException( "DB_ReadCommercialItemStorageList : CreateInstance(command) error" ); cmd->CommandType = adCmdStoredProc; cmd->CommandText = _bstr_t( "dbo.smp_read_purchased_item_list" ); // Store the name of current stored-procedure for debugging szStoredProcedureName = "dbo.smp_read_purchased_item_list"; cmd->Parameters->Append( cmd->CreateParameter( "IN_ACCOUNT_ID", adInteger, adParamInput, 4, m_pPlayer->GetAccountID() ) ); _variant_t vNull; vNull.vt=VT_ERROR; vNull.scode=DISP_E_PARAMNOTFOUND; _RecordsetPtr pRS = cmd->Execute(&vNull,&vNull,adCmdStoredProc); /* sid, -- ID account_id, -- 구매한 계정 ID avatar_id, -- 구매한 캐릭 ID ( -1 일경우홈피에서구매한것임) avatar_name, -- 구매한 캐릭 이름 ( -1 일경우홈피에서구매한것임) server_name, -- 구매한 서버 이름 item_code, -- 아이템코드 item_count, -- 구매한 아이템갯수 rest_item_count, -- 남은 아이템 갯수 bought_time, -- 구매시간 valid_time -- 유효시간( 제한없을경우-12-31 ) */ TS_SC_COMMERCIAL_STORAGE_LIST msg; TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo info; msg.count = 0; std::vector< TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo > vList; while( pRS->State != adStateClosed && !pRS->EndOfFile ) { info.commercial_item_uid = pRS->Fields->Item["sid"]->Value.intVal; info.code = pRS->Fields->Item["item_code"]->Value.intVal; info.count = pRS->Fields->Item["rest_item_count"]->Value.intVal; vList.push_back( info ); ++msg.count; msg.size += sizeof(info); pRS->MoveNext(); } char *pBuf = NULL; char szBuf[ SENDMSG_BUFFER_SIZE ] = ""; size_t buff_size = sizeof( szBuf ); if( sizeof(msg) + sizeof(info) * msg.count < SENDMSG_BUFFER_SIZE ) { pBuf = szBuf; } else { buff_size = sizeof(msg) + sizeof(info) * msg.count; pBuf = new char[ buff_size ]; } s_memcpy( pBuf, buff_size, &msg, sizeof(msg) ); if( msg.count ) s_memcpy( pBuf + sizeof(msg), buff_size - sizeof(msg), &*vList.begin(), sizeof(info) * msg.count ); PendStream( m_pPlayer, pBuf, msg.size ); if( pBuf != szBuf ) delete [] pBuf; LOG::Log11N4S( LM_READ_COMMERCIAL_STORAGE, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), msg.count, 0, 0, 0, 0, 0, 0, 0, 0, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); m_pPlayer->onEndQuery(); } catch( ... ) { throw; } return true; } void DB_ReadCommercialStorageList::onFail( const _com_error & exception ) { std::string strMessage( GameContent::GetString( 103 ) ); strMessage += "(2)"; SendChatMessage( false, CHAT_NOTICE, "@NOTICE", m_pPlayer, strMessage.c_str() ); m_pPlayer->onEndQuery(); } bool DB_TakeOutCommercialItem::onProcess( DBConnection & db ) { try { _CommandPtr cmd; if( db.CreateCommand( cmd ) == false ) throw XException( "DB_TakeOutCommercialItem : CreateInstance(command) error" ); cmd->CommandType = adCmdStoredProc; cmd->CommandText = _bstr_t( "dbo.smp_takeout_commercial_item" ); // Store the name of current stored-procedure for debugging szStoredProcedureName = "dbo.smp_takeout_commercial_item"; ItemUID item_uid = StructPlayer::allocItemUID(); LOG::Log11N4S( LM_TAKEOUT_TEMP_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, m_nCount, 0, 0, 0, 0, 0, 0, item_uid, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); cmd->Parameters->Append( cmd->CreateParameter( "RETURN_VALUE", adInteger, adParamReturnValue, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "OUT_ITEM_CODE", adInteger, adParamOutput, 4, 0 ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_CID", adInteger, adParamInput, 4, m_unItemCID ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_COUNT", adInteger, adParamInput, 4, m_nCount ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_ACCOUNT_ID", adInteger, adParamInput, 4, m_pPlayer->GetAccountID() ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_AVATAR_ID", adInteger, adParamInput, 4, m_pPlayer->GetPlayerUID() ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_AVATAR_NAME", adVarChar, adParamInput, 61, m_pPlayer->GetName() ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_SERVER_NAME", adVarChar, adParamInput, 30, ENV().GetString( "app.name", "Unknown" ).c_str() ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_SID", adBigInt, adParamInput, 8, item_uid ) ); cmd->Parameters->Append( cmd->CreateParameter( "IN_REMAIN_TIME", adInteger, adParamInput, 4, 0 ) ); _variant_t vNull; vNull.vt=VT_ERROR; vNull.scode=DISP_E_PARAMNOTFOUND; cmd->Execute(&vNull,&vNull,adCmdStoredProc); int nErrorCode = cmd->Parameters->Item[ "RETURN_VALUE" ]->Value; if( cmd->Parameters->Item[ "OUT_ITEM_CODE" ]->Value.vt != VT_NULL ) { int nItemCode = cmd->Parameters->Item[ "OUT_ITEM_CODE" ]->Value; if( nItemCode > 0 ) { SendResult( m_pPlayer, TM_CS_TAKEOUT_COMMERCIAL_ITEM, ERROR_SUCCESS, nItemCode ); ARCADIA_LOCK( ArcadiaServer::Instance().LockObjectWithVisibleRange( m_pPlayer ) ); if( StructItem::GetItemBase( nItemCode ).Flag.IsOn( ItemBase::FLAG_JOIN ) ) { StructItem *pNewItem = StructItem::AllocItem( item_uid, nItemCode, m_nCount, ItemInstance::BY_CASH ); StructItem *pResultItem = NULL; pResultItem = m_pPlayer->PushItem( pNewItem, pNewItem->GetCount() ); ItemUID uid = pResultItem->GetItemUID(); if( pNewItem != pResultItem ) { pNewItem->SetOwnerInfo( NULL, 0, 0 ); pNewItem->DBQuery( new DB_UpdateItemOwner( pNewItem ) ); StructItem::PendFreeItem( pNewItem ); pResultItem->DBQuery( new DB_UpdateItem( pResultItem ) ); } LOG::Log11N4S( LM_TAKEOUT_COMMERCIAL_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, nItemCode, m_nCount, nErrorCode, 0, 0, 0, 0, uid, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); } else { ItemUID last_uid = 0; for( __int64 i = 0; i < m_nCount; ++i ) { if( last_uid == item_uid ) { item_uid = StructPlayer::allocItemUID(); } // JOINABLE 아이템이 아닌경우 StructItem *pItem = NULL; StructItem *pNewItem = StructItem::AllocItem( item_uid, nItemCode, 1, ItemInstance::BY_CASH ); pItem = m_pPlayer->PushItem( pNewItem, pNewItem->GetCount() ); if( pItem ) { last_uid = pItem->GetItemUID(); pItem->DBQuery( new DB_UpdateItem( pItem ) ); } LOG::Log11N4S( LM_TAKEOUT_COMMERCIAL_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, nItemCode, 1, nErrorCode, 0, 0, 0, 0, last_uid, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); } } } else { LOG::Log11N4S( LM_TAKEOUT_COMMERCIAL_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, nItemCode, m_nCount, nErrorCode, 0, 0, 0, 0, 0, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); SendResult( m_pPlayer, TM_CS_TAKEOUT_COMMERCIAL_ITEM, ERROR_ACCESS_DENIED ); } } else { LOG::Log11N4S( LM_TAKEOUT_COMMERCIAL_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, 0, m_nCount, nErrorCode, 0, 0, 0, 0, 0, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); SendResult( m_pPlayer, TM_CS_TAKEOUT_COMMERCIAL_ITEM, ERROR_ACCESS_DENIED ); } m_pPlayer->onEndQuery(); } catch( ... ) { LOG::Log11N4S( LM_TAKEOUT_COMMERCIAL_ITEM, m_pPlayer->GetAccountID(), m_pPlayer->GetPlayerUID(), m_unItemCID, -1, -1, 0, 0, 0, 0, 0, 0, m_pPlayer->GetAccountName(), LOG::STR_NTS, m_pPlayer->GetName(), LOG::STR_NTS, "", 0, "", 0 ); throw; } return true; } void DB_TakeOutCommercialItem::onFail( const _com_error & exception ) { std::string strMessage( GameContent::GetString( 103 ) ); strMessage += "(3)"; SendChatMessage( false, CHAT_NOTICE, "@NOTICE", m_pPlayer, strMessage.c_str() ); m_pPlayer->onEndQuery(); }