Razu V5 altyapısına, Sonitex konusundaki sistemi entegre etmeye çalışıyorum. Birçok hatayı geçerek kodu belli bir noktaya getirdim ancak şu anki hata herhangi bir syserr basmıyor.
Örnek olarak bir pazar oluşturdum ve içerisine 1 adet item listeledim. Farklı bir account üzerinden bu itemi satın aldım ve doğal olarak pazar kapandı ve yok oldu. Bu aşamadan sonra kapanan pazar sahibi olan account yeni bir pazar açamıyor ve char_item.cpp içerisindeki if (IsPrivateShopOwner()) satırına girerek "Close your current personal shop before opening a new one." hatasını basıyor.
Bu hatayı görünce sıkıntının server source kaynaklı olduğunu düşündüm. DB kodlarını kurcalarken player DB içerisine eklemiş olduğum private_shop tablosuna verinin geç yazıldığını fark ettim.
Örneğin pazarı açıyorum, tabloya sırasıyla (owner_id, owner_name, state, title, title_type, vnum, x, y, map_index, channel, port, gold, cheque, page_count, premium_time) bilgileri gecikmeli olarak ekleniyor ve state kısmı OPEN olarak işleniyor. Pazar item satın alınıp kapandıktan sonra bu stateyi güncellemeden yok oluyor yaklaşık 1 dakika sonra DB ye state CLOSED olarak güncellemeyi ekliyor. Anladığım kadarıyla bu işlemleri önce cache üzerinden gerçekleştirdiği için DB ye ihtiyaç duymadan bu noktaya kadar gelebiliyor iş.
Örnek 1 satırlık private_shop tablosu kayıtı:
1 PDx CLOSED PAZAR 0 30000 960004 271937 41 1 13000 1111 0 1 0
private_shop_item tablosuna ise pazarı açsam da kapasam da hiçbir veri işlenmiyor (tahminimce böyle olması gerekiyor ama emin değilim).
Rehberin ClientManagerBoot.cpp kısmındaki detaylarını kullandığım source TXT proto olduğu için gerçekleştirmemiştim ama vnum_range olayı bu soruna sebep olur mu kestiremiyorum. ClientManager.cpp içerisine bir girişmeyi düşündüm ama sıkıntının nereden kaynaklandığını tam anlamadığım için dokunmayayım dedim.
Elimde ekleyebileceğim sadece syslog var belki buradan siz de bir çıkarım yapabilirsiniz.
Örnek olarak bir pazar oluşturdum ve içerisine 1 adet item listeledim. Farklı bir account üzerinden bu itemi satın aldım ve doğal olarak pazar kapandı ve yok oldu. Bu aşamadan sonra kapanan pazar sahibi olan account yeni bir pazar açamıyor ve char_item.cpp içerisindeki if (IsPrivateShopOwner()) satırına girerek "Close your current personal shop before opening a new one." hatasını basıyor.
Bu hatayı görünce sıkıntının server source kaynaklı olduğunu düşündüm. DB kodlarını kurcalarken player DB içerisine eklemiş olduğum private_shop tablosuna verinin geç yazıldığını fark ettim.
Örneğin pazarı açıyorum, tabloya sırasıyla (owner_id, owner_name, state, title, title_type, vnum, x, y, map_index, channel, port, gold, cheque, page_count, premium_time) bilgileri gecikmeli olarak ekleniyor ve state kısmı OPEN olarak işleniyor. Pazar item satın alınıp kapandıktan sonra bu stateyi güncellemeden yok oluyor yaklaşık 1 dakika sonra DB ye state CLOSED olarak güncellemeyi ekliyor. Anladığım kadarıyla bu işlemleri önce cache üzerinden gerçekleştirdiği için DB ye ihtiyaç duymadan bu noktaya kadar gelebiliyor iş.
Örnek 1 satırlık private_shop tablosu kayıtı:
1 PDx CLOSED PAZAR 0 30000 960004 271937 41 1 13000 1111 0 1 0
private_shop_item tablosuna ise pazarı açsam da kapasam da hiçbir veri işlenmiyor (tahminimce böyle olması gerekiyor ama emin değilim).
Rehberin ClientManagerBoot.cpp kısmındaki detaylarını kullandığım source TXT proto olduğu için gerçekleştirmemiştim ama vnum_range olayı bu soruna sebep olur mu kestiremiyorum. ClientManager.cpp içerisine bir girişmeyi düşündüm ama sıkıntının nereden kaynaklandığını tam anlamadığım için dokunmayayım dedim.
Elimde ekleyebileceğim sadece syslog var belki buradan siz de bir çıkarım yapabilirsiniz.
syslog:
Jun 4 22:09:11 :: PRIVATE_SHOP: Building private shop 3
Jun 4 22:09:11 :: Re-creating private shop for owner 3
Jun 4 22:09:11 :: PRIVATE_SHOP: Added item 10000658 pos 17 vnum 189 to private shop 3
Jun 4 22:09:11 :: PRIVATE_SHOP: Private shop 3 successfully created
Jun 4 22:09:11 :: PRIVATE_SHOP: Private shop 3 successfully built
Jun 4 22:09:13 :: [ 10550] return 0/0/1 async 0/0/0
Jun 4 22:09:18 :: [ 10600] return 0/0/0 async 0/0/0
Jun 4 22:09:23 :: [ 10650] return 0/0/0 async 0/0/0
Jun 4 22:09:28 :: [ 10700] return 0/0/0 async 0/0/0
Jun 4 22:09:33 :: [ 10750] return 0/0/0 async 0/0/0
Jun 4 22:09:38 :: [ 10800] return 0/0/1 async 0/0/0
Jun 4 22:09:43 :: [ 10850] return 0/0/0 async 0/0/0
Jun 4 22:09:48 :: [ 10900] return 0/0/0 async 0/0/0
Jun 4 22:09:53 :: [ 10950] return 0/0/0 async 0/0/0
Jun 4 22:09:58 :: [ 11000] return 0/0/0 async 0/0/0
Jun 4 22:10:03 :: [ 11050] return 0/0/0 async 0/0/0
Jun 4 22:10:08 :: [ 11100] return 0/0/0 async 0/0/0
Jun 4 22:10:13 :: [ 11150] return 0/0/0 async 0/0/0
Jun 4 22:10:18 :: [ 11200] return 0/0/0 async 0/0/0
Jun 4 22:10:23 :: [ 11250] return 0/0/0 async 0/0/0
Jun 4 22:10:28 :: [ 11300] return 0/0/0 async 0/0/0
Jun 4 22:10:33 :: [ 11350] return 0/0/0 async 0/0/0
Jun 4 22:10:38 :: [ 11400] return 0/0/0 async 0/0/0
Jun 4 22:10:43 :: [ 11450] return 0/0/0 async 0/0/0
Jun 4 22:10:48 :: [ 11500] return 0/0/0 async 0/0/0
Jun 4 22:10:53 :: [ 11550] return 0/0/0 async 0/0/0
Jun 4 22:10:58 :: [ 11600] return 0/0/0 async 0/0/0
Jun 4 22:11:03 :: [ 11650] return 0/0/0 async 0/0/0
Jun 4 22:11:08 :: [ 11700] return 0/0/0 async 0/0/0
Jun 4 22:11:13 :: [ 11750] return 0/0/0 async 0/0/0
Jun 4 22:11:18 :: [ 11800] return 0/0/0 async 0/0/0
Jun 4 22:11:23 :: [ 11850] return 0/0/0 async 0/0/0
Jun 4 22:11:28 :: [ 11900] return 0/0/0 async 0/0/0
Jun 4 22:11:33 :: [ 11950] return 0/0/0 async 0/0/0
Jun 4 22:11:38 :: [ 12000] return 0/0/0 async 0/0/0
Jun 4 22:11:43 :: [ 12050] return 0/0/0 async 0/0/0
Jun 4 22:11:48 :: [ 12100] return 0/0/0 async 0/0/0
Jun 4 22:11:53 :: [ 12150] return 0/0/0 async 0/0/0
Jun 4 22:11:58 :: [ 12200] return 0/0/0 async 0/0/0
Jun 4 22:12:03 :: [ 12250] return 0/0/0 async 0/0/0
Jun 4 22:12:08 :: [ 12300] return 0/0/0 async 0/0/0
Jun 4 22:12:13 :: [ 12350] return 0/0/0 async 0/0/0
Jun 4 22:12:18 :: [ 12400] return 0/0/0 async 0/0/0
Jun 4 22:12:23 :: [ 12450] return 0/0/0 async 0/0/0
Jun 4 22:12:28 :: [ 12500] return 0/0/0 async 0/0/0
Jun 4 22:12:33 :: [ 12550] return 0/0/0 async 0/0/0
Jun 4 22:12:38 :: [ 12600] return 0/0/0 async 0/0/0
Jun 4 22:12:43 :: [ 12650] return 0/0/1 async 0/0/0
Jun 4 22:12:48 :: [ 12700] return 0/0/0 async 0/0/0
Jun 4 22:12:53 :: [ 12750] return 0/0/0 async 0/0/0
Jun 4 22:12:58 :: [ 12800] return 0/0/0 async 0/0/0
Jun 4 22:13:03 :: [ 12850] return 0/0/0 async 0/0/0
Jun 4 22:13:08 :: [ 12900] return 0/0/0 async 0/0/0
Jun 4 22:13:13 :: [ 12950] return 0/0/0 async 0/0/0
Jun 4 22:13:18 :: [ 13000] return 0/0/0 async 0/0/0
Jun 4 22:13:23 :: [ 13050] return 0/0/0 async 0/0/0
Jun 4 22:13:28 :: [ 13100] return 0/0/0 async 0/0/0
Jun 4 22:13:33 :: [ 13150] return 0/0/0 async 0/0/0
Jun 4 22:13:38 :: [ 13200] return 0/0/0 async 0/0/0
Jun 4 22:13:43 :: [ 13250] return 0/0/0 async 0/0/0
Jun 4 22:13:48 :: [ 13300] return 0/0/0 async 0/0/0
Jun 4 22:13:53 :: [ 13350] return 0/0/0 async 0/0/0
Jun 4 22:13:58 :: [ 13400] return 0/0/0 async 0/0/0
Jun 4 22:14:03 :: [ 13450] return 0/0/0 async 0/0/0
Jun 4 22:14:08 :: [ 13500] return 0/0/0 async 0/0/0
Jun 4 22:14:13 :: [ 13550] return 0/0/2 async 0/0/0
Jun 4 22:14:18 :: [ 13600] return 0/0/0 async 0/0/0
Jun 4 22:14:23 :: [ 13650] return 0/0/0 async 0/0/0
Jun 4 22:14:28 :: [ 13700] return 0/0/0 async 0/0/0
Jun 4 22:14:33 :: [ 13750] return 0/0/0 async 0/0/0
Jun 4 22:14:38 :: [ 13800] return 0/0/0 async 0/0/0
Jun 4 22:14:43 :: [ 13850] return 0/0/0 async 0/0/0
Jun 4 22:14:44 :: PRIVATE_SHOP: Buy request forwarded to game for private shop 3 customer 1 item pos 17 item 189 yang 1313 won 0
Jun 4 22:14:44 :: PRIVATE_SHOP: Item bought from private shop 3 pos 17 gold 1313 won 0 by pid 1
Jun 4 22:14:44 :: PRIVATE_SHOP: Despawning item empty private shop 3 by item sale
Jun 4 22:14:44 :: PRIVATE_SHOP: Sending despawn update to owner 3
Jun 4 22:14:48 :: [ 13900] return 0/0/0 async 0/0/0
Jun 4 22:14:53 :: [ 13950] return 0/0/0 async 0/0/0
Jun 4 22:14:58 :: [ 14000] return 0/0/0 async 0/0/0
Jun 4 22:15:03 :: [ 14050] return 0/0/0 async 0/0/0
Jun 4 22:15:08 :: [ 14100] return 0/0/0 async 0/0/0
Jun 4 22:15:13 :: [ 14150] return 0/0/0 async 0/0/0
Jun 4 22:15:18 :: [ 14200] return 0/0/0 async 0/0/0
Jun 4 22:15:23 :: [ 14250] return 0/0/0 async 0/0/0
Jun 4 22:15:28 :: [ 14300] return 0/0/0 async 0/0/0
Jun 4 22:15:33 :: [ 14350] return 0/0/0 async 0/0/0
Jun 4 22:15:38 :: [ 14400] return 0/0/0 async 0/0/0
Jun 4 22:15:43 :: [ 14450] return 0/0/0 async 0/0/0
Jun 4 22:15:48 :: [ 14500] return 0/0/0 async 0/0/0
Jun 4 22:15:53 :: [ 14550] return 0/0/0 async 0/0/0
Jun 4 22:15:58 :: [ 14600] return 0/0/0 async 0/0/0
Jun 4 22:16:03 :: [ 14650] return 0/0/0 async 0/0/0
Jun 4 22:16:08 :: [ 14700] return 0/0/0 async 0/0/0
Jun 4 22:16:13 :: [ 14750] return 0/0/0 async 0/0/0
Jun 4 22:16:18 :: [ 14800] return 0/0/0 async 0/0/0
Jun 4 22:16:23 :: [ 14850] return 0/0/0 async 0/0/0
Jun 4 22:16:28 :: [ 14900] return 0/0/0 async 0/0/0
Jun 4 22:16:33 :: [ 14950] return 0/0/0 async 0/0/0
Jun 4 22:16:38 :: [ 15000] return 0/0/0 async 0/0/0
Jun 4 22:16:43 :: [ 15050] return 0/0/0 async 0/0/0
Jun 4 22:16:48 :: [ 15100] return 0/0/0 async 0/0/0
Jun 4 22:16:53 :: [ 15150] return 0/0/0 async 0/0/0
Jun 4 22:16:58 :: [ 15200] return 0/0/0 async 0/0/0
Jun 4 22:17:03 :: [ 15250] return 0/0/0 async 0/0/0
Jun 4 22:17:08 :: [ 15300] return 0/0/0 async 0/0/0
Jun 4 22:17:13 :: [ 15350] return 0/0/0 async 0/0/0
Jun 4 22:17:18 :: [ 15400] return 0/0/0 async 0/0/0
Jun 4 22:17:23 :: [ 15450] return 0/0/0 async 0/0/0
Jun 4 22:17:28 :: [ 15500] return 0/0/0 async 0/0/0
Jun 4 22:17:33 :: [ 15550] return 0/0/0 async 0/0/0
Jun 4 22:17:38 :: [ 15600] return 0/0/1 async 0/0/0
Jun 4 22:17:43 :: [ 15650] return 0/0/0 async 0/0/0
Jun 4 22:17:48 :: [ 15700] return 0/0/0 async 0/0/0
Jun 4 22:17:53 :: [ 15750] return 0/0/0 async 0/0/0
Jun 4 22:17:58 :: [ 15800] return 0/0/0 async 0/0/0
Jun 4 22:18:03 :: [ 15850] return 0/0/0 async 0/0/0
Jun 4 22:18:08 :: [ 15900] return 0/0/0 async 0/0/0
Jun 4 22:18:13 :: [ 15950] return 0/0/0 async 0/0/0
Jun 4 22:18:18 :: [ 16000] return 0/0/0 async 0/0/0
Jun 4 22:18:23 :: [ 16050] return 0/0/0 async 0/0/0
Jun 4 22:18:28 :: [ 16100] return 0/0/0 async 0/0/0
Jun 4 22:18:33 :: [ 16150] return 0/0/0 async 0/0/0
Jun 4 22:18:38 :: [ 16200] return 0/0/0 async 0/0/0
Jun 4 22:18:43 :: [ 16250] return 0/0/0 async 0/0/0
char.cpp Sonitex rehberi:
//EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
#include "private_shop_manager.h"
#include "private_shop.h"
#include "private_shop_util.h"
#endif
//ARA :
m_iSyncHackCount = 0;
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
m_pPrivateShop = nullptr;
m_pMyPrivateShop = nullptr;
m_dwPrivateShopOwner = 0;
m_bIsEditingPrivateShop = false;
memset(&m_privateShopTable, 0, sizeof(TPrivateShop));
m_bShopSearchMode = MODE_NONE;
m_tLastPrivateShopModify = 0;
m_tLastPrivateShopWithdraw = 0;
m_tLastPrivateShopClose = 0;
m_tLastPrivateShopBuild = 0;
m_tLastPrivateShopBuy = 0;
m_tLastPrivateShopSearch = 0;
m_tLastPrivateShopStateChange = 0;
#endif
//ARA :
if (GetArena() != NULL)
{
GetArena()->OnDisconnect(GetPlayerID());
}
//ÜSTÜNE EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (GetViewingPrivateShop())
{
GetViewingPrivateShop()->RemoveShopViewer(this);
SetViewingPrivateShop(nullptr);
}
// @note: DB does not get notified about characters disconnect when a player is going back to
// the select character window.
if (IsPrivateShopOwner() && strcmp(c_pszReason, "timed_event - SCMD_PHASE_SELECT") == 0)
{
// Update db
BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_LOGOUT;
DWORD dwPID = GetPlayerID();
db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
db_clientdesc->Packet(&dwPID, sizeof(DWORD));
}
#endif
//ARA :
if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen())
return false;
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (GetViewingPrivateShop() || IsEditingPrivateShop() || IsShopSearch())
return false;
#endif
//EN SONA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
bool CHARACTER::BuildPrivateShop(const char* c_szTitle, DWORD dwPolyVnum, BYTE bTitleType, BYTE bPageCount, WORD wItemCount, TPrivateShopItem* pShopItemTable)
{
if (!CanHandleItem())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot use a personal shop now."));
return false;
}
if (!CountSpecifyItem(50200) && !CountSpecifyItem(71221))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot open a personal shop without a Bundle."));
return false;
}
if ((dwPolyVnum > 30000 || bTitleType > 0) && !CountSpecifyItem(71221))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot open a personal shop without a Bundle."));
return false;
}
if (IsPrivateShopOwner())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have already opened your personal shop."));
return false;
}
if (GetDungeon())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot open a personal shop in a dungeon."));
return false;
}
if (m_pkExchange)
m_pkExchange->Cancel();
quest::PC* pPC = quest::CQuestManager::instance().GetPCForce(GetPlayerID());
if (pPC->IsRunning())
return false;
if (wItemCount == 0)
{
sys_err("Item count is equal to zero for player %d", GetPlayerID());
return false;
}
if (CBanwordManager::instance().CheckString(c_szTitle, strlen(c_szTitle)))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Please choose another title name for your personal shop."));
return false;
}
if (strlen(c_szTitle) < TITLE_MIN_LEN)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The entered name is too short."));
return false;
}
std::vector<TPrivateShopItem> s_vec_shopItem;
std::set<TItemPos> s_set_item;
for (BYTE i = 0; i < wItemCount; ++i, ++pShopItemTable)
{
if (s_set_item.find(pShopItemTable->TPos) != s_set_item.end())
{
sys_err("Duplicated item in private shop detected! (name: %s)", GetName());
return false;
}
const LPITEM pItem = GetItem(pShopItemTable->TPos);
if (!pItem)
{
sys_err("Could not find an item in position: %d", pShopItemTable->TPos.cell);
return false;
}
if (pItem->GetVnum() == 50200 || pItem->GetVnum() == 71221)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot put Bundles items in a personal shop when building it."));
return false;
}
const TItemTable* pItemTable = pItem->GetProto();
if (!pItemTable)
{
sys_err("Could not find an item table for an item at position: %d vnum: %d", pShopItemTable->TPos.cell, pItem->GetVnum());
return false;
}
if (pItemTable && (IS_SET(pItemTable->dwAntiFlags, ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MYSHOP)))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot sell Item-Shop items in a personal shop."));
return false;
}
if (pItem->IsEquipped())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot sell equipped items in a personal shop."));
return false;
}
#ifdef WJ_SOULBINDING_SYSTEM
if (pItem->IsBind() || pItem->IsUntilBind())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't sell this item because is binded!"));
return false;
}
#endif
if (pItem->isLocked())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot sell locked items in a personal shop."));
return false;
}
if (pShopItemTable->TPrice.llGold < 0)
{
sys_err("Player %u is trying to build private shop with negative prices", GetPlayerID());
return false;
}
pItem->Lock(true);//Darklovers_Fix_Offline_Shop
s_set_item.insert(pShopItemTable->TPos);
s_vec_shopItem.push_back(*pShopItemTable);
}
if (dwPolyVnum < 30000 || dwPolyVnum > 30008)
dwPolyVnum = 30000;
if (CPrivateShopManager::Instance().BuildPrivateShop(this, c_szTitle, dwPolyVnum, bTitleType, bPageCount, s_vec_shopItem))
{
{
if (dwPolyVnum != 30000 || bTitleType != 0 || bPageCount == PRIVATE_SHOP_PAGE_MAX_NUM)
RemoveSpecifyItem(71221);
else
RemoveSpecifyItem(50200);
}
}
return true;
}
void CHARACTER::ClosePrivateShop()
{
memset(&m_privateShopTable, 0, sizeof(m_privateShopTable));
m_vec_privateShopItem.clear();
ClosePrivateShopPanel();
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_CLOSE;
GetDesc()->Packet(&mainPacket, sizeof(mainPacket));
}
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Your personal shop has been closed."));
}
void CHARACTER::SetPrivateShopTable(const TPrivateShop& rPrivateShopTable)
{
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPacketGCPrivateShopLoad);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_LOAD;
TPacketGCPrivateShopLoad subPacket{};
strlcpy(subPacket.szTitle, rPrivateShopTable.szTitle, sizeof(subPacket.szTitle));
subPacket.llGold = rPrivateShopTable.llGold;
subPacket.dwCheque = rPrivateShopTable.dwCheque;
subPacket.lX = rPrivateShopTable.lX;
subPacket.lY = rPrivateShopTable.lY;
subPacket.bChannel = rPrivateShopTable.bChannel;
subPacket.bState = rPrivateShopTable.bState;
subPacket.bPageCount = rPrivateShopTable.bPageCount;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPacketGCPrivateShopLoad));
}
m_privateShopTable = rPrivateShopTable;
}
void CHARACTER::OpenPrivateShopPanel()
{
if (GetViewingPrivateShop())
GetViewingPrivateShop()->RemoveShopViewer(this);
SetEditingPrivateShop(true);
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_OPEN_PANEL;
GetDesc()->Packet(&mainPacket, sizeof(mainPacket));
}
}
void CHARACTER::ClosePrivateShopPanel(bool bSendClient /* = false */)
{
if (!IsEditingPrivateShop())
return;
SetEditingPrivateShop(false);
SetMyShopTime();
if (bSendClient)
{
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_CLOSE_PANEL;
GetDesc()->Packet(&mainPacket, sizeof(mainPacket));
}
}
}
long long CHARACTER::GetPrivateShopTotalGold()
{
long long llGold = GetPrivateShopTable()->llGold;
for (const auto& rShopItem : m_vec_privateShopItem)
llGold += rShopItem.TPrice.llGold;
return llGold;
}
DWORD CHARACTER::GetPrivateShopTotalCheque()
{
long long dwCheque = GetPrivateShopTable()->dwCheque;
for (const auto& rShopItem : m_vec_privateShopItem)
dwCheque += rShopItem.TPrice.dwCheque;
return dwCheque;
}
void CHARACTER::SetPrivateShopItem(const TPlayerPrivateShopItem& c_rPrivateShopItem)
{
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPrivateShopItemData);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_SET_ITEM;
TPrivateShopItemData subPacket{};
CopyItemData(c_rPrivateShopItem, subPacket);
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPrivateShopItemData));
}
m_vec_privateShopItem.push_back(c_rPrivateShopItem);
}
bool CHARACTER::RemovePrivateShopItem(WORD wPos)
{
for (auto it = m_vec_privateShopItem.begin(); it != m_vec_privateShopItem.end(); ++it)
{
const TPlayerPrivateShopItem& r_shopItem = *it;
if (r_shopItem.wPos == wPos)
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(WORD);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_REMOVE_MY_ITEM;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&wPos, sizeof(WORD));
m_vec_privateShopItem.erase(it);
return true;
}
}
return false;
}
const TPlayerPrivateShopItem* CHARACTER::GetPrivateShopItem(WORD wPos)
{
for (auto it = m_vec_privateShopItem.begin(); it != m_vec_privateShopItem.end(); ++it)
{
const TPlayerPrivateShopItem& rShopItem = *it;
if (rShopItem.wPos == wPos)
return &rShopItem;
}
return nullptr;
}
void CHARACTER::ChangePrivateShopItemPrice(WORD wPos, long long llGold, DWORD dwCheque)
{
for (auto it = m_vec_privateShopItem.begin(); it != m_vec_privateShopItem.end(); ++it)
{
TPlayerPrivateShopItem& r_shopItem = *it;
if (r_shopItem.wPos == wPos)
{
// Update prices of the item
r_shopItem.TPrice.llGold = llGold;
r_shopItem.TPrice.dwCheque = dwCheque;
// Send information to client
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPacketGCPrivateShopItemPriceChange);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_ITEM_PRICE_CHANGE;
TPacketGCPrivateShopItemPriceChange subPacket{};
subPacket.wPos = wPos;
subPacket.TPrice.llGold = llGold;
subPacket.TPrice.dwCheque = dwCheque;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPacketGCPrivateShopItemPriceChange));
break;
}
}
}
void CHARACTER::ChangePrivateShopItemPos(WORD wPos, WORD wChangePos)
{
for (auto it = m_vec_privateShopItem.begin(); it != m_vec_privateShopItem.end(); ++it)
{
TPlayerPrivateShopItem& r_shopItem = *it;
if (r_shopItem.wPos == wPos)
{
// Update position of the item
r_shopItem.wPos = wChangePos;
// Send information to client
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPacketGCPrivateShopItemMove);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_ITEM_MOVE;
TPacketGCPrivateShopItemMove subPacket{};
subPacket.wPos = wPos;
subPacket.wChangePos = wChangePos;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPacketGCPrivateShopItemMove));
break;
}
}
}
void CHARACTER::ChangePrivateShopTitle(const char* c_szTitle)
{
strlcpy(m_privateShopTable.szTitle, c_szTitle, sizeof(m_privateShopTable.szTitle));
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(m_privateShopTable.szTitle);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_TITLE_CHANGE;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&m_privateShopTable.szTitle, sizeof(m_privateShopTable.szTitle));
}
}
void CHARACTER::SaleUpdate(const TPlayerPrivateShopItem& c_rPrivateShopItem, const char* c_szCustomerName)
{
const TPlayerPrivateShopItem* pShopItem = GetPrivateShopItem(c_rPrivateShopItem.wPos);
if (pShopItem)
{
// Update the stash values at table
GetPrivateShopTable()->llGold += c_rPrivateShopItem.TPrice.llGold;
GetPrivateShopTable()->dwCheque += c_rPrivateShopItem.TPrice.dwCheque;
// Remove the bought item
RemovePrivateShopItem(c_rPrivateShopItem.wPos);
// Send the balance update
if (GetDesc())
{
// Send a notification to the player
TItemTable* pItemTable = ITEM_MANAGER::Instance().GetTable(c_rPrivateShopItem.dwVnum);
if (pItemTable)
{
char szMsg[256 + 1]{};
int len = 0;
#ifdef WJ_PRIVATE_SHOP_CHEQUE
{
len = snprintf(szMsg, sizeof(szMsg), LC_TEXT("You have sold x%d %s for %s Yangs and %s Wons."),
c_rPrivateShopItem.dwCount, pItemTable->szLocaleName,
format_number(c_rPrivateShopItem.TPrice.llGold).c_str(), format_number(c_rPrivateShopItem.TPrice.dwCheque).c_str());
}
#else
{
len = snprintf(szMsg, sizeof(szMsg), LC_TEXT("You have sold x%d %s for %s Yangs."),
c_rPrivateShopItem.dwCount, pItemTable->szLocaleName, format_number(c_rPrivateShopItem.TPrice.llGold).c_str());
}
#endif
TPacketGCWhisper packet{};
packet.bHeader = HEADER_GC_WHISPER;
packet.wSize = sizeof(TPacketGCWhisper) + len;
packet.bType = EWhisperType::WHISPER_TYPE_SYSTEM;
strlcpy(packet.szNameFrom, "Private Shop", sizeof(packet.szNameFrom));
TEMP_BUFFER buf;
buf.write(&packet, sizeof(packet));
buf.write(szMsg, len);
GetDesc()->Packet(buf.read_peek(), buf.size());
}
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPacketGCPrivateShopBalanceUpdate);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_BALANCE_UPDATE;
TPacketGCPrivateShopBalanceUpdate subPacket{};
subPacket.TPrice = c_rPrivateShopItem.TPrice;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPacketGCPrivateShopBalanceUpdate));
}
}
}
void CHARACTER::ItemExpireUpdate(WORD wPos)
{
const TPlayerPrivateShopItem* pShopItem = GetPrivateShopItem(wPos);
if (!pShopItem)
{
sys_err("Could not find item on pos %u for player %u", wPos, GetPlayerID());
return;
}
// Send a notification to the player
TItemTable* pItemTable = ITEM_MANAGER::Instance().GetTable(pShopItem->dwVnum);
if (pItemTable)
{
char szMsg[128 + 1]{};
int len = snprintf(szMsg, sizeof(szMsg), LC_TEXT("%s has been removed from the shop as the time has expired."),
pItemTable->szLocaleName);
TPacketGCWhisper packet{};
packet.bHeader = HEADER_GC_WHISPER;
packet.wSize = sizeof(TPacketGCWhisper) + len;
packet.bType = EWhisperType::WHISPER_TYPE_SYSTEM;
strlcpy(packet.szNameFrom, "Private Shop", sizeof(packet.szNameFrom));
TEMP_BUFFER buf;
buf.write(&packet, sizeof(packet));
buf.write(szMsg, len);
GetDesc()->Packet(buf.read_peek(), buf.size());
}
RemovePrivateShopItem(wPos);
}
void CHARACTER::SetPrivateShopState(BYTE bState, bool bIsMainPlayerPrivateShop)
{
if (bIsMainPlayerPrivateShop)
GetPrivateShopTable()->bState = bState;
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop) + sizeof(TPacketGCPrivateStateUpdate);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_STATE_UPDATE;
TPacketGCPrivateStateUpdate subPacket{};
subPacket.bState = bState;
subPacket.bIsMainPlayerPrivateShop = bIsMainPlayerPrivateShop;
GetDesc()->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
GetDesc()->Packet(&subPacket, sizeof(TPacketGCPrivateStateUpdate));
}
}
void CHARACTER::WithdrawPrivateShop(long long llGold, DWORD dwCheque)
{
if (llGold != GetPrivateShopTable()->llGold || dwCheque != GetPrivateShopTable()->dwCheque)
{
sys_err("Withdraw values mismatch gold: %lld | %lld cheque: %u | %u for player %u", llGold, GetPrivateShopTable()->llGold, dwCheque, GetPrivateShopTable()->dwCheque, GetPlayerID());
return;
}
long long llCurrentGold = static_cast<long long>(GetGold());
#ifdef WJ_PRIVATE_SHOP_CHEQUE
DWORD dwCurrentCheque = GetCheque();
#endif
if ((llCurrentGold + GetPrivateShopTable()->llGold) >= GOLD_MAX)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot collect the money, because you would then have more than 2 billion Yang."));
return;
}
#ifdef WJ_PRIVATE_SHOP_CHEQUE
if ((dwCurrentCheque + GetPrivateShopTable()->dwCheque) > CHEQUE_MAX)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot collect the money, because you would then have more than 999 Won."));
return;
}
#endif
PointChange(POINT_GOLD, GetPrivateShopTable()->llGold);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
PointChange(POINT_CHEQUE, GetPrivateShopTable()->dwCheque);
#endif
if (GetPrivateShopTable()->llGold && GetPrivateShopTable()->dwCheque <= 0)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have withdrawn %lld Yang from your personal shop earnings."), GetPrivateShopTable()->llGold);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
else if (GetPrivateShopTable()->dwCheque && GetPrivateShopTable()->llGold <= 0)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have withdrawn %u Won from your personal shop earnings."), GetPrivateShopTable()->dwCheque);
else if(GetPrivateShopTable()->llGold && GetPrivateShopTable()->dwCheque)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have withdrawn %lld Yang and %u Won from your personal shop earnings."), GetPrivateShopTable()->llGold, GetPrivateShopTable()->dwCheque);
#endif
sys_log(0, "%s PRIVATE_SHOP: WITHDRAW GOLD %lld CHEQUE %u", GetName(), GetPrivateShopTable()->llGold, GetPrivateShopTable()->dwCheque);
char szHint[128 + 1] {};
snprintf(szHint, sizeof(szHint), "Gold %lld Cheque %u", GetPrivateShopTable()->llGold, GetPrivateShopTable()->dwCheque);
LogManager::Instance().CharLog(this, 0, "PRIVATE SHOP WITHDRAW", szHint);
GetPrivateShopTable()->llGold = 0;
GetPrivateShopTable()->dwCheque = 0;
// Update the value on client-side
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop);
mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_WITHDRAW;
GetDesc()->Packet(&mainPacket, sizeof(TPacketGCPrivateShop));
}
// Update the value on db
BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_WITHDRAW;
DWORD dwPID = GetPlayerID();
db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
db_clientdesc->Packet(&dwPID, sizeof(DWORD));
}
void CHARACTER::OpenShopSearch(BYTE bMode)
{
if (!CheckTradeWindows(this))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot trade while another window is open."));
return;
}
m_bShopSearchMode = bMode;
if (GetDesc())
{
TPacketGCPrivateShop mainPacket{};
mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
mainPacket.wSize = sizeof(TPacketGCPrivateShop);
mainPacket.bSubHeader = (bMode == MODE_LOOKING ? SUBHEADER_GC_PRIVATE_SHOP_SEARCH_OPEN_LOOK_MODE : SUBHEADER_GC_PRIVATE_SHOP_SEARCH_OPEN_TRADE_MODE);
GetDesc()->Packet(&mainPacket, sizeof(mainPacket));
}
}
void CHARACTER::CloseShopSearch()
{
m_bShopSearchMode = MODE_NONE;
}
bool CHARACTER::SetPremiumPrivateShopBonus(time_t tDuration)
{
if (!GetDesc())
return false;
CAffect* pAffect = FindAffect(AFFECT_PREMIUM_PRIVATE_SHOP);
if (pAffect)
{
tDuration = std::min<time_t>(tDuration + pAffect->lDuration, PRIVATE_SHOP_MAX_PREMIUM_TIME);
// Return if player has reached limit moments ago
if (PRIVATE_SHOP_MAX_PREMIUM_TIME - pAffect->lDuration < 60)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have just recently reached maximum premium time for your personal shop. "));
return false;
}
}
// Old affect will be removed by AddAffect
AddAffect(AFFECT_PREMIUM_PRIVATE_SHOP, POINT_NONE, 0, 0, tDuration, 0, true);
m_aiPremiumTimes[PREMIUM_PRIVATE_SHOP] = tDuration + time(0);
// Update db
BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_PREMIUM_TIME_UPDATE;
TPacketGDPrivateShopPremiumTimeUpdate packet{};
packet.dwAID = GetDesc()->GetAccountTable().id;
packet.dwPID = GetPlayerID();
packet.tPremiumTime = tDuration;
db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketGDPrivateShopPremiumTimeUpdate));
db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
db_clientdesc->Packet(&packet, sizeof(TPacketGDPrivateShopPremiumTimeUpdate));
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have increased Premium Personal Shop duration."));
// Warn the player about time limit
if (tDuration == PRIVATE_SHOP_MAX_PREMIUM_TIME)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have reached maximum premium time for your personal shop. "));
char szHint[128 + 1]{};
snprintf(szHint, sizeof(szHint), "+%u", tDuration);
LogManager::Instance().CharLog(this, 0, "PRIVATE SHOP PREMIUM TIME", szHint);
return true;
}
#endif
char_item.cpp Sonitex Rehberi:
//ARA :
case 50200:
if (g_bEnableBootaryCheck)
{
if (IS_BOTARYABLE_ZONE(GetMapIndex()) == true)
{
__OpenPrivateShop();
}
else
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개인 상점을 열 수 없는 지역입니다"));
}
}
else
{
__OpenPrivateShop();
}
break;
//DEĞİŞTİR :
case 50200:
if (g_bEnableBootaryCheck)
{
if (IS_BOTARYABLE_ZONE(GetMapIndex()) == true)
{
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (IsPrivateShopOwner())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Close your current personal shop before opening a new one."));
return false;
}
OpenPrivateShopPanel();
#else
__OpenPrivateShop();
#endif
}
else
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개인 상점을 열 수 없는 지역입니다"));
}
}
else
{
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (IsPrivateShopOwner())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Close your current personal shop before opening a new one."));
return false;
}
OpenPrivateShopPanel();
#else
__OpenPrivateShop();
#endif
}
break;
#ifdef WJ_PREMIUM_PRIVATE_SHOP
case 71221:
{
if (IsPrivateShopOwner())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Close your current personal shop before opening a new one."));
return false;
}
OpenPrivateShopPanel();
ChatPacket(CHAT_TYPE_COMMAND, "SetPrivateShopPremiumBuild");
}
break;
case 60004:
{
OpenShopSearch(MODE_LOOKING);
}
break;
case 60005:
{
OpenShopSearch(MODE_TRADING);
}
break;
#endif
//ARA :
if (FindAffect(item->GetValue(0), aApplyInfo[item->GetValue(1)].bPointType))
//ÜSTÜNE EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (item->GetValue(0) == AFFECT_PREMIUM_PRIVATE_SHOP)
{
if (SetPremiumPrivateShopBonus(item->GetValue(3)))
item->SetCount(item->GetCount() - 1);
return true;
}
#endif
//ARA :
sys_log(0, "%s: USE_ITEM %s (inven %d, cell: %d)", GetName(), item->GetName(), window_type, wCell);
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (IsEditingPrivateShop())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot use items while editing your personal shop."));
return false;
}
#endif
//ARA :
if (!IsValidItemPosition(DestCell))
{
return false;
}
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (IsEditingPrivateShop())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot move items while your personal shop window is open."));
return false;
}
#endif
//ARA :
if (IsWarping()) return false;
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
if (IsEditingPrivateShop() || IsShopSearch() || GetMyPrivateShop()) return false;
#endif
char.h Sonitex Rehberi:
//EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
#include "packet.h"
#endif
//ARA :
class CPetSystem;
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
class CPrivateShop;
#endif
//ARA :
#ifdef __PET_SYSTEM__
public:
CPetSystem* GetPetSystem() { return m_petSystem; }
protected:
CPetSystem* m_petSystem;
public:
#endif
//ALTINA EKLE :
#ifdef WJ_PREMIUM_PRIVATE_SHOP
private:
LPPRIVATE_SHOP m_pPrivateShop;
LPPRIVATE_SHOP m_pMyPrivateShop;
DWORD m_dwPrivateShopOwner;
TPrivateShop m_privateShopTable;
bool m_bIsEditingPrivateShop;
BYTE m_bShopSearchMode;
time_t m_tLastPrivateShopModify;
time_t m_tLastPrivateShopWithdraw;
time_t m_tLastPrivateShopClose;
time_t m_tLastPrivateShopBuy;
time_t m_tLastPrivateShopSearch;
time_t m_tLastPrivateShopStateChange;
time_t m_tLastPrivateShopBuild;
std::vector<TPlayerPrivateShopItem> m_vec_privateShopItem;
public:
bool BuildPrivateShop(const char* c_szTitle, DWORD dwPolyVnum, BYTE bTitleType, BYTE bPageCount, WORD wItemCount, TPrivateShopItem* pShopItemTable);
void ClosePrivateShop();
void SetViewingPrivateShop(LPPRIVATE_SHOP pShop) { m_pPrivateShop = pShop; }
LPPRIVATE_SHOP GetViewingPrivateShop() const { return m_pPrivateShop; }
void SetMyPrivateShop(LPPRIVATE_SHOP pShop) { m_pMyPrivateShop = pShop; }
LPPRIVATE_SHOP GetMyPrivateShop() const { return m_pMyPrivateShop; }
void SetPrivateShopOwner(DWORD dwPID) { m_dwPrivateShopOwner = dwPID; }
DWORD GetPrivateShopOwner() { return m_dwPrivateShopOwner; }
void SetPrivateShopTable(const TPrivateShop& rPrivateShopTable);
TPrivateShop* GetPrivateShopTable() { return &m_privateShopTable; }
bool IsPrivateShopOwner() { return m_privateShopTable.dwOwner != 0; }
bool CanModifyPrivateShop() { return m_privateShopTable.bState == STATE_MODIFY; }
void SetEditingPrivateShop(bool bEditingPrivateShop) { m_bIsEditingPrivateShop = bEditingPrivateShop; }
bool IsEditingPrivateShop() const { return m_bIsEditingPrivateShop; }
void OpenPrivateShopPanel();
void ClosePrivateShopPanel(bool bSendClient = false);
void OpenShopSearch(BYTE bMode);
void CloseShopSearch();
bool IsShopSearch() const { return m_bShopSearchMode != MODE_NONE; }
BYTE GetShopSearchMode() { return m_bShopSearchMode; }
long long GetPrivateShopTotalGold();
DWORD GetPrivateShopTotalCheque();
void SetPrivateShopItem(const TPlayerPrivateShopItem& c_rPrivateShopItem);
bool RemovePrivateShopItem(WORD wPos);
const TPlayerPrivateShopItem* GetPrivateShopItem(WORD wPos);
WORD GetPrivateShopItemCount() { return m_vec_privateShopItem.size(); }
void ChangePrivateShopItemPrice(WORD wPos, long long llGold, DWORD dwCheque);
void ChangePrivateShopItemPos(WORD wPos, WORD wChangePos);
void ChangePrivateShopTitle(const char* c_szTitle);
void SaleUpdate(const TPlayerPrivateShopItem& c_rPrivateShopItem, const char* c_szCustomerName);
void ItemExpireUpdate(WORD wPos);
void SetPrivateShopState(BYTE bState, bool bIsMainPlayerPrivateShop);
void WithdrawPrivateShop(long long llGold, DWORD dwCheque);
bool SetPremiumPrivateShopBonus(time_t tDuration);
int GetLastPrivateShopModifyTime() const { return m_tLastPrivateShopModify; }
void SetLastPrivateShopModifyTime() { m_tLastPrivateShopModify = thecore_pulse(); }
int GetLastPrivateShopWithdrawTime() const { return m_tLastPrivateShopWithdraw; }
void SetLastPrivateShopWithdrawTime() { m_tLastPrivateShopWithdraw = thecore_pulse(); }
int GetLastPrivateShopCloseTime() const { return m_tLastPrivateShopClose; }
void SetLastPrivateShopCloseTime() { m_tLastPrivateShopClose = thecore_pulse(); }
int GetLastPrivateShopBuildTime() const { return m_tLastPrivateShopBuild; }
void SetLastPrivateShopBuildTime() { m_tLastPrivateShopBuild = thecore_pulse(); }
int GetLastPrivateShopBuyTime() const { return m_tLastPrivateShopBuy; }
void SetLastPrivateShopBuyTime() { m_tLastPrivateShopBuy = thecore_pulse(); }
int GetLastPrivateShopSearchTime() const { return m_tLastPrivateShopSearch; }
void SetLastPrivateShopSearchTime() { m_tLastPrivateShopSearch = thecore_pulse(); }
int GetLastPrivateShopStateChangeTime() const { return m_tLastPrivateShopStateChange; }
void SetLastPrivateShopStateChangeTime() { m_tLastPrivateShopStateChange = thecore_pulse(); }
#endif
desc_client.cpp:
#ifdef WJ_PREMIUM_PRIVATE_SHOP
pck.dwPID = d->GetCharacter() ? d->GetCharacter()->GetPlayerID() : 0;
pck.dwHandle = d->GetHandle();
pck.bHasPrivateShop = (d->GetCharacter() && d->GetCharacter()->IsPrivateShopOwner()) ? true : false;
#endif
Son düzenleme: