Untitled
gggunknown
plain_text
2 years ago
20 kB
6
Indexable
Never
//Find CShop::Buy and replace #ifdef OFFLINE_SHOP #include "char.h" int CShop::Buy(LPCHARACTER ch, BYTE pos) { if (IsLocked()) return SHOP_SUBHEADER_GC_END; if (pos >= m_itemVector.size()) { sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName()); return SHOP_SUBHEADER_GC_INVALID_POS; } sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos); GuestMapType::iterator it = m_map_guest.find(ch); if (it == m_map_guest.end()) return SHOP_SUBHEADER_GC_END; SHOP_ITEM& r_item = m_itemVector[pos]; if (r_item.price < 0) { LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } LPITEM pkSelectedItem = ITEM_MANAGER::instance().Find(r_item.itemid); #ifdef FULL_YANG long long dwPrice = r_item.price; #else DWORD dwPrice = r_item.price; #endif DWORD dwTax = 0; int iVal = quest::CQuestManager::instance().GetEventFlag ("personal_shop"); if (0 < iVal) { if (iVal > 100) { iVal = 100; } dwTax = dwPrice * iVal / 100; dwPrice = dwPrice - dwTax; } else { iVal = 0; dwTax = 0; } if (ch->GetGold() < r_item.price) { sys_log(1, "Shop::Buy : Not enough money : %s has %d, price %d", ch->GetName(), ch->GetGold(), dwPrice); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } LPITEM item; if (m_pkPC) item = r_item.pkItem; else { item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count); } if (!item) return SHOP_SUBHEADER_GC_SOLD_OUT; int iEmptyPos; if (item->IsDragonSoul()) { iEmptyPos = ch->GetEmptyDragonSoulInventory(item); } else { iEmptyPos = ch->GetEmptyInventory(item->GetSize()); } if (iEmptyPos < 0) { if (m_pkPC) { sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize()); return SHOP_SUBHEADER_GC_INVENTORY_FULL; } else { sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize()); M2_DESTROY_ITEM(item); return SHOP_SUBHEADER_GC_INVENTORY_FULL; } } #ifdef FULL_YANG_OWN ch->ChangeGold(-dwPrice); #else ch->PointChange(POINT_GOLD, -dwPrice, false); #endif // ±?AO ˝?˝??? : ??±Y Aˇ?o if (m_pkPC) { if (!m_pkPC->IsPrivShop()) m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); char buf[512]; DWORD mpid = (m_pkPC->IsPrivShop() ? m_pkPC->GetPrivShopOwner() : m_pkPC->GetPlayerID()); if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007) { snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), mpid, dwPrice); LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf); LogManager::instance().GoldBarLog(mpid, item->GetID(), SHOP_SELL, buf); } LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count); if (pkNewItem) { for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++) { pkNewItem->SetSocket(i, item->GetSocket(i)); } // 매직 아이템 설정 item->CopyAttributeTo(pkNewItem); if (pkNewItem->IsDragonSoul()) pkNewItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos)); else pkNewItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); item->RemoveFromCharacter(); M2_DESTROY_ITEM(item); ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem); std::string szBuy("SHOP_BUY"); std::string szSell("SHOP_SELL"); if (m_pkPC->IsPrivShop()) { std::string temp("OFFLINE_"); szBuy = temp + szBuy; szSell = temp + szSell; } #ifdef FULL_YANG snprintf(buf, sizeof(buf), "%s %u(%s) %lld %u", pkNewItem->GetName(), mpid, m_pkPC->GetName(), dwPrice, pkNewItem->GetCount()); LogManager::instance().ItemLog(ch, pkNewItem, szBuy.c_str(), buf); snprintf(buf, sizeof(buf), "%s %u(%s) %lld %u", pkNewItem->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, pkNewItem->GetCount()); LogManager::instance().ItemLog(m_pkPC, pkNewItem, szSell.c_str(), buf); #else snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", pkNewItem->GetName(), mpid, m_pkPC->GetName(), dwPrice, pkNewItem->GetCount()); LogManager::instance().ItemLog(ch, pkNewItem, szBuy.c_str(), buf); snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", pkNewItem->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, pkNewItem->GetCount()); LogManager::instance().ItemLog(m_pkPC, pkNewItem, szSell.c_str(), buf); #endif r_item.pkItem = NULL; BroadcastUpdateItem(pos); if (m_pkPC->IsPrivShop()) { LPCHARACTER owner = CHARACTER_MANAGER::instance().FindByPID(m_pkPC->GetPrivShopOwner()); #ifdef FULL_YANG DBManager::instance().DirectQuery("UPDATE player_shop SET gold=gold + %lld WHERE id=%d", dwPrice, m_pkPC->GetPrivShop()); #else DBManager::instance().DirectQuery("INSERT INTO player_gift SET \ owner_id=%d,vnum=1,count='%d',reason=\"%s\",`from`=replace(\"%s #%d\",' ','_'),status='WAIT',date_add=NOW()", m_pkPC->GetPrivShopOwner(), dwPrice, LC_TEXT("SHOP_REASON"), m_pkPC->GetName(), m_pkPC->GetPrivShop()); #endif DBManager::instance().DirectQuery("DELETE FROM player_shop_items WHERE shop_id=%d and id = %d", m_pkPC->GetPrivShop(), r_item.itemid); if (owner) { owner->LoadPrivShops(); #ifdef FULL_YANG if (owner->GetGiftPages() > 0) owner->ChatPacket(CHAT_TYPE_COMMAND, "gift_info %d", owner->GetGiftPages()); #else owner->RefreshGift(); #endif } } else{ #ifdef FULL_YANG_OWN m_pkPC->ChangeGold(dwPrice); #else m_pkPC->PointChange(POINT_GOLD, dwPrice, false); #endif if (iVal > 0) { m_pkPC->ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal); } } item = pkNewItem; } else { return SHOP_SUBHEADER_GC_INVALID_POS; } } else { if (item->IsDragonSoul()) item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos)); else item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); ITEM_MANAGER::instance().FlushDelayedSave(item); LogManager::instance().ItemLog(ch, item, "BUY", item->GetName()); if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007) { LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, ""); } //DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice); } if (item) sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice); ch->Save(); #if defined(SHOP_AUTO_CLOSE) && defined(OFFLINE_SHOP) if (m_pkPC && m_pkPC->IsPrivShop()) { if (GetItemCount()<=0) m_pkPC->DeleteMyShop(); } #endif return (SHOP_SUBHEADER_GC_OK); } void CShop::RemoveGuests(LPCHARACTER except) { GuestMapType::iterator it = m_map_guest.begin(); while (it != m_map_guest.end()) { LPCHARACTER ch = it->first; if (except && ch == except) { it++; continue; } if (ch) { ch->SetShop(NULL); TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = SHOP_SUBHEADER_GC_END; pack.size = sizeof(TPacketGCShop); ch->GetDesc()->Packet(&pack, sizeof(pack)); } m_map_guest.erase(it++); } } void CShop::ClearItems() { for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i) { m_itemVector[i].pkItem = NULL; BroadcastUpdateItem(i); } } int CShop::GetItemCount() { int count = 0; for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i) { if (m_itemVector[i].pkItem) count++; } return count; } bool CShop::GetItems() { if (!m_pkPC) return false; if (!m_pkPC) return false; for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i) { if (!m_itemVector[i].pkItem) continue; char query[8192]; sprintf(query, "INSERT INTO player_gift SET \ owner_id=%d,vnum=%d,count=%d,reason='%s',`from`=replace(\"%s\",' ','_'),status='WAIT',date_add=NOW()", m_pkPC->GetPrivShopOwner(), m_itemVector[i].vnum, m_itemVector[i].count, LC_TEXT("SHOP_REASON"), m_pkPC->GetName()); for (int s = 0; s < ITEM_SOCKET_MAX_NUM; s++) { sprintf(query, "%s, socket%d='%ld'", query, s, m_itemVector[i].pkItem->GetSocket(s)); } for (int ia = 0; ia < ITEM_ATTRIBUTE_MAX_NUM; ia++) { const TPlayerItemAttribute& attr = m_itemVector[i].pkItem->GetAttribute(ia); if (ia < 7) { sprintf(query, "%s, attrtype%d='%u'", query, ia, attr.bType); sprintf(query, "%s, attrvalue%d='%d'", query, ia, attr.sValue); } else { sprintf(query, "%s, applytype%d='%u'", query, ia-7, attr.bType); sprintf(query, "%s, applyvalue%d='%d'", query, ia-7, attr.sValue); } } DBManager::instance().DirectQuery(query); DBManager::instance().DirectQuery("delete from player_shop_items where id='%d'", m_itemVector[i].itemid); m_itemVector[i].pkItem->RemoveFromCharacter(); m_itemVector[i].pkItem = NULL; BroadcastUpdateItem(i); } return true; } void CShop::SetPrivShopItems(std::vector<TShopItemTable *> map_shop) { m_pGrid->Clear(); m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM); memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size()); for (DWORD count = 0;count < map_shop.size();count++) { TShopItemTable * pTable = map_shop[count]; LPITEM pkItem = NULL; const TItemTable * item_table; if (!m_pkPC) return; pkItem = m_pkPC->GetItem(pTable->pos); if (!pkItem) { sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, m_pkPC->GetName()); continue; } item_table = pkItem->GetProto(); if (!item_table) { sys_err("Shop: no item table by item vnum #%d", pTable->vnum); continue; } WORD iPos = pTable->display_pos; sys_log(0, "MyShop: use position %d", iPos); if (iPos < 0) { sys_err("not enough shop window"); continue; } if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize)) { sys_err("not empty position for pc shop %s[%d] fixing", m_pkPC->GetName(), m_pkPC->GetPlayerID()); iPos = m_pGrid->FindBlank(1, item_table->bSize); if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize)) { sys_err("not empty position for pc shop %s[%d]", m_pkPC->GetName(), m_pkPC->GetPlayerID()); continue; } } m_pGrid->Put(iPos, 1, item_table->bSize); SHOP_ITEM & item = m_itemVector[iPos]; item.pkItem = pkItem; item.itemid = 0; if (item.pkItem) { item.vnum = pkItem->GetVnum(); item.count = pkItem->GetCount(); // PC ?? ?? ??? ??? ?? ???? ???? ??. item.price = pTable->price; // ??? ???? ????.. item.itemid = pkItem->GetRealID(); } char name[36]; snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int)item.vnum, item.count); sys_log(0, "PRIV_SHOP_ITEM: %-36s PRICE %-5d", name, item.price); } } #else extern bool FN_check_item_socket(LPITEM item); int CShop::Buy(LPCHARACTER ch, BYTE pos) { if (pos >= m_itemVector.size()) { sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName()); return SHOP_SUBHEADER_GC_INVALID_POS; } sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos); GuestMapType::iterator it = m_map_guest.find(ch); if (it == m_map_guest.end()) return SHOP_SUBHEADER_GC_END; if (ch == m_pkPC) return SHOP_SUBHEADER_GC_END; SHOP_ITEM& r_item = m_itemVector[pos]; if (r_item.price < 0) { LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } LPITEM pkSelectedItem = ITEM_MANAGER::instance().Find(r_item.itemid); if (IsPCShop()) { if (!pkSelectedItem) { sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item id %d : BuyerPID:%d SellerPID:%d", r_item.itemid, ch->GetPlayerID(), m_pkPC->GetPlayerID()); return false; } if ((pkSelectedItem->GetOwner() != m_pkPC)) { sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item owner: BuyerPID:%d SellerPID:%d", ch->GetPlayerID(), m_pkPC->GetPlayerID()); return false; } } long long dwPrice = r_item.price; if (ch->GetGold() < dwPrice) { sys_log(1, "Shop::Buy : Not enough money : %s has %d, price %d", ch->GetName(), ch->GetGold(), dwPrice); return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY; } LPITEM item; if (m_pkPC) // 피씨가 운영하는 샵은 피씨가 실제 아이템을 가지고있어야 한다. item = r_item.pkItem; else item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count); if (!item) return SHOP_SUBHEADER_GC_SOLD_OUT; WORD iEmptyPos; if (item->IsDragonSoul()) { iEmptyPos = ch->GetEmptyDragonSoulInventory(item); } else { iEmptyPos = ch->GetEmptyInventory(item->GetSize()); } if (iEmptyPos < 0) { if (m_pkPC) { sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize()); return SHOP_SUBHEADER_GC_INVENTORY_FULL; } else { sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize()); M2_DESTROY_ITEM(item); return SHOP_SUBHEADER_GC_INVENTORY_FULL; } } ch->SetGold(ch->GetGold() - dwPrice); ch->SendGold(); //ch->PointChange(POINT_GOLD, -dwPrice, false); /*TShopTable test; std::map<int, TShopTable *> map_shop; TShopTable * shop_table; shop_table->dwNPCVnum; ch->SetQuestNPCID('2'); quest::CQuestManager::instance().OnBuy(ch->GetPlayerID(), item); */ // 군주 시스템 : 세금 징수 if (m_pkPC) { m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); char buf[512]; if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007) { snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), m_pkPC->GetPlayerID(), dwPrice); LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf); LogManager::instance().GoldBarLog(m_pkPC->GetPlayerID(), item->GetID(), SHOP_SELL, buf); } item->RemoveFromCharacter(); if (item->IsDragonSoul()) item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos)); else item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); ITEM_MANAGER::instance().FlushDelayedSave(item); snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, item->GetCount()); LogManager::instance().ItemLog(ch, item, "SHOP_BUY", buf); // BUY EVENT snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount()); LogManager::instance().ItemLog(m_pkPC, item, "SHOP_SELL", buf); r_item.pkItem = NULL; BroadcastUpdateItem(pos); m_pkPC->SetGold(m_pkPC->GetGold() + dwPrice); m_pkPC->SendGold(); } else { if (item->IsDragonSoul()) item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos)); else{ WORD bCount = item->GetCount(); if ((item->GetFlag() == 4 || item->GetFlag() == 20)) { for (WORD i = 0; i < INVENTORY_MAX_NUM; ++i) { LPITEM item2 = ch->GetInventoryItem(i); if (!item2) continue; if (item2->GetVnum() == item->GetVnum()) { int j; for (j = 0; j < ITEM_SOCKET_MAX_NUM; ++j) if (item2->GetSocket(j) != item->GetSocket(j)) break; if (j != ITEM_SOCKET_MAX_NUM) continue; WORD bCount2 = MIN(g_bItemCountLimit - item2->GetCount(), bCount); bCount -= bCount2; item2->SetCount(item2->GetCount() + bCount2); if (bCount == 0) { break; } } } item->SetCount(bCount); } if (bCount > 0) { item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); } else M2_DESTROY_ITEM(item); } ITEM_MANAGER::instance().FlushDelayedSave(item); LogManager::instance().ItemLog(ch, item, "BUY", item->GetName()); if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007) { LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, ""); } //DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), -dwPrice); } if (item) sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice); ch->Save(); return (SHOP_SUBHEADER_GC_OK); } #endif