Reklam
void CUser::MerchantItemBuy(Packet& pkt)
{
uint32 itemid, req_gold;
uint16 item_count, leftover_count;
uint8 item_slot, dest_slot;
Packet result(WIZ_MERCHANT);
if (m_sMerchantsSocketID < MAX_USER)
{
CUser* pMerchUser = g_pMain->GetUserPtr(m_sMerchantsSocketID);
if (!pMerchUser)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerchUser->GetSocketID() == GetSocketID() || pMerchUser->GetAccountName() == GetAccountName())
return goDisconnect("trying to buy parts from its own market.", __FUNCTION__);
if (!isInGame() || isDead() || isMining() || isFishing()
/*|| isStoreOpen()*/
|| isMerchanting() || isSellingMerchantingPreparing()
|| isBuyingMerchant() || m_sMerchantsSocketID < 0
|| m_sMerchantsSocketID > MAX_USER || isTrading())
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (!isInRange(pMerchUser, 35.0f) || !pMerchUser->isMerchanting() || pMerchUser->isSellingMerchantingPreparing()
|| pMerchUser->GetMerchantState() != MERCHANT_STATE_SELLING)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
pkt >> itemid >> item_count >> item_slot >> dest_slot;
if (item_slot >= MAX_MERCH_ITEMS || dest_slot >= HAVE_MAX || !item_count)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
// Grab pointers to the items.
_MERCH_DATA* pMerch = &pMerchUser->m_arMerchantItems[item_slot];
if (pMerch == nullptr || pMerch->IsSoldOut || !pMerch->sCount || !pMerch->nPrice)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
_ITEM_DATA* pBuyerItem = GetItem(SLOT_MAX + dest_slot);
if (pBuyerItem == nullptr)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
_ITEM_DATA* pSellerItem = pMerchUser->GetItem(pMerch->bOriginalSlot);
if (pSellerItem == nullptr || pSellerItem->nNum != pMerch->nNum
|| !pSellerItem->isMerchantItem() || pSellerItem->sCount < item_count
|| !pSellerItem->sCount)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerch->nNum != itemid || pMerch->sCount < item_count || pMerch->orgcount < item_count)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
_ITEM_TABLE pSellingItem = g_pMain->GetItemPtr(itemid);
if (pSellingItem.isnull() || (!pSellingItem.m_bCountable && item_count != 1))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pSellingItem.m_bKind == 255 && item_count != 1 && !pSellingItem.m_bCountable)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
uint32 nReqWeight = pSellingItem.m_sWeight * item_count;
if ((nReqWeight + m_sItemWeight > m_sMaxWeight))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pBuyerItem->nNum != 0 && (pBuyerItem->nNum != itemid || !pSellingItem.m_bCountable))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
int8 PosXZ = FindSlotForItem(pMerch->nNum, pMerch->sCount);
if (PosXZ < 0)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
// Do we have enough coins?
req_gold = pMerch->nPrice * item_count;
if (pMerch->isKC)
{
if (m_nKnightCash < req_gold)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
}
else
{
if (m_iGold < req_gold)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
}
if (pMerchUser && pMerchUser->m_iGold + req_gold > COIN_MAX)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerch->isKC)
{
if (!CashLose(req_gold))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerchUser) pMerchUser->CashGain(req_gold);
}
else
{
if (!GoldLose(req_gold))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerchUser) pMerchUser->GoldGain(req_gold);
}
if (!pMerch->isKC)
pMerchUser->pUserDailyRank.GMTotalSold += req_gold;
leftover_count = pMerch->sCount - item_count;
pBuyerItem->sCount += item_count;
SendStackChange(itemid, pBuyerItem->sCount, pBuyerItem->sDuration, dest_slot, (pBuyerItem->sCount == item_count)); // is it a new item?
pMerch->sCount -= item_count;
pSellerItem->sCount -= item_count;
uint64 serial = pSellerItem->nSerialNum;
if (!serial) serial = g_pMain->GenerateItemSerial();
if (pSellingItem.isStackable())
{
if (!pSellerItem->sCount && !pBuyerItem->nNum)
pBuyerItem->nSerialNum = serial;
else if (!pBuyerItem->nNum)
pBuyerItem->nSerialNum = g_pMain->GenerateItemSerial();
}
else pBuyerItem->nSerialNum = serial;
pBuyerItem->nNum = pMerch->nNum;
pBuyerItem->sDuration = pMerch->sDuration;
if (!pSellingItem.isStackable() || item_count == pMerch->sCount) pBuyerItem->nSerialNum = pSellerItem->nSerialNum;
if (!pSellingItem.isStackable() && pBuyerItem->nSerialNum == 0) pBuyerItem->nSerialNum = g_pMain->GenerateItemSerial();
pBuyerItem->MerchItem = false;
MerchantShoppingDetailInsertLog(false, 1, itemid, item_count, pMerch->nPrice, pMerchUser);
if (!pSellerItem->sCount || (pSellingItem.m_bKind == 255 && pSellingItem.m_bCountable == 0)) memset(pSellerItem, 0, sizeof(_ITEM_DATA));
pMerchUser->SendStackChange(pSellerItem->nNum, pSellerItem->sCount, pSellerItem->sDuration, pMerch->bOriginalSlot - SLOT_MAX);
if (!pMerch->sCount || (pSellingItem.m_bCountable == 0 && pSellingItem.m_bKind == 255)) { memset(pMerch, 0, sizeof(_MERCH_DATA)); pMerch->IsSoldOut = true; }
result.clear();
result.Initialize(WIZ_MERCHANT);
result << uint8(MERCHANT_ITEM_PURCHASED) << itemid << GetName();
pMerchUser->Send(&result);
result.clear();
result.Initialize(WIZ_MERCHANT);
result << uint8(MERCHANT_ITEM_BUY) << uint16(1)
<< itemid << leftover_count
<< item_slot << dest_slot;
Send(&result);
if (item_slot < 4 && leftover_count == 0)
{
result.clear();
result.Initialize(WIZ_MERCHANT_INOUT);
result << uint8(2) << m_sMerchantsSocketID << uint8(1) << uint8(0) << item_slot;
pMerchUser->SendToRegion(&result, nullptr, GetEventRoom());
}
int nItemsRemaining = 0;
for (int i = 0; i < MAX_MERCH_ITEMS; i++)
{
if (pMerchUser->m_arMerchantItems[i].nNum != 0 && !pMerchUser->m_arMerchantItems[i].IsSoldOut)
nItemsRemaining++;
}
if (nItemsRemaining == 0 && pMerchUser) pMerchUser->MerchantClose();
if (nItemsRemaining > 0) MerchantSlipRefList(pMerchUser);
}
else
{
CBot* pUserBot = g_pMain->GetBotPtr(m_sMerchantsSocketID);
if (pUserBot != nullptr)
{
printf("[MerchantLog] Bot MerchantID: %d, State: %d\n", m_sMerchantsSocketID, pUserBot->GetMerchantState());
if (pUserBot->GetMerchantState() != MERCHANT_STATE_SELLING)
{
printf("[MerchantLog] Bot is not in selling state.\n");
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
pkt >> itemid >> item_count >> item_slot >> dest_slot;
printf("[MerchantLog] Attempting to buy itemID %u, count %u from slot %u to dest %u\n", itemid, item_count, item_slot, dest_slot);
// Make sure the slots are correct and that we're actually buying at least 1 item.
if (item_slot >= MAX_MERCH_ITEMS || dest_slot >= HAVE_MAX || !item_count)
{
printf("[MerchantLog] Invalid item slot or destination slot.\n");
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
// Grab pointers to the items.
_MERCH_DATA* pMerch = &pUserBot->m_arMerchantItems[item_slot];
if (pMerch == nullptr || pMerch->IsSoldOut || !pMerch->sCount || !pMerch->nPrice)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
_ITEM_DATA* pBuyerItem = GetItem(SLOT_MAX + dest_slot);
if (pBuyerItem == nullptr)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerch->nNum != itemid || pMerch->sCount < item_count || pMerch->orgcount < item_count)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
auto pSellingItem = g_pMain->GetItemPtr(itemid);
if (pSellingItem.isnull() || pSellingItem.m_bCountable == 2 || (!pSellingItem.m_bCountable && item_count != 1))
{
result << uint16(-18);
Send(&result);
return;
}
if (pSellingItem.m_bKind == 255 && item_count != 1 && !pSellingItem.m_bCountable)
{
result << uint16(-18);
Send(&result);
return;
}
uint32 nReqWeight = pSellingItem.m_sWeight * item_count;
if (nReqWeight + m_sItemWeight > m_sMaxWeight)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
req_gold = pMerch->nPrice * item_count;
if (pMerch->isKC)
{
if (m_nKnightCash < req_gold)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
}
else
{
if (m_iGold < req_gold)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
}
if (pBuyerItem->nNum != 0 && (pBuyerItem->nNum != itemid || !pSellingItem.m_bCountable))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (!pMerch->isKC && dynamic_cast<CUser*>(pUserBot) && pUserBot->m_iGold + req_gold > COIN_MAX)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pMerch->isKC)
{
if (pUserBot->isSlaveMerchant())
{
if (!CashLose(req_gold)) {
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
CUser* pSlaveUser = g_pMain->GetUserPtr(pUserBot->m_bSlaveUserID);
if (pSlaveUser != nullptr)
{
for (int i = 0; i < 12; i++) {
if (pSlaveUser->SlaveItemID[i] == itemid)
{
pSlaveUser->SlaveItemID[i] = 0;
pSlaveUser->SlaveItemCount[i] -= item_count;
}
}
std::string m_sAutosystem, gold, gold2, total;
m_sAutosystem = string_format("[Slave Merchant] You Received ");
gold = std::to_string(req_gold);
gold2 = " cash.";
total = m_sAutosystem + gold + gold2;
#if 0
Packet result(XSafeOpCodes::PL_INFOMESSAGE);
result << total;
pSlaveUser->Send(&result);
#else
pSlaveUser->SendBoxMessage(0, "", "[Slave Merchant] You Received ", 0, messagecolour::red);
#endif
g_DBAgent.UpdateSlaveKC(pSlaveUser->GetName(), req_gold);
for (int i = 0; i < 12; i++)
SlaveItemID[i] = 0;
for (int i = 0; i < 12; i++)
SlaveItemCount[i] = 0;
}
}
else
{
if (!CashLose(req_gold)) {
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
}
}
else
{
if (pUserBot->isSlaveMerchant())
{
if (!GoldLose(req_gold))
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
CUser* pSlaveUser = g_pMain->GetUserPtr(pUserBot->m_bSlaveUserID);
if (pSlaveUser != nullptr)
{
for (int i = 0; i < 12; i++) {
if (pSlaveUser->SlaveItemID[i] == itemid)
{
pSlaveUser->SlaveItemID[i] = 0;
pSlaveUser->SlaveItemCount[i] -= item_count;
}
}
if (pSlaveUser->m_iGold + req_gold > COIN_MAX)
{
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
std::string m_sAutosystem, gold, gold2, total;
m_sAutosystem = string_format("[Slave Merchant] You Received ");
gold = std::to_string(req_gold);
gold2 = " gold.";
total = m_sAutosystem + gold + gold2;
#if 0
Packet result(XSafeOpCodes::PL_INFOMESSAGE);
result << total;
pSlaveUser->Send(&result);
#else
pSlaveUser->SendBoxMessage(0, "", "[Slave Merchant] You Received ", 0, messagecolour::red);
#endif
g_DBAgent.UpdateSlaveCoins(pSlaveUser->GetName(), req_gold);
for (int i = 0; i < 12; i++)
SlaveItemID[i] = 0;
for (int i = 0; i < 12; i++)
SlaveItemCount[i] = 0;
}
}
else
{
if (!GoldLose(req_gold)) {
result << uint8(6) << uint16(-18);
Send(&result);
return;
}
if (pUserBot->m_iGold + req_gold > COIN_MAX)
pUserBot->m_iGold = COIN_MAX;
else
pUserBot->m_iGold += req_gold;
}
}
leftover_count = pMerch->sCount - item_count;
pBuyerItem->sCount += item_count;
pMerch->sCount -= item_count;
pBuyerItem->nSerialNum = g_pMain->GenerateItemSerial();
pBuyerItem->nNum = pMerch->nNum;
pBuyerItem->sDuration = pMerch->sDuration;
if (!pSellingItem.isStackable() || item_count == pMerch->sCount) pBuyerItem->nSerialNum = g_pMain->GenerateItemSerial();
if (!pSellingItem.isStackable() && pBuyerItem->nSerialNum == 0) pBuyerItem->nSerialNum = g_pMain->GenerateItemSerial();
pBuyerItem->MerchItem = false;
SendStackChange(itemid, pBuyerItem->sCount, pBuyerItem->sDuration, dest_slot, (pBuyerItem->sCount == item_count)); // is it a new item?
MerchantShoppingDetailInsertLog(true, 1, itemid, item_count, pMerch->nPrice, nullptr);
if (!pMerch->sCount || (pSellingItem.m_bCountable == 0 && pSellingItem.m_bKind == 255))
{
memset(pMerch, 0, sizeof(_MERCH_DATA));
pMerch->IsSoldOut = true;
}
result.clear();
result.Initialize(WIZ_MERCHANT);
result << uint8(MERCHANT_ITEM_PURCHASED) << itemid << GetName();
if (pUserBot->isSlaveMerchant())
{
CUser* pSlaveUser = g_pMain->GetUserPtr(pUserBot->GetSlaveGetID());
if (pSlaveUser != nullptr)
{
if (pSlaveUser->isSlaveMerchant())
pSlaveUser->Send(&result);
}
}
result.clear();
result.Initialize(WIZ_MERCHANT);
result << uint8(MERCHANT_ITEM_BUY) << uint16(1) << itemid << leftover_count << item_slot << dest_slot;
Send(&result);
if (item_slot < 4 && leftover_count == 0)
{
result.clear();
result.Initialize(WIZ_MERCHANT_INOUT);
result << uint8(2) << m_sMerchantsSocketID << uint8(1) << uint8(0) << item_slot;
pUserBot->SendToRegion(&result);
}
int nItemsRemaining = 0;
for (int i = 0; i < MAX_MERCH_ITEMS; i++)
{
if (pUserBot->m_arMerchantItems[i].nNum != 0 && !pUserBot->m_arMerchantItems[i].IsSoldOut)
nItemsRemaining++;
}
if (nItemsRemaining == 0)
{
if (pUserBot->isSlaveMerchant())
{
CUser* pSlaveUser = g_pMain->GetUserPtr(pUserBot->GetSlaveGetID());
if (pSlaveUser != nullptr)
{
if (pSlaveUser->isSlaveMerchant())
{
pSlaveUser->m_bSlaveMerchant = false;
pSlaveUser->m_bSlaveUserID = -1;
}
}
result.clear();
result.Initialize(WIZ_MERCHANT);
result << uint8(MERCHANT_CLOSE) << pUserBot->GetID();
pUserBot->SendToRegion(&result);
pUserBot->UserInOut(INOUT_OUT);
return;
}
pUserBot->LastWarpTime = UNIXTIME + 10;
pUserBot->m_bMerchantViewer = -1;
//pUserBot->m_bSellingMerchantPreparing = false;
pUserBot->m_bMerchantState = MERCHANT_STATE_NONE;
Packet res(WIZ_MERCHANT, uint8(MERCHANT_CLOSE));
res << pUserBot->GetID();
pUserBot->SendToRegion(&res);
}
}
}
}
Teşekkürler.cbot.cpp
MerchantHandler.cpp
revize edilip düzeltildi
ücretli yaparım xd
discord: xd
konuyla ilgili sorun yaşayan arkadaşlar gerekli cpp alttaki linkte mevcut
*** Gizli metin: alıntı yapılamaz. ***