#include "StdAfx.h" #include ".\trademanager.h" #include ".\TradeSlot.h" #include ".\Player.h" #include ".\ItemManager.h" #include ".\SCItemSlotContainer.h" #include #include ".\TradeSlotContainer.h" #include "GameServerEx.h" #include "FunctionalRestrictManager.h" #include "ChaoState.h" TradeManager g_TradeManager; TradeManager::TradeManager(void) { } TradeManager::~TradeManager(void) { Release(); } VOID TradeManager::Init( DWORD maxPoolSize ) { m_TradeKey = 0; m_pTradePool.Initialize( maxPoolSize, 0, "TradeSlotContainer", AssertionLogger4Pool_Server ); } VOID TradeManager::Release() { m_pTradePool.Release(); } RC::eTRADE_RESULT TradeManager::StartTrade( Player * pRequester, Player * pAcceptor ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pRequester->GetChaoState().IsChaoState() || pAcceptor->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( pRequester->GetBehave() != PLAYER_BEHAVE_IDLE_STATE || pAcceptor->GetBehave() != PLAYER_BEHAVE_IDLE_STATE ) return RC::RC_TRADE_INVALID_STATE; BOOL bEnabled = FALSE; bEnabled = pRequester->GetItemManager()->ValidContainer( SI_INVENTORY ); if( !bEnabled ) { ProtectorInventory& rPROTECT = pRequester->GetWarehouseInventoryProtector().INVENTORY(); if( !rPROTECT.IsUsable() ) return RC::RC_TRADE_INVENTORY_NEED_PASSWORD; return RC::RC_TRADE_INVALID_STATE; } bEnabled = pAcceptor->GetItemManager()->ValidContainer( SI_INVENTORY ); if( !bEnabled ) { ProtectorInventory& rPROTECT = pAcceptor->GetWarehouseInventoryProtector().INVENTORY(); if( !rPROTECT.IsUsable() ) return RC::RC_TRADE_INVENTORY_NEED_PASSWORD; return RC::RC_TRADE_INVALID_STATE; } TradeSlotContainer * pReq_Container = _ALLOC(); if( !pReq_Container ) return RC::RC_TRADE_INVALID_STATE; TradeSlotContainer * pAcpt_Container = _ALLOC(); if( !pAcpt_Container ) { SUNLOG( eCRITICAL_LOG, "不能派发交易集装箱." ); if( !_FREE(pReq_Container) ) { SUNLOG( eCRITICAL_LOG, "交易池返还失败0[%s][%s]", pRequester->GetCharName(), pAcceptor->GetCharName() ); } return RC::RC_TRADE_INVALID_STATE; } DWORD gen_key = ++m_TradeKey; pReq_Container->Init( pRequester, pAcceptor, gen_key ); pAcpt_Container->Init( pAcceptor, pRequester, gen_key ); pRequester->SetTradeContainer( pReq_Container ); pAcceptor->SetTradeContainer( pAcpt_Container ); pRequester->SetBehave(PLAYER_BEHAVE_TRADE_STATE); pAcceptor->SetBehave(PLAYER_BEHAVE_TRADE_STATE); SUNLOG( eFULL_LOG, "交易开始[%s][%s]", pRequester->GetCharName(), pAcceptor->GetCharName() ); return RC::RC_TRADE_SUCCESS; } __inline BOOL TradeManager::_FREE( TradeSlotContainer* pUnit ) { ASSERT(pUnit); FlowControl flow; FLOWCONTROL_START() { IfFailThenBreak(pUnit, 10); TEST_HASH::iterator it = m_TestHash.find(pUnit); IfFailThenBreak(it != m_TestHash.end(), 20); //Player* pPlayer1 = pUnit->GetPlayer(); //Player* pPlayer2 = pUnit->GetCounterPlayer(); m_TestHash.erase(it); return m_pTradePool.Free(pUnit); } FLOWCONTROL_END; switch( flow.GetErrorCode() ) { case 10: case 20: { Player* pPlayer1 = pUnit->GetPlayer(); Player* pPlayer2 = pUnit->GetCounterPlayer(); const TCHAR* pErrorStr = flow.GetErrorCode() == 10 ? _T("Invalid Release Ptr") : flow.GetErrorCode() == 20 ? _T("TRADE 已返回相同地址的内存") : NULL; SUNLOG( eCRITICAL_LOG, _T("[%s:%d][%s:%d] %s PTR(0x%p)"), pPlayer1->GetCharName(), pPlayer1->GetBehave(), pPlayer2->GetCharName(), pPlayer2->GetBehave(), pErrorStr, pUnit ); } break; } return FALSE; } RC::eTRADE_RESULT TradeManager::EndTrade( Player * pRequester ) { if( pRequester->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( pRequester->GetBehave() != PLAYER_BEHAVE_TRADE_STATE ) return RC::RC_TRADE_INVALID_STATE; ASSERT( pRequester->GetTradeContainer() ); Player * pPlayer2 = pRequester->GetTradeContainer()->GetCounterPlayer(); ASSERT( pPlayer2->GetBehave() == PLAYER_BEHAVE_TRADE_STATE ); if( pPlayer2->GetBehave() != PLAYER_BEHAVE_TRADE_STATE ) { SUNLOG( eCRITICAL_LOG, "EndTrade()[p2:%s:%d]状态异常", pPlayer2->GetCharName(), pPlayer2->GetBehave() ); pRequester->GetTradeContainer()->ClearAll(); if( !_FREE(pRequester->GetTradeContainer()) ) { SUNLOG( eCRITICAL_LOG, "EndTrade()P1交易池返还失败[P1:%s][P2:%s:%d]", pRequester->GetCharName(), pPlayer2->GetCharName(), pPlayer2->GetBehave() ); } pRequester->SetTradeContainer( NULL ); pRequester->SetBehave(PLAYER_BEHAVE_IDLE_STATE); return RC::RC_TRADE_INVALID_STATE; } pRequester->GetTradeContainer()->ClearAll(); pPlayer2->GetTradeContainer()->ClearAll(); if( !_FREE(pRequester->GetTradeContainer()) ) { SUNLOG( eCRITICAL_LOG, "交易池返还失败2[%s][%s]", pRequester->GetCharName(), pPlayer2->GetCharName() ); } if( !_FREE(pPlayer2->GetTradeContainer()) ) { SUNLOG( eCRITICAL_LOG, "交易池返还失败3[%s][%s]", pRequester->GetCharName(), pPlayer2->GetCharName() ); } pRequester->SetTradeContainer( NULL ); pPlayer2->SetTradeContainer( NULL ); pRequester->SetBehave(PLAYER_BEHAVE_IDLE_STATE); pPlayer2->SetBehave(PLAYER_BEHAVE_IDLE_STATE); SUNLOG( eFULL_LOG, "交易结束[%s][%s]", pRequester->GetCharName(), pPlayer2->GetCharName() ); return RC::RC_TRADE_SUCCESS; } BOOL TradeManager::ValidTradeState( Player * pPlayer ) { if( pPlayer->IsExpiredPlayer() || pPlayer->GetBehave() != PLAYER_BEHAVE_TRADE_STATE ) return FALSE; Player * pPlayer2 = pPlayer->GetTradeContainer()->GetCounterPlayer(); if( pPlayer2->IsExpiredPlayer() || pPlayer2->GetBehave() != PLAYER_BEHAVE_TRADE_STATE ) return FALSE; return TRUE; } RC::eTRADE_RESULT TradeManager::PutItem( Player * pPlayer, POSTYPE org_pos, POSTYPE & OUT trade_pos_out, RENDER_ITEMSTREAMEX & OUT trade_stream_out ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_INVALID_STATE; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() != TRADE_READY ) return RC::RC_TRADE_FAILED; SCSlotContainer * pInventoryContainer = pPlayer->GetItemManager()->GetItemSlotContainer(SI_INVENTORY); if( !pInventoryContainer->ValidPos( org_pos ) || pInventoryContainer->IsEmpty( org_pos ) || pInventoryContainer->IsLocked( org_pos ) ) return RC::RC_TRADE_FAILED; SCItemSlot & rSlot = (SCItemSlot &)pInventoryContainer->GetSlot( org_pos ); // (CHANGES) change to more generic code 'IsPetLocked' & 'IsRiderLocked' ... if(rSlot.IsUserBlocked()) return RC::RC_TRADE_CANNOT_TRADE_ITEM; if( rSlot.GetLaxLock()->IsLock() ) { //SUNLOG( eCRITICAL_LOG, "Can not Trade - LaxLock"); return RC::RC_TRADE_CANNOT_TRADE_ITEM; } if (rSlot.IsPossessionItem() && rSlot.GetIdentifyPossession() && (!rSlot.IsDestroyItem())) { return RC::RC_TRADE_CANNOT_TRADE_ITEM; } #ifdef _NA_20101208_SET_PROGRESSTIME_ITEM_IS_NOT_TRADE if(rSlot.IsProgressTime()) return RC::RC_TRADE_CANNOT_TRADE_ITEM; #endif if (rSlot.CanTradeSell(eITEM_TRADESELL_TRADE) == false) { return RC::RC_TRADE_CANNOT_TRADE_ITEM; } if (rSlot.CanTradeSell(eITEM_TRADESELL_USED_ITEM) == false && rSlot.IsProgressTime()) { return RC::RC_TRADE_CANNOT_TRADE_ITEM; } if( !pContainer->PutItem( rSlot, trade_pos_out ) ) return RC::RC_TRADE_FAILED; ((SCItemSlot &)rSlot).CopyOut( trade_stream_out ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::GetItem( Player * pPlayer, POSTYPE trade_pos ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() != TRADE_READY ) return RC::RC_TRADE_FAILED; if( !pContainer->ValidPos( trade_pos ) || pContainer->IsEmpty(trade_pos ) ) return RC::RC_TRADE_FAILED; pContainer->DeleteSlot( trade_pos, NULL ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::PutMoney( Player * pPlayer, MONEY & IN money ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() != TRADE_READY ) return RC::RC_TRADE_FAILED; if( pPlayer->GetMoney() < money ) return RC::RC_TRADE_FAILED; pContainer->SetMoney( money ); Player * pPartner = pContainer->GetCounterPlayer(); GAMELOG->LogMoney( MONEY_TRADE_PUT_PRICE, pPlayer, money, pContainer->GetMoney(), pPartner->GetUserID(), pPartner->GetCharName() ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::GetMoney( Player * pPlayer, MONEY & IN money ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() != TRADE_READY ) return RC::RC_TRADE_FAILED; if( pContainer->GetMoney() < money ) return RC::RC_TRADE_FAILED; pContainer->SetMoney( (pContainer->GetMoney() - money) ); Player * pPartner = pContainer->GetCounterPlayer(); GAMELOG->LogMoney( MONEY_TRADE_GET_PRICE, pPlayer, money, pContainer->GetMoney(), pPartner->GetUserID(), pPartner->GetCharName() ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::Proposal( Player * pPlayer ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() != TRADE_READY ) return RC::RC_TRADE_FAILED; pContainer->SetTradeState( TRADE_PROPOSAL ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::Modify( Player * pPlayer ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pPlayer->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pPlayer) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pContainer = pPlayer->GetTradeContainer(); if( pContainer->GetTradeState() == TRADE_READY ) return RC::RC_TRADE_FAILED; Player * pPlayer2 = PlayerManager::Instance()->FindPlayerByUserKey( pContainer->GetCounterPlayer()->GetUserKey() ); if( !pPlayer2 ) { SUNLOG( eCRITICAL_LOG, "[TradeManager::Modify] pPartner[%d] doesn't exist!", pContainer->GetCounterPlayer()->GetUserKey() ); return RC::RC_TRADE_INVALID_STATE; } TradeSlotContainer * pContainer2 = pPlayer2->GetTradeContainer(); switch( pContainer2->GetTradeState() ) { case TRADE_ACCEPT: { pContainer2->SetTradeState(TRADE_PROPOSAL); }break; } pContainer->SetTradeState( TRADE_READY ); return RC::RC_TRADE_SUCCESS; } RC::eTRADE_RESULT TradeManager::Exchange( Player * pMyself, TRADE_TOTAL_INFO & OUT rTradeInfo1, MONEY & OUT money1, TRADE_TOTAL_INFO & OUT rTradeInfo2, MONEY & OUT money2 ) { if( g_FunctionalRestrictMgr.IsRestrictFunction( eFUNCTIONALRESTRICT_USE_TRADE ) ) return RC::RC_TRADE_NOT_AVAILABLE_SERVICE; if( pMyself->GetChaoState().IsChaoState() ) return RC::RC_TRADE_UNABLE_FUNCTION_FOR_CHAOSTATE; if( !ValidTradeState(pMyself) ) return RC::RC_TRADE_CANCEL; TradeSlotContainer * pMyContainer = pMyself->GetTradeContainer(); Player * pPartner = PlayerManager::Instance()->FindPlayerByUserKey( pMyContainer->GetCounterPlayer()->GetUserKey() ); if( !pPartner ) { SUNLOG( eCRITICAL_LOG, "[TradeManager::Exchange] pPartner[%d] doesn't exist!", pMyContainer->GetCounterPlayer()->GetUserKey() ); return RC::RC_TRADE_INVALID_STATE; } TradeSlotContainer * pPartnerContainer = pPartner->GetTradeContainer(); switch ( pMyContainer->GetTradeState() ) { case TRADE_PROPOSAL: break; default: return RC::RC_TRADE_INVALID_STATE; } switch ( pPartnerContainer->GetTradeState() ) { case TRADE_READY: return RC::RC_TRADE_INVALID_STATE; case TRADE_PROPOSAL: pMyContainer->SetTradeState(TRADE_ACCEPT); return RC::RC_TRADE_COUNTERPARTNER_NOTACCEPT; } //SUNLOG( eFULL_LOG, "Exchange启动1[%s][%s]", pMyself->GetCharName(), pPartner->GetCharName() ); pMyContainer->SetTradeState(TRADE_ACCEPT); SCSlotContainer * pInventory1 = pMyself->GetItemManager()->GetItemSlotContainer(SI_INVENTORY); SCSlotContainer * pInventory2 = pPartner->GetItemManager()->GetItemSlotContainer(SI_INVENTORY); #if SUN_CODE_BACKUP SCSlotContainer * pTemporary1 = pMyself->GetItemManager()->GetItemSlotContainer(SI_TEMPINVENTORY); SCSlotContainer * pTemporary2 = pPartner->GetItemManager()->GetItemSlotContainer(SI_TEMPINVENTORY); #endif if( pInventory1->GetEmptySlotNum() < pPartnerContainer->GetSlotNum() ) { return RC::RC_TRADE_PLAYER1_HAVENOTSPACE; } if( pInventory2->GetEmptySlotNum() < pMyContainer->GetSlotNum() ) { return RC::RC_TRADE_PLAYER1_HAVENOTSPACE; } if( pMyself->GetMoney() < pMyContainer->GetMoney() ) return RC::RC_TRADE_PLAYER1_HAVENOTMONEY; if( pPartner->GetMoney() < pPartnerContainer->GetMoney() ) return RC::RC_TRADE_PLAYER2_HAVENOTMONEY; if( !pMyself->CanPlusMoney( pPartnerContainer->GetMoney() ) ) return RC::RC_TRADE_FAILED; if( !pPartner->CanPlusMoney( pMyContainer->GetMoney() ) ) return RC::RC_TRADE_FAILED; //SUNLOG( eFULL_LOG, "Exchange启动2[%s][%s]", pMyself->GetCharName(), pPartner->GetCharName() ); TradeSlot * pMyTradeSlot[MAX_TRADE_SLOT_NUM>>1] = {NULL, }; POSTYPE MyTradeItemNum = 0; for( int i = pMyContainer->GetMaxSlotNum()-1 ; i >= 0 ; --i ) { if( !pMyContainer->IsEmpty(i) ) { TradeSlot & rTradeSlot = (TradeSlot &)pMyContainer->GetSlot(i); if( rTradeSlot.GetLinkItem()->GetNum() != rTradeSlot.GetNum() ) { return RC::RC_TRADE_DIFFERENT_ITEM_INFO; } pMyTradeSlot[MyTradeItemNum++] = &rTradeSlot; } } TradeSlot * pPartnerTradeSlot[MAX_TRADE_SLOT_NUM>>1] = {NULL, }; POSTYPE PartnerTradeItemNum = 0; for( int i = pPartnerContainer->GetMaxSlotNum()-1 ; i >= 0 ; --i ) { if( !pPartnerContainer->IsEmpty(i) ) { TradeSlot & rTradeSlot = (TradeSlot &)pPartnerContainer->GetSlot(i); if( rTradeSlot.GetLinkItem()->GetNum() != rTradeSlot.GetNum() ) { return RC::RC_TRADE_DIFFERENT_ITEM_INFO; } pPartnerTradeSlot[PartnerTradeItemNum++] = &rTradeSlot; } } rTradeInfo2.m_InvenCount = 0; rTradeInfo2.m_TmpInvenCount = 0; POSTYPE RemainNum = MyTradeItemNum; _GiveItem( pInventory2, pMyTradeSlot, RemainNum, &rTradeInfo2.m_Slot[0], rTradeInfo2.m_InvenCount ); #if SUN_CODE_BACKUP if( RemainNum != 0 ) _GiveItem( pTemporary2, pMyTradeSlot, RemainNum, &rTradeInfo2.m_Slot[rTradeInfo2.m_InvenCount], rTradeInfo2.m_TmpInvenCount ); #endif for(int i = 0 ; i < MyTradeItemNum ; ++i ) { SCItemSlot* pItemSlot = pMyTradeSlot[i]->GetLinkItem(); ASSERT( pItemSlot ); if( !pItemSlot ) continue; GAMELOG->LogItem( ITEM_TRADE_GIVE, pMyself, pItemSlot, 0, pItemSlot->GetNum(), pPartner->GetUserID(), pPartner->GetCharName() ); GAMELOG->LogItem( ITEM_TRADE_RECEIVE, pPartner, pItemSlot, 0, pItemSlot->GetNum(), pMyself->GetUserID(), pMyself->GetCharName() ); } rTradeInfo1.m_InvenCount = 0; rTradeInfo1.m_TmpInvenCount = 0; RemainNum = PartnerTradeItemNum; _GiveItem( pInventory1, pPartnerTradeSlot, RemainNum, &rTradeInfo1.m_Slot[0], rTradeInfo1.m_InvenCount ); #if SUN_CODE_BACKUP if( RemainNum != 0 ) _GiveItem( pTemporary1, pPartnerTradeSlot, RemainNum, &rTradeInfo1.m_Slot[rTradeInfo1.m_InvenCount], rTradeInfo1.m_TmpInvenCount ); #endif for(int i = 0 ; i < PartnerTradeItemNum ; ++i ) { SCItemSlot* pItemSlot = pPartnerTradeSlot[i]->GetLinkItem(); ASSERT(pItemSlot); if( !pItemSlot ) continue; GAMELOG->LogItem( ITEM_TRADE_GIVE, pPartner, pItemSlot, 0, pItemSlot->GetNum(), pMyself->GetUserID(), pMyself->GetCharName() ); GAMELOG->LogItem( ITEM_TRADE_RECEIVE, pMyself, pItemSlot, 0, pItemSlot->GetNum(), pPartner->GetUserID(), pPartner->GetCharName() ); } for( POSTYPE i = 0 ; i < (MAX_TRADE_SLOT_NUM>>1) ; ++i ) { if( !pMyContainer->IsEmpty(i) ) pInventory1->DeleteSlot( ((TradeSlot &)pMyContainer->GetSlot(i)).GetLinkItem()->GetPos(), NULL ); if( !pPartnerContainer->IsEmpty(i) ) pInventory2->DeleteSlot( ((TradeSlot &)pPartnerContainer->GetSlot(i)).GetLinkItem()->GetPos(), NULL ); } pMyself->MinusMoney( pMyContainer->GetMoney(), Player::eMONEY_CIRCULATING ); pMyself->PlusMoney( pPartnerContainer->GetMoney(), Player::eMONEY_CIRCULATING ); pPartner->MinusMoney( pPartnerContainer->GetMoney(), Player::eMONEY_CIRCULATING ); pPartner->PlusMoney( pMyContainer->GetMoney(), Player::eMONEY_CIRCULATING ); if( pPartnerContainer->GetMoney() + pMyContainer->GetMoney() > 0 ) { GAMELOG->LogMoney( MONEY_TRADE, pMyself, pMyContainer->GetMoney(), pPartnerContainer->GetMoney(), pPartner->GetUserID(), pPartner->GetCharName() ); GAMELOG->LogMoney( MONEY_TRADE, pPartner, pPartnerContainer->GetMoney(), pMyContainer->GetMoney(), pMyself->GetUserID(), pMyself->GetCharName() ); } money1 = pMyself->GetMoney(); money2 = pPartner->GetMoney(); pMyContainer->ClearAll(); pPartnerContainer->ClearAll(); return RC::RC_TRADE_SUCCESS; } VOID TradeManager::_GiveItem( SCSlotContainer * pContainer, TradeSlot ** ppSlot, POSTYPE & INOUT num, TRADE_TOTAL_INFO::SLOT_TYPE * OUT rItemSlot, POSTYPE & OUT Count ) { for( POSTYPE pos = 0 ; pos < pContainer->GetMaxSlotNum() && (num != 0) ; ++pos ) { if( pContainer->IsEmpty(pos) ) { if( num == 0 ) { SUNLOG(eCRITICAL_LOG, "[Error]Trade Num == 0" ); return; } --num; rItemSlot[Count].m_Pos = pos; ppSlot[num]->GetLinkItem()->SetLock(FALSE); ppSlot[num]->GetLinkItem()->CopyOut( rItemSlot[Count].m_Stream ); pContainer->InsertSlot(pos, *(ppSlot[num]->GetLinkItem()) ); ++Count; } } }