-
Activity
-
3
Once upon a time...
Im also curios what you accomplished on minecraft , if you programmed some crazy-ass servers - because that game is a lot more friendly if you want to mod it. -
1183
[40250] Reference Serverfile + Client + Src [15 Available Languages]
I can t start it. every time I receive connection refused. freebsd is 13.1 x64,I installed all libs,sv,mysql instaled,but I receive connection refused.... syser db can help me please? -
3
Once upon a time...
I have to continue this story, I have to write the chapter 2021 and 2022... Because 2023, you are his story!- 1
-
-
3
Once upon a time...
Great story! Glad you ended up doing what you were so passionate about! And I think this is the most professional managed community I have ever been a part of.- 1
-
-
1
-
0
problem ability
Hello guys, i have a problem with "refine-ability" a new ability with book [Hidden Content] (this is the book) [Hidden Content] (ability) when I try to read the book nothing happens sysser client 0325 21:21:15437 :: Traceback (most recent call last): 0325 21:21:15437 :: File "game.py", line 759, in BINARY_NEW_AddAffect 0325 21:21:15438 :: File "uiAffectShower.py", line 524, in BINARY_NEW_AddAffect 0325 21:21:15438 :: File "localeInfo.py", line 137, in f 0325 21:21:15438 :: TypeError 0325 21:21:15438 :: : 0325 21:21:15438 :: not all arguments converted during string formatting 0325 21:21:15438 :: 0325 21:23:21014 :: Traceback (most recent call last): 0325 21:23:21014 :: File "ui.py", line 1487, in OnOverInItem 0325 21:23:21014 :: File "ui.py", line 87, in __call__ 0325 21:23:21015 :: File "ui.py", line 78, in __call__ 0325 21:23:21015 :: File "uiCharacter.py", line 649, in OverInItem 0325 21:23:21015 :: File "uiToolTip.py", line 1872, in SetSkillNew 0325 21:23:21015 :: File "uiToolTip.py", line 2245, in AppendPartySkillData 0325 21:23:21015 :: ValueError 0325 21:23:21015 :: : 0325 21:23:21015 :: unsupported format character ',' (0x2c) at index 32 0325 21:23:21015 :: -
0
Transmutation system error "unknow command server"
I entered the official transmutation/change look system but get a communication error with the server. I checked quest, questlua_game, quest_function, game.py but can't figure it out. [Hidden Content] SYSERR: 0325 19:42:31105 :: Unknown Server Command ShowChangeDialog 1 | ShowChangeDialog Thanks for helping -
39
official Official Transmutation / Change Look
Help please [Hidden Content] 0325 19:42:31105 :: Unknown Server Command ShowChangeDialog 1 | ShowChangeDialog -
-
-
Recently Browsing
- No registered users viewing this page.
Question
gummyantifi 2
Hello people,
I have a little problem with offline business.
I create a stand. I will put one item. A shop is created.
I open the stand and empty.
(MySQL to write vnum 0)
and
I'll offline administration.
I'll add the item.
and everything is fine.
but
if I set up shop offline and in the establishment will put more than one item.
Kicks me out of the game.
Do you know where I have a problem?
Offline_shop.cpp
/*
* Filename : offline_shop.cpp
* Version : 0.1
* Description : --
*/
#include "stdafx.h"
#include "../../libgame/include/grid.h"
#include "constants.h"
#include "utils.h"
#include "config.h"
#include "desc.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "item.h"
#include "item_manager.h"
#include "buffer_manager.h"
#include "packet.h"
#include "log.h"
#include "db.h"
#include "questmanager.h"
#include "monarch.h"
#include "mob_manager.h"
#include "locale_service.h"
#include "offline_shop.h"
#include "p2p.h"
COfflineShop::COfflineShop() : m_pkOfflineShopNPC(NULL)
{
m_pGrid = M2_NEW CGrid(12, 10);
}
COfflineShop::~COfflineShop()
{
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_END;
pack.size = sizeof(TPacketGCShop);
Broadcast(&pack, sizeof(pack));
for (GuestMapType::iterator it = m_map_guest.begin(); it != m_map_guest.end(); ++it)
{
LPCHARACTER ch = it->first;
ch->SetOfflineShop(NULL);
}
M2_DELETE(m_pGrid);
}
void COfflineShop::SetOfflineShopNPC(LPCHARACTER npc)
{
m_pkOfflineShopNPC = npc;
}
bool COfflineShop::AddGuest(LPCHARACTER ch, LPCHARACTER npc)
{
// If there is no ch, return false
if (!ch)
return false;
// If ch is exchanging, return false
if (ch->GetExchange())
return false;
// If target is shopping, return false
if (ch->GetShop())
return false;
// If target is look at private shop, return false
if (ch->GetMyShop())
return false;
// If target is look at offline shop, return false
if (ch->GetOfflineShop())
return false;
// Start process
ch->SetOfflineShop(this);
m_map_guest.insert(GuestMapType::value_type(ch, false));
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_START;
TPacketGCOfflineShopStart pack2;
memset(&pack2, 0, sizeof(pack2));
pack2.owner_vid = npc->GetVID();
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), npc ? npc->GetOfflineShopRealOwner() : 0));
if (pMsg->Get()->uiNumRows == 0)
{
DBManager::instance().DirectQuery("DELETE FROM player_2.offline_shop_npc WHERE owner_id = %u", npc->GetOfflineShopRealOwner());
ch->SetOfflineShop(NULL);
ch->SetOfflineShopOwner(NULL);
M2_DESTROY_CHARACTER(npc);
return false;
}
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
BYTE bPos = 0;
str_to_number(bPos, row[0]);
str_to_number(pack2.items[bPos].count, row[1]);
str_to_number(pack2.items[bPos].vnum, row[2]);
str_to_number(pack2.items[bPos].price, row[3]);
DWORD alSockets[ITEM_SOCKET_MAX_NUM];
for (int i = 0, n = 4; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(alSockets, row[n]);
TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
for (int i = 0, iStartType = 7, iStartValue = 8; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartType += 2, iStartValue += 2)
{
str_to_number(aAttr.bType, row[iStartType]);
str_to_number(aAttr.sValue, row[iStartValue]);
}
thecore_memcpy(pack2.items[bPos].alSockets, alSockets, sizeof(pack2.items[bPos].alSockets));
thecore_memcpy(pack2.items[bPos].aAttr, aAttr, sizeof(pack2.items[bPos].aAttr));
}
pack.size = sizeof(pack) + sizeof(pack2);
ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCOfflineShopStart));
return true;
}
void COfflineShop::RemoveGuest(LPCHARACTER ch)
{
// If this offline shop is not equal to this, break it
if (ch->GetOfflineShop() != this)
return;
m_map_guest.erase(ch);
ch->SetOfflineShop(NULL);
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_END;
pack.size = sizeof(TPacketGCShop);
ch->GetDesc()->Packet(&pack, sizeof(pack));
}
void COfflineShop::RemoveAllGuest()
{
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_END;
pack.size = sizeof(TPacketGCShop);
Broadcast(&pack, sizeof(pack));
for (GuestMapType::iterator it = m_map_guest.begin(); it != m_map_guest.end(); ++it)
{
LPCHARACTER ch = it->first;
ch->SetOfflineShop(NULL);
}
}
void COfflineShop::Destroy(LPCHARACTER npc)
{
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), npc->GetOfflineShopRealOwner());
RemoveAllGuest();
M2_DESTROY_CHARACTER(npc);
}
int COfflineShop::Buy(LPCHARACTER ch, BYTE bPos)
{
if (ch->GetOfflineShopOwner()->GetOfflineShopRealOwner() == ch->GetPlayerID())
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu poti sa cumperi din propriul magazin offline.");
return SHOP_SUBHEADER_GC_OK;
}
if (bPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
{
sys_log(0, "OfflineShop::Buy : invalid position %d : %s", bPos, ch->GetName());
return SHOP_SUBHEADER_GC_INVALID_POS;
}
sys_log(0, "OfflineShop::Buy : name %s pos %d", ch->GetName(), bPos);
GuestMapType::iterator it = m_map_guest.find(ch);
if (it == m_map_guest.end())
return SHOP_SUBHEADER_GC_END;
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetOfflineShopOwner()->GetOfflineShopRealOwner(), bPos);
std::auto_ptr<SQLMsg> pMsg(DBManager::Instance().DirectQuery(szQuery));
MYSQL_ROW row;
DWORD dwPrice = 0;
DWORD dwItemVnum = 0;
BYTE bCount = 0;
DWORD alSockets[ITEM_SOCKET_MAX_NUM];
TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
str_to_number(bCount, row[1]);
str_to_number(dwItemVnum, row[2]);
str_to_number(dwPrice, row[3]);
// Set Sockets
for (int i = 0, n = 4; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(alSockets, row[n]);
// End Of Sockets
// Set Attributes
for (int i = 0, iStartAttributeType = 7, iStartAttributeValue = 8; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartAttributeType += 2, iStartAttributeValue += 2)
{
str_to_number(aAttr.bType, row[iStartAttributeType]);
str_to_number(aAttr.sValue, row[iStartAttributeValue]);
}
// End Of Set Attributes
}
// Brazil server is not use gold option.
if (!LC_IsBrazil())
{
if (ch->GetGold() < static_cast<int>(dwPrice))
{
sys_log(1, "OfflineShop::Buy : Not enough money : %s has %u, price %u", ch->GetName(), ch->GetGold(), dwPrice);
return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
}
}
else
{
int iItemCount = quest::CQuestManager::instance().GetCurrentCharacterPtr()->CountSpecifyItem(30183);
if (iItemCount < static_cast<int>(dwPrice))
{
sys_log(1, "OfflineShop::Buy : Not enough gold mask : %s has %d, gold mask %u", ch->GetName(), iItemCount, dwPrice);
return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
}
}
LPITEM pItem = ITEM_MANAGER::Instance().CreateItem(dwItemVnum, bCount);
if (!pItem)
return SHOP_SUBHEADER_GC_SOLD_OUT;
// Set Attributes, Sockets
pItem->SetAttributes(aAttr);
for (BYTE i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
pItem->SetSocket(i, alSockets);
// End Of Set Attributes, Sockets
// If item is a dragon soul item or normal item
int iEmptyPos = 0;
if (pItem->IsDragonSoul())
iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
else
iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
// If iEmptyPos is less than 0, return inventory is full
if (iEmptyPos < 0)
return SHOP_SUBHEADER_GC_INVENTORY_FULL;
// If item is a dragon soul, add this item in dragon soul inventory
if (pItem->IsDragonSoul())
pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
pItem->AddToCharacter(ch, TItemPos(INVENTORY,iEmptyPos));
if (pItem)
sys_log(0, "OFFLINE_SHOP: BUY: name %s %s(x %u):%u price %u", ch->GetName(), pItem->GetName(), pItem->GetCount(), pItem->GetID(), dwPrice);
// Check if the player is online
LPCHARACTER tch = CHARACTER_MANAGER::instance().FindByPID(ch->GetOfflineShopOwner()->GetOfflineShopRealOwner());
if (!LC_IsBrazil())
{
if (tch)
{
bool bIsOverFlow = tch->GetGold() + dwPrice > GOLD_MAX - 1 ? true : false;
if (bIsOverFlow)
DBManager::instance().DirectQuery("UPDATE player_2.player SET money = money + %u WHERE id = %u", dwPrice, tch->GetPlayerID());
else
tch->PointChange(POINT_GOLD, dwPrice, false);
}
else
DBManager::instance().DirectQuery("UPDATE player_2.player SET money = money + %u WHERE id = %u", dwPrice, ch->GetOfflineShopOwner()->GetOfflineShopRealOwner());
}
RemoveItem(ch->GetOfflineShopOwner()->GetOfflineShopRealOwner(), bPos);
BroadcastUpdateItem(bPos, ch->GetOfflineShopOwner()->GetOfflineShopRealOwner(), true);
ch->PointChange(POINT_GOLD, -dwPrice, false);
ch->Save();
LogManager::instance().ItemLog(ch, pItem, "BUY ITEM FROM OFFLINE SHOP", "");
BYTE bLeftItemCount = GetLeftItemCount(ch->GetOfflineShopOwner()->GetOfflineShopRealOwner());
if (bLeftItemCount == 0)
Destroy(ch->GetOfflineShopOwner());
return (SHOP_SUBHEADER_GC_OK);
}
void COfflineShop::BroadcastUpdateItem(BYTE bPos, DWORD dwPID, bool bDestroy)
{
TPacketGCShop pack;
TPacketGCShopUpdateItem pack2;
TEMP_BUFFER buf;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM;
pack.size = sizeof(pack) + sizeof(pack2);
pack2.pos = bPos;
if (bDestroy)
{
pack2.item.vnum = 0;
pack2.item.count = 0;
pack2.item.price = 0;
memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
}
else
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), dwPID, bPos);
std::auto_ptr<SQLMsg> pMsg(DBManager::Instance().DirectQuery(szQuery));
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
str_to_number(pack2.item.count, row[1]);
str_to_number(pack2.item.vnum, row[2]);
str_to_number(pack2.item.price, row[3]);
// Set Sockets
for (int i = 0, n = 4; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(pack2.item.alSockets, row[n]);
// End Of Sockets
// Set Attributes
for (int i = 0, iStartAttributeType = 7, iStartAttributeValue = 8; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartAttributeType += 2, iStartAttributeValue += 2)
{
str_to_number(pack2.item.aAttr.bType, row[iStartAttributeType]);
str_to_number(pack2.item.aAttr.sValue, row[iStartAttributeValue]);
}
// End Of Set Attributes
}
}
buf.write(&pack, sizeof(pack));
buf.write(&pack2, sizeof(pack2));
Broadcast(buf.read_peek(), buf.size());
}
void COfflineShop::BroadcastUpdatePrice(BYTE bPos, DWORD dwPrice)
{
TPacketGCShop pack;
TPacketGCShopUpdatePrice pack2;
TEMP_BUFFER buf;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_UPDATE_PRICE;
pack.size = sizeof(pack) + sizeof(pack2);
pack2.bPos = bPos;
pack2.iPrice = dwPrice;
buf.write(&pack, sizeof(pack));
buf.write(&pack2, sizeof(pack2));
Broadcast(buf.read_peek(), buf.size());
}
void COfflineShop::Refresh(LPCHARACTER ch)
{
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM2;
TPacketGCOfflineShopStart pack2;
memset(&pack2, 0, sizeof(pack2));
pack2.owner_vid = 0;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
BYTE bPos = 0;
str_to_number(bPos, row[0]);
str_to_number(pack2.items[bPos].count, row[1]);
str_to_number(pack2.items[bPos].vnum, row[2]);
str_to_number(pack2.items[bPos].price, row[3]);
DWORD alSockets[ITEM_SOCKET_MAX_NUM];
for (int i = 0, n = 4; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(alSockets, row[n]);
TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
for (int i = 0, iStartType = 7, iStartValue = 8; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartType += 2, iStartValue += 2)
{
str_to_number(aAttr.bType, row[iStartType]);
str_to_number(aAttr.sValue, row[iStartValue]);
}
thecore_memcpy(pack2.items[bPos].alSockets, alSockets, sizeof(pack2.items[bPos].alSockets));
thecore_memcpy(pack2.items[bPos].aAttr, aAttr, sizeof(pack2.items[bPos].aAttr));
}
pack.size = sizeof(pack) + sizeof(pack2);
ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCOfflineShopStart));
}
bool COfflineShop::RemoveItem(DWORD dwVID, BYTE bPos)
{
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), dwVID, bPos));
return pMsg->Get()->uiAffectedRows > 0;
}
BYTE COfflineShop::GetLeftItemCount(DWORD dwPID)
{
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM %soffline_shop_item WHERE owner_id = %u and status = 0", get_table_postfix(), dwPID));
if (pMsg->Get()->uiNumRows == 0)
return 0;
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
BYTE bCount = 0;
str_to_number(bCount, row[0]);
return bCount;
}
void COfflineShop::Broadcast(const void * data, int bytes)
{
sys_log(1, "OfflineShop::Broadcast %p %d", data, bytes);
for (GuestMapType::iterator it = m_map_guest.begin(); it != m_map_guest.end(); ++it)
{
LPCHARACTER ch = it->first;
if (ch->GetDesc())
ch->GetDesc()->Packet(data, bytes);
}
}
Offlineshop.h
#pragma once
enum
{
OFFLINE_SHOP_MAX_DISTANCE = 1500,
};
class COfflineShop
{
public:
COfflineShop();
~COfflineShop();
virtual void SetOfflineShopNPC(LPCHARACTER npc);
virtual bool IsOfflineShopNPC(){ return m_pkOfflineShopNPC ? true : false; }
virtual bool AddGuest(LPCHARACTER ch, LPCHARACTER npc);
void RemoveGuest(LPCHARACTER ch);
void RemoveAllGuest();
void Destroy(LPCHARACTER npc);
virtual int Buy(LPCHARACTER ch, BYTE bPos);
void BroadcastUpdateItem(BYTE bPos, DWORD dwPID, bool bDestroy = false);
void BroadcastUpdatePrice(BYTE bPos, DWORD dwPrice);
void Refresh(LPCHARACTER ch);
bool RemoveItem(DWORD dwVID, BYTE bPos);
BYTE GetLeftItemCount(DWORD dwPID);
protected:
void Broadcast(const void * data, int bytes);
private:
// Grid
CGrid * m_pGrid;
// Guest Map
typedef TR1_NS::unordered_map<LPCHARACTER, bool> GuestMapType;
GuestMapType m_map_guest;
// End Of Guest Map
LPCHARACTER m_pkOfflineShopNPC;
};
Offlineshopmanager.cpp
#include "stdafx.h"
#include "../../libgame/include/grid.h"
#include "constants.h"
#include "utils.h"
#include "config.h"
#include "offline_shop.h"
#include "desc.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "item.h"
#include "item_manager.h"
#include "buffer_manager.h"
#include "packet.h"
#include "log.h"
#include "db.h"
#include "questmanager.h"
#include "monarch.h"
#include "mob_manager.h"
#include "locale_service.h"
#include "desc_client.h"
#include "group_text_parse_tree.h"
#include <boost/algorithm/string/predicate.hpp>
#include <cctype>
#include "offlineshop_manager.h"
#include "p2p.h"
#include "entity.h"
#include "sectree_manager.h"
#include "offlineshop_config.h"
COfflineShopManager::COfflineShopManager()
{
}
COfflineShopManager::~COfflineShopManager()
{
}
struct FFindOfflineShop
{
const char * szName;
DWORD dwVID, dwRealOwner;
FFindOfflineShop(const char * c_szName) : szName(c_szName), dwVID(0), dwRealOwner(0) {};
void operator()(LPENTITY ent)
{
if (!ent)
return;
if (ent->IsType(ENTITY_CHARACTER))
{
LPCHARACTER ch = (LPCHARACTER)ent;
if (ch->IsOfflineShopNPC() && !strcmp(szName, ch->GetName()))
{
dwVID = ch->GetVID();
dwRealOwner = ch->GetOfflineShopRealOwner();
M2_DESTROY_CHARACTER(ch);
}
}
}
};
bool COfflineShopManager::StartShopping(LPCHARACTER pkChr, LPCHARACTER pkChrShopKeeper)
{
if (pkChr->GetOfflineShopOwner() == pkChrShopKeeper)
return false;
if (pkChrShopKeeper->IsPC())
return false;
sys_log(0, "OFFLINE_SHOP: START: %s", pkChr->GetName());
return true;
}
LPOFFLINESHOP COfflineShopManager::CreateOfflineShop(LPCHARACTER npc, DWORD dwOwnerPID)
{
if (FindOfflineShop(npc->GetVID()))
return NULL;
LPOFFLINESHOP pkOfflineShop = M2_NEW COfflineShop;
pkOfflineShop->SetOfflineShopNPC(npc);
m_map_pkOfflineShopByNPC.insert(TShopMap::value_type(npc->GetVID(), pkOfflineShop));
m_Map_pkOfflineShopByNPC2.insert(TOfflineShopMap::value_type(dwOwnerPID, npc->GetVID()));
return pkOfflineShop;
}
LPOFFLINESHOP COfflineShopManager::FindOfflineShop(DWORD dwVID)
{
TShopMap::iterator it = m_map_pkOfflineShopByNPC.find(dwVID);
if (it == m_map_pkOfflineShopByNPC.end())
return NULL;
return it->second;
}
void COfflineShopManager::DestroyOfflineShop(LPCHARACTER ch, DWORD dwVID, bool bDestroyAll)
{
if (dwVID == 0)
{
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT mapIndex, mapIndex,channel FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
if (pMsg->Get()->uiNumRows == 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai un magazin offline deschis!");
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
long lMapIndex = 0;
str_to_number(lMapIndex, row[0]);
TPacketGGRemoveOfflineShop p;
p.bHeader = HEADER_GG_REMOVE_OFFLINE_SHOP;
p.lMapIndex = lMapIndex;
// Set offline shop name
char szNpcName[CHARACTER_NAME_MAX_LEN + 1];
snprintf(szNpcName, sizeof(szNpcName), "%s's Magazin Privat", ch->GetName());
strlcpy(p.szNpcName, szNpcName, sizeof(p.szNpcName));
// End Of Set offline shop name
P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGRemoveOfflineShop));
Giveback(ch);
}
else
{
LPCHARACTER npc;
if (!ch)
npc = CHARACTER_MANAGER::instance().Find(dwVID);
else
npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
if (!npc)
{
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT mapIndex,channel FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
if (pMsg->Get()->uiNumRows == 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai un magazin offline deschis!");
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
long lMapIndex = 0;
str_to_number(lMapIndex, row[0]);
BYTE bChannel = 0;
str_to_number(bChannel, row[1]);
if (g_bChannel != bChannel)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Trebuie sa fii pe channel %d pentru a inchide magazinul. Esti conectat pe channel %d .", g_bChannel, bChannel);
return;
}
char szName[CHARACTER_NAME_MAX_LEN + 1];
snprintf(szName, sizeof(szName), "%s's Magazin Privat", ch->GetName());
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(lMapIndex);
FFindOfflineShop offlineShop(szName);
pMap->for_each(offlineShop);
if (bDestroyAll)
{
Giveback(ch);
m_map_pkOfflineShopByNPC.erase(offlineShop.dwVID);
m_Map_pkOfflineShopByNPC2.erase(offlineShop.dwRealOwner);
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), offlineShop.dwRealOwner);
return;
}
}
LPOFFLINESHOP pkOfflineShop;
if (!ch)
pkOfflineShop = FindOfflineShop(dwVID);
else
pkOfflineShop = FindOfflineShop(FindMyOfflineShop(ch->GetPlayerID()));
if (!pkOfflineShop)
return;
if (npc->GetOfflineShopChannel() != g_bChannel)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Trebuie sa fii pe channel %d pentru a inchide magazinul. Esti conectat pe channel %d .", g_bChannel, npc->GetOfflineShopChannel());
return;
}
if (bDestroyAll)
{
Giveback(ch);
pkOfflineShop->Destroy(npc);
}
m_map_pkOfflineShopByNPC.erase(npc->GetVID());
m_Map_pkOfflineShopByNPC2.erase(npc->GetOfflineShopRealOwner());
M2_DELETE(pkOfflineShop);
}
}
void COfflineShopManager::Giveback(LPCHARACTER ch)
{
if (!ch)
return;
char szQuery[1024];
if (g_bOfflineShopSocketMax == 3)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
else if(g_bOfflineShopSocketMax == 4)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
else if(g_bOfflineShopSocketMax == 5)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3,socket4, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
else if(g_bOfflineShopSocketMax == 6)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID());
std::auto_ptr<SQLMsg> pMsg(DBManager::Instance().DirectQuery(szQuery));
if (pMsg->Get()->uiNumRows == 0)
{
sys_err("COfflineShopManager::GiveBack - There is nothing for this player [%s]", ch->GetName());
return;
}
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
TPlayerItem item;
str_to_number(item.pos, row[0]);
str_to_number(item.count, row[1]);
str_to_number(item.vnum, row[2]);
// Set Sockets
for (int i = 0, n = 3; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(item.alSockets, row[n]);
// End Of Set Sockets
// Set Attributes
for (int i = 0, iStartAttributeType = 6, iStartAttributeValue = 7 ; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartAttributeType += 2, iStartAttributeValue += 2)
{
str_to_number(item.aAttr.bType, row[iStartAttributeType]);
str_to_number(item.aAttr.sValue, row[iStartAttributeValue]);
}
// End Of Set Attributes
LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
if (pItem)
{
int iEmptyPos = 0;
if (pItem->IsDragonSoul())
iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
else
iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
if (iEmptyPos < 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai locuri disponibile in magazin!");
return;
}
pItem->SetSockets(item.alSockets);
pItem->SetAttributes(item.aAttr);
if (pItem->IsDragonSoul())
pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
ch->ChatPacket(CHAT_TYPE_INFO, "Ai primit %s din magazinul tau offline.", pItem->GetName());
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), item.pos);
}
}
}
void COfflineShopManager::Giveback2(LPCHARACTER ch)
{
if (!ch)
return;
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and status = 1", get_table_postfix(), ch->GetPlayerID());
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szQuery));
if (pMsg->Get()->uiNumRows == 0)
return;
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
TPlayerItem item;
str_to_number(item.pos, row[0]);
str_to_number(item.count, row[1]);
str_to_number(item.vnum, row[2]);
// Set Sockets
for (int i = 0, n = 3; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(item.alSockets, row[n]);
// End Of Set Sockets
// Set Attributes
for (int i = 0, iStartAttributeType = 6, iStartAttributeValue = ITEM_ATTRIBUTE_MAX_NUM; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartAttributeType += 2, iStartAttributeValue += 2)
{
str_to_number(item.aAttr.bType, row[iStartAttributeType]);
str_to_number(item.aAttr.sValue, row[iStartAttributeValue]);
}
// End Of Set Attributes
LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
if (pItem)
{
int iEmptyPos = 0;
if (pItem->IsDragonSoul())
iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
else
iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
if (iEmptyPos < 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai locuri disponibile in magazin!");
return;
}
pItem->SetSockets(item.alSockets);
pItem->SetAttributes(item.aAttr);
if (pItem->IsDragonSoul())
pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
ch->ChatPacket(CHAT_TYPE_INFO, "Ai primit %s din magazinul tau offline.", pItem->GetName());
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), item.pos);
}
}
}
void COfflineShopManager::AddItem(LPCHARACTER ch, BYTE bDisplayPos, BYTE bPos, int iPrice)
{
if (!ch)
return;
// Fixed bug 6.21.2015
if (bDisplayPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
{
sys_err("Overflow offline shop slot count [%s]", ch->GetName());
return;
}
// End Of fixed bug 6.21.2015
// Check player has offline shop or not
std::auto_ptr<SQLMsg> pmsg(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM player_2.offline_shop_npc WHERE owner_id = %u", ch->GetPlayerID()));
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
BYTE bResult = 0;
str_to_number(bResult, row[0]);
if (!bResult)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai un magazin offline deschis!");
return;
}
// End Of Check player has offline shop or not
LPITEM pkItem = ch->GetInventoryItem(bPos);
if (!pkItem)
return;
// Check
const TItemTable * itemTable = pkItem->GetProto();
if (IS_SET(itemTable->dwAntiFlags, ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MY_OFFLINE_SHOP))
{
ch->ChatPacket(CHAT_TYPE_INFO, "Acest item nu poate fi vandut!");
return;
}
if (pkItem->isLocked())
return;
if (pkItem->IsEquipped())
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu poti sa vinzi itemele echipate!");
return;
}
char szColumns[QUERY_MAX_LEN], szValues[QUERY_MAX_LEN];
int iLen = snprintf(szColumns, sizeof(szColumns), "id,owner_id,pos,count,price,vnum");
int iUpdateLen = snprintf(szValues, sizeof(szValues), "%u,%u,%d,%u,%d,%u", pkItem->GetID(), ch->GetPlayerID(), bDisplayPos, pkItem->GetCount(), iPrice, pkItem->GetVnum());
if (g_bOfflineShopSocketMax == 3)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2");
iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2));
}
else if(g_bOfflineShopSocketMax == 4)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2,socket3");
iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2), pkItem->GetSocket(3));
}
else if(g_bOfflineShopSocketMax == 5)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2,socket3,socket4");
iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2), pkItem->GetSocket(3), pkItem->GetSocket(4));
}
else if(g_bOfflineShopSocketMax == 6)
{
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ",socket0,socket1,socket2,socket3,socket4,socket5");
iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%ld,%ld,%ld,%ld,%ld,%ld", pkItem->GetSocket(0), pkItem->GetSocket(1), pkItem->GetSocket(2), pkItem->GetSocket(3), pkItem->GetSocket(4), pkItem->GetSocket(5));
}
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7");
iUpdateLen += snprintf(szValues + iUpdateLen, sizeof(szValues) - iUpdateLen, ",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
pkItem->GetAttributeType(0), pkItem->GetAttributeValue(0),
pkItem->GetAttributeType(1), pkItem->GetAttributeValue(1),
pkItem->GetAttributeType(2), pkItem->GetAttributeValue(2),
pkItem->GetAttributeType(3), pkItem->GetAttributeValue(3),
pkItem->GetAttributeType(4), pkItem->GetAttributeValue(4),
pkItem->GetAttributeType(5), pkItem->GetAttributeValue(5),
pkItem->GetAttributeType(6), pkItem->GetAttributeValue(6),
pkItem->GetAttributeType(7), pkItem->GetAttributeValue(7),
pkItem->GetAttributeType(8), pkItem->GetAttributeValue(8),
pkItem->GetAttributeType(9), pkItem->GetAttributeValue(9),
pkItem->GetAttributeType(10), pkItem->GetAttributeValue(10),
pkItem->GetAttributeType(11), pkItem->GetAttributeValue(11),
pkItem->GetAttributeType(12), pkItem->GetAttributeValue(12),
pkItem->GetAttributeType(12), pkItem->GetAttributeValue(13),
pkItem->GetAttributeType(14), pkItem->GetAttributeValue(14));
char szInsertQuery[QUERY_MAX_LEN];
snprintf(szInsertQuery, sizeof(szInsertQuery), "INSERT INTO %soffline_shop_item (%s) VALUES (%s)", get_table_postfix(), szColumns, szValues);
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szInsertQuery));
pkItem->RemoveFromCharacter();
LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
if (!npc)
return;
LPOFFLINESHOP pkOfflineShop = FindOfflineShop(npc->GetVID());
if (!pkOfflineShop)
return;
pkOfflineShop->BroadcastUpdateItem(bDisplayPos, ch->GetPlayerID());
LogManager::instance().ItemLog(ch, pkItem, "ADD ITEM OFFLINE SHOP", "");
}
void COfflineShopManager::RemoveItem(LPCHARACTER ch, BYTE bPos)
{
if (!ch)
return;
if (bPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
{
sys_log(0, "OfflineShopManager::RemoveItem - Overflow slot! [%s]", ch->GetName());
return;
}
LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
// Check npc
if (!npc)
{
char szQuery[1024];
if (g_bOfflineShopSocketMax == 3)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
else if(g_bOfflineShopSocketMax == 4)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
else if(g_bOfflineShopSocketMax == 5)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3,socket4, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
else if(g_bOfflineShopSocketMax == 6)
snprintf(szQuery, sizeof(szQuery), "SELECT pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(szQuery));
if (pMsg->Get()->uiNumRows == 0)
{
sys_log(0, "OfflineShopManager::RemoveItem - This slot is empty! [%s]", ch->GetName());
return;
}
TPlayerItem item;
int rows;
if (!(rows = mysql_num_rows(pMsg->Get()->pSQLResult)))
return;
for (int i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
int cur = 0;
str_to_number(item.pos, row[cur++]);
str_to_number(item.count, row[cur++]);
str_to_number(item.vnum, row[cur++]);
str_to_number(item.alSockets[0], row[cur++]);
str_to_number(item.alSockets[1], row[cur++]);
str_to_number(item.alSockets[2], row[cur++]);
for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
{
str_to_number(item.aAttr[j].bType, row[cur++]);
str_to_number(item.aAttr[j].sValue, row[cur++]);
}
}
LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
if (!pItem)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Te rugam sa incerci din nou!");
return;
}
pItem->SetAttributes(item.aAttr);
pItem->SetSockets(item.alSockets);
int iEmptyPos;
if (pItem->IsDragonSoul())
iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
else
iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
if (iEmptyPos < 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai locuri disponibile in magazin!");
return;
}
if (pItem->IsDragonSoul())
pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
LogManager::instance().ItemLog(ch, pItem, "DELETE OFFLINE SHOP ITEM", "");
}
else
{
LPOFFLINESHOP pkOfflineShop = npc->GetOfflineShop();
// Check pkOfflineShop
if (!pkOfflineShop)
return;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos));
if (pMsg->Get()->uiNumRows == 0)
{
sys_log(0, "OfflineShopManager::RemoveItem - This slot is empty! [%s]", ch->GetName());
return;
}
TPlayerItem item;
int rows;
if (!(rows = mysql_num_rows(pMsg->Get()->pSQLResult)))
return;
for (int i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
int cur = 0;
str_to_number(item.pos, row[cur++]);
str_to_number(item.count, row[cur++]);
str_to_number(item.vnum, row[cur++]);
str_to_number(item.alSockets[0], row[cur++]);
str_to_number(item.alSockets[1], row[cur++]);
str_to_number(item.alSockets[2], row[cur++]);
for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
{
str_to_number(item.aAttr[j].bType, row[cur++]);
str_to_number(item.aAttr[j].sValue, row[cur++]);
}
}
LPITEM pItem = ITEM_MANAGER::instance().CreateItem(item.vnum, item.count);
if (!pItem)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Te rugam sa incerci din nou!");
return;
}
pItem->SetAttributes(item.aAttr);
pItem->SetSockets(item.alSockets);
int iEmptyPos;
if (pItem->IsDragonSoul())
iEmptyPos = ch->GetEmptyDragonSoulInventory(pItem);
else
iEmptyPos = ch->GetEmptyInventory(pItem->GetSize());
if (iEmptyPos < 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai locuri disponibile in magazin!");
return;
}
if (pItem->IsDragonSoul())
pItem->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
pItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
DBManager::instance().DirectQuery("DELETE FROM %soffline_shop_item WHERE owner_id = %u and pos = %d", get_table_postfix(), ch->GetPlayerID(), bPos);
pkOfflineShop->BroadcastUpdateItem(bPos, ch->GetPlayerID(), true);
if (LeftItemCount(ch) == 0)
pkOfflineShop->Destroy(npc);
LogManager::instance().ItemLog(ch, pItem, "DELETE OFFLINE SHOP ITEM", "");
}
}
void COfflineShopManager::ChangePrice(LPCHARACTER ch, BYTE bPos, DWORD dwPrice)
{
if (!ch)
return;
if (bPos >= OFFLINE_SHOP_HOST_ITEM_MAX_NUM)
{
sys_err("Offlineshop overflow slot count [%s][%d]", ch->GetName(), bPos);
return;
}
LPOFFLINESHOP pkOfflineShop = FindOfflineShop(FindMyOfflineShop(ch->GetPlayerID()));
if (pkOfflineShop)
pkOfflineShop->BroadcastUpdatePrice(bPos, dwPrice);
DBManager::instance().DirectQuery("UPDATE %soffline_shop_item SET price = %u WHERE owner_id = %u and pos = %d", get_table_postfix(), dwPrice, ch->GetPlayerID(), bPos);
sys_log(0, "PRET: %u | ITEM ID: %u | POZITIE: %d", dwPrice, ch->GetPlayerID(), bPos);
}
void COfflineShopManager::Refresh(LPCHARACTER ch)
{
if (!ch)
return;
LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
if (!npc)
{
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM2;
TPacketGCOfflineShopStart pack2;
memset(&pack2, 0, sizeof(pack2));
pack2.owner_vid = 0;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT pos,count,vnum,price,socket0,socket1,socket2, attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3, attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6, applytype7, applyvalue7 FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
MYSQL_ROW row;
while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
{
BYTE bPos = 0;
str_to_number(bPos, row[0]);
str_to_number(pack2.items[bPos].count, row[1]);
str_to_number(pack2.items[bPos].vnum, row[2]);
str_to_number(pack2.items[bPos].price, row[3]);
DWORD alSockets[ITEM_SOCKET_MAX_NUM];
for (int i = 0, n = 4; i < ITEM_SOCKET_MAX_NUM; ++i, n++)
str_to_number(alSockets, row[n]);
TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
for (int i = 0, iStartType = 7, iStartValue = 8; i < ITEM_ATTRIBUTE_MAX_NUM; ++i, iStartType += 2, iStartValue += 2)
{
str_to_number(aAttr.bType, row[iStartType]);
str_to_number(aAttr.sValue, row[iStartValue]);
}
thecore_memcpy(pack2.items[bPos].alSockets, alSockets, sizeof(pack2.items[bPos].alSockets));
thecore_memcpy(pack2.items[bPos].aAttr, aAttr, sizeof(pack2.items[bPos].aAttr));
}
pack.size = sizeof(pack) + sizeof(pack2);
ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCOfflineShopStart));
}
else
{
LPOFFLINESHOP pkOfflineShop = npc->GetOfflineShop();
if (!pkOfflineShop)
return;
pkOfflineShop->Refresh(ch);
}
}
void COfflineShopManager::RefreshMoney(LPCHARACTER ch)
{
if (!ch)
return;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT money FROM player_2.player WHERE id = %u", ch->GetPlayerID()));
TPacketGCShop p;
TPacketGCOfflineShopMoney p2;
p.header = HEADER_GC_OFFLINE_SHOP;
p.subheader = SHOP_SUBHEADER_GC_REFRESH_MONEY;
if (pMsg->Get()->uiNumRows == 0)
{
p2.dwMoney = 0;
p.size = sizeof(p) + sizeof(p2);
ch->GetDesc()->BufferedPacket(&p, sizeof(TPacketGCShop));
ch->GetDesc()->Packet(&p2, sizeof(TPacketGCOfflineShopMoney));
}
else
{
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
str_to_number(p2.dwMoney, row[0]);
p.size = sizeof(p) + sizeof(p2);
ch->GetDesc()->BufferedPacket(&p, sizeof(TPacketGCShop));
ch->GetDesc()->Packet(&p2, sizeof(TPacketGCOfflineShopMoney));
}
}
DWORD COfflineShopManager::FindMyOfflineShop(DWORD dwPID)
{
TOfflineShopMap::iterator it = m_Map_pkOfflineShopByNPC2.find(dwPID);
if (m_Map_pkOfflineShopByNPC2.end() == it)
return 0;
return it->second;
}
void COfflineShopManager::ChangeOfflineShopTime(LPCHARACTER ch, BYTE bTime)
{
if (!ch)
return;
// Remember
DWORD dwOfflineShopVID = FindMyOfflineShop(ch->GetPlayerID());
if (!dwOfflineShopVID)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu ai un magazin offline deschis!");
return;
}
LPCHARACTER npc = CHARACTER_MANAGER::instance().Find(FindMyOfflineShop(ch->GetPlayerID()));
if (npc)
{
if (test_server)
SendNotice("#DEBUG - Offline Shop NPC Found!");
if (bTime == 4)
{
npc->StopOfflineShopUpdateEvent();
}
else
{
int iTime = 0;
switch (bTime)
{
case 1:
iTime = 1 * 60 * 60;
break;
case 2:
iTime = 2 * 60 * 60;
break;
case 3:
iTime = 4 * 60 * 60;
break;
}
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("UPDATE %soffline_shop_npc SET time = %d WHERE owner_id = %u", get_table_postfix(), iTime, ch->GetPlayerID()));
ch->ChatPacket(CHAT_TYPE_INFO, "Timp schimbat: %u ora(e)", iTime / 3600);
sys_log(0, "TIMP: %u | PLAYER ID: %u", iTime, ch->GetPlayerID());
npc->StopOfflineShopUpdateEvent();
npc->SetOfflineShopTimer(iTime);
npc->StartOfflineShopUpdateEvent();
LogManager::instance().CharLog(ch, 0, "OFFLINE SHOP", "CHANGE TIME");
}
}
else
{
TPacketGGChangeOfflineShopTime p;
p.bHeader = HEADER_GG_CHANGE_OFFLINE_SHOP_TIME;
p.bTime = bTime;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT mapIndex FROM %soffline_shop_npc WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
if (pMsg->Get()->uiNumRows == 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Nu poti sa folosesti aceasta optiune!");
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
str_to_number(p.lMapIndex, row[0]);
p.dwOwnerPID = ch->GetPlayerID();
P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGChangeOfflineShopTime));
}
}
void COfflineShopManager::StopShopping(LPCHARACTER ch)
{
LPOFFLINESHOP pkOfflineShop;
if (!(pkOfflineShop = ch->GetOfflineShop()))
return;
pkOfflineShop->RemoveGuest(ch);
sys_log(0, "OFFLINE_SHOP: END: %s", ch->GetName());
}
void COfflineShopManager::Buy(LPCHARACTER ch, BYTE pos)
{
if (!ch->GetOfflineShop())
return;
if (!ch->GetOfflineShopOwner())
return;
if (DISTANCE_APPROX(ch->GetX() - ch->GetOfflineShopOwner()->GetX(), ch->GetY() - ch->GetOfflineShopOwner()->GetY()) > 1500)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 살 수 없습니다."));
return;
}
LPOFFLINESHOP pkOfflineShop = ch->GetOfflineShop();
if (!pkOfflineShop)
return;
int ret = pkOfflineShop->Buy(ch, pos);
// The result is not equal to SHOP_SUBHEADER_GC_OK, send the error to the character.
if (SHOP_SUBHEADER_GC_OK != ret)
{
TPacketGCShop pack;
pack.header = HEADER_GC_OFFLINE_SHOP;
pack.subheader = ret;
pack.size = sizeof(TPacketGCShop);
ch->GetDesc()->Packet(&pack, sizeof(pack));
}
}
void COfflineShopManager::WithdrawMoney(LPCHARACTER ch, DWORD dwRequiredMoney)
{
if (!ch)
return;
if (dwRequiredMoney < 0)
return;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT money FROM player_2.player WHERE id = %u", ch->GetPlayerID()));
if (pMsg->Get()->uiNumRows == 0)
return;
DWORD dwCurrentMoney = 0;
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
str_to_number(dwCurrentMoney, row[0]);
if (dwRequiredMoney >= dwCurrentMoney)
{
if (test_server)
ch->ChatPacket(CHAT_TYPE_INFO, "dwCurrentMoney(%lu) - dwRequiredMoney(%lu)", dwCurrentMoney, dwRequiredMoney);
ch->ChatPacket(CHAT_TYPE_INFO, "Ai introdus o valoare mai mare decat suma curenta!");
return;
}
bool isOverFlow = ch->GetGold() + dwRequiredMoney > GOLD_MAX - 1 ? true : false;
if (isOverFlow)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Valoare introdusa trebuie sa fie SUMA dorita - 1.");
return;
}
ch->PointChange(POINT_GOLD, dwRequiredMoney, false);
ch->ChatPacket(CHAT_TYPE_INFO, "Ai primit %u yang.", dwRequiredMoney);
DBManager::instance().DirectQuery("UPDATE player_2.player SET money = money - %u WHERE id = %u", dwRequiredMoney, ch->GetPlayerID());
LogManager::instance().CharLog(ch, 0, "OFFLINE SHOP", "WITHDRAW MONEY");
}
BYTE COfflineShopManager::LeftItemCount(LPCHARACTER ch)
{
if (!ch)
return -1;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT COUNT(*) FROM %soffline_shop_item WHERE owner_id = %u", get_table_postfix(), ch->GetPlayerID()));
if (pMsg->Get()->uiNumRows == 0)
return 0;
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
BYTE bCount = 0;
str_to_number(bCount, row[0]);
return bCount;
}
offlineshop_manager.h
#pragma once
class COfflineShopManager : public singleton<COfflineShopManager>
{
public:
typedef std::map<DWORD, COfflineShop *> TShopMap;
typedef std::map<DWORD, DWORD> TOfflineShopMap;
public:
COfflineShopManager();
~COfflineShopManager();
bool StartShopping(LPCHARACTER pkChr, LPCHARACTER pkChrShopKeeper);
void StopShopping(LPCHARACTER ch);
void Buy(LPCHARACTER ch, BYTE bPos);
LPOFFLINESHOP CreateOfflineShop(LPCHARACTER npc, DWORD dwOwnerPID);
LPOFFLINESHOP FindOfflineShop(DWORD dwVID);
void DestroyOfflineShop(LPCHARACTER ch, DWORD dwVID, bool bDestroyAll = false);
void Giveback(LPCHARACTER ch);
void Giveback2(LPCHARACTER ch);
void AddItem(LPCHARACTER ch, BYTE bDisplayPos, BYTE bPos, int iPrice);
void RemoveItem(LPCHARACTER ch, BYTE bPos);
void ChangePrice(LPCHARACTER ch, BYTE bPos, DWORD dwPrice);
void Refresh(LPCHARACTER ch);
void RefreshMoney(LPCHARACTER ch);
DWORD FindMyOfflineShop(DWORD dwPID);
void ChangeOfflineShopTime(LPCHARACTER ch, BYTE bTime);
void WithdrawMoney(LPCHARACTER ch, DWORD dwRequiredMoney);
BYTE LeftItemCount(LPCHARACTER ch);
private:
TOfflineShopMap m_Map_pkOfflineShopByNPC2;
TShopMap m_map_pkOfflineShopByNPC;
};
thanks for help all
Link to comment
Share on other sites
Top Posters For This Question
2
Popular Days
Apr 15
1
Jul 27
1
Top Posters For This Question
gummyantifi 2 posts
Popular Days
Apr 15 2016
1 post
Jul 27 2016
1 post
1 answer to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now