void CExchangeGoods::ExchangeCancel(CPlayer *pDestPlayer, bool isSrc) { if (!pDestPlayer) return; CPlayer *pSrcPlayer = static_cast<CPlayer *>(this); if (!pSrcPlayer) return; // 交易取消,需要恢复被锁定的道具和金钱 for (int i=0; i<m_MyBox.m_SellNumber; i++) { SPackageItem &item = m_MyBox.m_GoodsArray[i]; SPackageItem *pItem = pSrcPlayer->FindItemByPos(item.wCellPos, XYD_FT_ONLYLOCK); if (!pItem) { rfalse(4, 1, "ExchangeGoods.cpp - ExchangeCancel() - !pItem"); return; } MY_ASSERT(pItem); pSrcPlayer->LockItemCell(pItem->wCellPos, false); } for (int i=0; i<m_YouBox.m_SellNumber; i++) { SPackageItem &item = m_YouBox.m_GoodsArray[i]; SPackageItem *pItem = pDestPlayer->FindItemByPos(item.wCellPos, XYD_FT_ONLYLOCK); if (!pItem) { rfalse(4, 1, "ExchangeGoods.cpp - ExchangeCancel() - !pItem"); return; } MY_ASSERT(pItem); pDestPlayer->LockItemCell(pItem->wCellPos, false); } // 清除当前的交易状态(包括了金钱的锁定) memset((CExchangeGoods *)pSrcPlayer, 0, sizeof(CExchangeGoods)); memset((CExchangeGoods *)pDestPlayer, 0, sizeof(CExchangeGoods)); // 通知客户端交易被取消 SAExchangeOperationMsg opmsg; opmsg.dwSrcGID = pSrcPlayer->GetGID(); opmsg.dwDestGID = pDestPlayer->GetGID(); opmsg.isSrc = isSrc; opmsg.operation = SAExchangeOperationMsg::CANCEL; g_StoreMessage(pSrcPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); g_StoreMessage(pDestPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); return; }
void CExchangeGoods::CommitExchange(CPlayer *pDestPlayer, bool isSrc, DWORD dwVerifyID4CardPoint) { if (!pDestPlayer) return; CPlayer *pSrcPlayer = static_cast<CPlayer *>(this); if (!pSrcPlayer) return; CPlayer *pPlayer = isSrc ? pSrcPlayer : pDestPlayer; SExchangeBox *pExchangeBox = isSrc ? &m_MyBox : &m_YouBox; if (!pPlayer || !pExchangeBox) { rfalse(4, 1, "ExchangeGoods.cpp - CommitExchange() - !pPlayer || !pExchangeBox"); return; } // 还没有确认 if (!(m_MyBox.m_bLocked && m_YouBox.m_bLocked)) { TalkToDnid(pPlayer->m_ClientIndex, "一方或双方没有锁定,无法提交交易"); return; } if (pExchangeBox->m_bCommit) return; pExchangeBox->m_bCommit = true; if (!(m_MyBox.m_bCommit && m_YouBox.m_bCommit)) { TalkToDnid(pPlayer->m_ClientIndex, "对方还没有提交,请等待"); // 通知交易双方,有一个人已经确认了 SAExchangeOperationMsg opmsg; opmsg.dwSrcGID = pSrcPlayer->GetGID(); opmsg.dwDestGID = pDestPlayer->GetGID(); opmsg.isSrc = isSrc; opmsg.operation = SAExchangeOperationMsg::COMMIT; g_StoreMessage(pSrcPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); g_StoreMessage(pDestPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); return; } // 双方都已确认,可以开始交易了,检测金钱的合法性 MY_ASSERT(pSrcPlayer->m_Property.m_Money >= m_MyBox.m_dwMoney); MY_ASSERT(pDestPlayer->m_Property.m_Money >= m_YouBox.m_dwMoney); if ((pSrcPlayer->m_Property.m_Money < m_MyBox.m_dwMoney) || (pDestPlayer->m_Property.m_Money < m_YouBox.m_dwMoney)) return; bool succeed = false; // 这里要确认他们至少交换过一个道具,或者一分钱 if (0 == m_MyBox.m_dwMoney && 0 == m_YouBox.m_dwMoney && !m_MyBox.m_SellNumber && !m_YouBox.m_SellNumber) goto goto_finish; else { // 检验交易发起方能否容纳金钱 DWORD canGet = 0xffffffff - pSrcPlayer->m_Property.m_Money + m_MyBox.m_dwMoney; if (canGet < m_YouBox.m_dwMoney) { TalkToDnid(pSrcPlayer->m_ClientIndex, "您钱包太满了!"); TalkToDnid(pDestPlayer->m_ClientIndex, "对方钱包太满了!"); // 交易发起方无法容纳金钱 pSrcPlayer->ExchangeCancel(pDestPlayer, isSrc); return; } // 检测交易目的方能否容纳金钱 canGet = 0xffffffff - pDestPlayer->m_Property.m_Money + m_YouBox.m_dwMoney; if (canGet < m_MyBox.m_dwMoney) { TalkToDnid(pSrcPlayer->m_ClientIndex, "对方钱包太满了!"); TalkToDnid(pDestPlayer->m_ClientIndex, "你钱包太满了!"); // 交易目的方无法容纳金钱 pSrcPlayer->ExchangeCancel(pDestPlayer, isSrc); return; } std::list<SAddItemInfo> itemList; // 检查交易目的玩家的背包状况 for (int i=0; i<m_YouBox.m_SellNumber; i++) itemList.push_back(SAddItemInfo(m_YouBox.m_GoodsArray[i].wIndex, m_YouBox.m_GoodsArray[i].overlap)); if (itemList.size() && !pSrcPlayer->CanAddItems(itemList, m_MyBox.m_SellNumber)) { // 交易发起方的背包无法满足交易目的道具 pSrcPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_SELF_PACKAGE_LACK); pDestPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_DEST_PACKAGE_LACK); pSrcPlayer->ExchangeCancel(pDestPlayer, isSrc); return; } itemList.clear(); for (int i=0; i<m_MyBox.m_SellNumber; i++) itemList.push_back(SAddItemInfo(m_MyBox.m_GoodsArray[i].wIndex, m_MyBox.m_GoodsArray[i].overlap)); if (itemList.size() && !pDestPlayer->CanAddItems(itemList, m_YouBox.m_SellNumber)) { // 交易目的的背包无法满足交易目的道具 pSrcPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_DEST_PACKAGE_LACK); pDestPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_SELF_PACKAGE_LACK); pSrcPlayer->ExchangeCancel(pDestPlayer, isSrc); return; } succeed = true; //背包检测成功,位置足够,可以开始交易,首先删除道具 for (int i=0; i<m_MyBox.m_SellNumber; i++) { SPackageItem *pItem = pSrcPlayer->FindItemByPos(m_MyBox.m_GoodsArray[i].wCellPos, XYD_FT_ONLYLOCK); if (!pItem) { rfalse(4, 1, "ExchangeGoods.cpp - CommitExchange() - !pItem - 2"); return; } MY_ASSERT(pItem); pSrcPlayer->DelItem(*pItem, "交易删除", true); } for (int i=0; i<m_YouBox.m_SellNumber; i++) { SPackageItem *pItem = pDestPlayer->FindItemByPos(m_YouBox.m_GoodsArray[i].wCellPos, XYD_FT_ONLYLOCK); if (!pItem) { rfalse(4, 1, "ExchangeGoods.cpp - CommitExchange() - !pItem"); return; } MY_ASSERT(pItem); pDestPlayer->DelItem(*pItem, "交易删除", true); } // 给交易发起方添加道具 for (int i=0; i<m_YouBox.m_SellNumber; i++) { const SItemBaseData *pData = CItemService::GetInstance().GetItemBaseData(m_YouBox.m_GoodsArray[i].wIndex); if (!pData) { rfalse(4, 1, "ExchangeGoods.cpp - CommitExchange() - !pData"); return; } MY_ASSERT(pData); WORD willCreate = pSrcPlayer->TryPossibleMerge(m_YouBox.m_GoodsArray[i].wIndex, m_YouBox.m_GoodsArray[i].overlap, pData->m_Overlay); pSrcPlayer->InsertItem(m_YouBox.m_GoodsArray[i].wIndex, willCreate, pData, m_YouBox.m_GoodsArray[i], false); } // 给交易目的放添加道具 for (int i=0; i<m_MyBox.m_SellNumber; i++) { const SItemBaseData *pData = CItemService::GetInstance().GetItemBaseData(m_MyBox.m_GoodsArray[i].wIndex); if (!pData) { rfalse(4, 1, "ExchangeGoods.cpp - CommitExchange() - !pData - 2"); } MY_ASSERT(pData); WORD willCreate = pDestPlayer->TryPossibleMerge(m_MyBox.m_GoodsArray[i].wIndex, m_MyBox.m_GoodsArray[i].overlap, pData->m_Overlay); pDestPlayer->InsertItem(m_MyBox.m_GoodsArray[i].wIndex, willCreate, pData, m_MyBox.m_GoodsArray[i], false); } if (m_MyBox.m_dwMoney || m_YouBox.m_dwMoney) { pSrcPlayer->m_Property.m_Money -= m_MyBox.m_dwMoney; pDestPlayer->m_Property.m_Money -= m_YouBox.m_dwMoney; pSrcPlayer->m_Property.m_Money += m_YouBox.m_dwMoney; pDestPlayer->m_Property.m_Money += m_MyBox.m_dwMoney; pSrcPlayer->m_PlayerPropertyStatus[XA_UNBIND_MONEY-XA_MAX_EXP] = true; pDestPlayer->m_PlayerPropertyStatus[XA_UNBIND_MONEY-XA_MAX_EXP] = true; } } goto_finish: // 交易完成,清除当前的交易状态 memset((CExchangeGoods*)pSrcPlayer, 0, sizeof(CExchangeGoods)); memset((CExchangeGoods*)pDestPlayer, 0, sizeof(CExchangeGoods)); // 通知客户端交易成功完成,可以关闭交易窗口了 SAExchangeOperationMsg opmsg; opmsg.dwSrcGID = pSrcPlayer->GetGID(); opmsg.dwDestGID = pDestPlayer->GetGID(); opmsg.isSrc = isSrc; opmsg.operation = SAExchangeOperationMsg::SUCCEED; g_StoreMessage(pSrcPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); g_StoreMessage(pDestPlayer->m_ClientIndex, &opmsg, sizeof(SAExchangeOperationMsg)); //发送交易成功后保存数据 if (!succeed) return; // 保存玩家道具 SPackageItem *pItems = pSrcPlayer->m_Property.m_BaseGoods; memset(pItems, 0, PackageAllCells * sizeof(SPackageItem)); for (DWORD i = 0; i < PackageAllCells; i++, pItems++) { SPackageItem *curItem = pSrcPlayer->FindItemByPos(i, XYD_FT_WHATEVER); if (curItem) *pItems = *curItem; } SPackageItem *pdestItems = pDestPlayer->m_Property.m_BaseGoods; memset(pdestItems, 0, PackageAllCells * sizeof(SPackageItem)); for (DWORD i = 0; i < PackageAllCells; i++, pdestItems++) { SPackageItem *curItem = pDestPlayer->FindItemByPos(i, XYD_FT_WHATEVER); if (curItem) *pdestItems = *curItem; } SDoubleSavePlayerMsg sdsavemsg; dwt::strcpy(sdsavemsg.account[0],pSrcPlayer->GetAccount(),MAX_ACCOUNT); dwt::strcpy(sdsavemsg.account[1],pDestPlayer->GetAccount(),MAX_ACCOUNT); sdsavemsg.gid[0] = pSrcPlayer->GetGID(); sdsavemsg.gid[1] = pDestPlayer->GetGID(); SFixProperty *pSreData = dynamic_cast<SFixProperty *>(&pSrcPlayer->m_Property); SFixProperty *pDestData =dynamic_cast<SFixProperty *>(&pDestPlayer->m_Property); memcpy(&sdsavemsg.data[0],pSreData,sizeof(SFixProperty)); memcpy(&sdsavemsg.data[1],pDestData,sizeof(SFixProperty)); int num = SectionMessageManager::getInstance().evaluateDevidedAmount(sizeof(sdsavemsg)); int id = 0; BOOL ret; for (int i = 0;i < num;i++) { SSectionMsg sMsg; id = SectionMessageManager::getInstance().devideMessage(i,num,&sMsg,&sdsavemsg,sizeof(sdsavemsg),id); ret = SendToLoginServer(&sMsg,sizeof(SSectionMsg)); } //SectionMessageManager::getInstance(). //SendToLoginServer(&sdsavemsg,sizeof(SDoubleSavePlayerMsg)); // g_StoreMessage(pSrcPlayer->m_ClientIndex,&sdsavemsg,sizeof(SDoubleSavePlayerMsg)); return; }
void CExchangeGoods::PutItemToExchangeBox(CPlayer *pDestPlayer, SPackageItem &item, WORD wDestX, WORD wDestY, bool isSrc) { if (!pDestPlayer) { rfalse(4, 1, "ExchangeGoods.cpp - PutItemToExchangeBox() - !pDestPlayer"); return; } CPlayer *pSrcPlayer = static_cast<CPlayer *>(this); if (!pSrcPlayer) return; CPlayer *pPlayer = isSrc ? pSrcPlayer : pDestPlayer; SExchangeBox *pExchangeBox = isSrc ? &m_MyBox : &m_YouBox; if (!pExchangeBox) { rfalse(4, 1, "ExchangeGoods.cpp - PutItemToExchangeBox() - !pExchangeBox"); return; } // 如果已锁定或者已提交,则无法继续添加道具 if (pExchangeBox->m_bLocked || pExchangeBox->m_bCommit) { pPlayer->SendStatusMsg(pExchangeBox->m_bLocked ? SANotifyStatus::NS_EXT_ALREADY_IN_LOCK : SANotifyStatus::NS_EXT_ALREADY_IN_COMMIT); return; } SAPutItemToExchangeBoxMsg msg; msg.dwSrcGID = pSrcPlayer->GetGID(); msg.dwDestGID = pDestPlayer->GetGID(); msg.isSrc = isSrc; msg.wCellX = wDestX; msg.wCellY = wDestY; msg.Item = item; bool bSuccess = false; // 是否是交易金钱 if (0xffff == item.wIndex) { if (0 == item.details.uniqueTimestamp || item.details.uniqueTimestamp > 99999999) { pPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_MONEY_INVALID); return; } if (item.details.uniqueTimestamp > pPlayer->m_Property.m_Money) return; // 通过检测,更新交易状态 pExchangeBox->m_dwMoney = item.details.uniqueTimestamp; pPlayer->m_IsMoneyLocked = true; // 此处锁定金钱 bSuccess = true; } else { // 判定目标道具的存在性 SPackageItem *pItem = pPlayer->FindItemByPos(item.wCellPos, XYD_FT_ONLYUNLOCK); if (!pItem || pItem->wIndex != msg.Item.wIndex) return; const SItemBaseData *pItemData = CItemService::GetInstance().GetItemBaseData(item.wIndex); if (!pItemData || ITEM_IS_TASK(pItemData->m_Type)) // 任务道具不可交易 return; // 判定道具是否可以被交易 if (!pItemData->m_CanTran) { TalkToDnid(pPlayer->m_ClientIndex, "该道具无法被交易!"); pPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_ITEM_CANTEXG); return; } if (item.IsBindState()) { TalkToDnid(pPlayer->m_ClientIndex, "该道具已绑定,不能被交易。"); pPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_ITEM_BIND); return ; } // 交易栏是否足够 if (MAX_EXCHANGE_ITEM_NUMBER == pExchangeBox->m_SellNumber) { TalkToDnid(pPlayer->m_ClientIndex, "交易栏已满!"); pPlayer->SendStatusMsg(SANotifyStatus::NS_EXT_EXTBOX_FULL); return; } SPackageItem *const pTempItem = &pExchangeBox->m_GoodsArray[pExchangeBox->m_SellNumber]; *pTempItem = *pItem; msg.wCellX = pExchangeBox->m_SellNumber / 5; msg.wCellY = pExchangeBox->m_SellNumber % 5; msg.Item = *pItem; pExchangeBox->m_SellNumber++; bSuccess = true; pPlayer->LockItemCell(item.wCellPos, true); } if (bSuccess) { g_StoreMessage(pSrcPlayer->m_ClientIndex, &msg, sizeof(SAPutItemToExchangeBoxMsg)); g_StoreMessage(pDestPlayer->m_ClientIndex, &msg, sizeof(SAPutItemToExchangeBoxMsg)); } }