Yardım Sonitex DB Sıkıntısı

Konu sahibi bu konuda soru soruyor. Sorusu ile ilgili bilgisi olanların yanıtlamasını bekliyor.

PDx

Üye
Üye
Mesaj
12
Beğeni
0
Puan
38
Ticaret Puanı
0
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.
syslog:
Genişlet Daralt Kopyala
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:
Genişlet Daralt Kopyala
//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:
Genişlet Daralt Kopyala
//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:
Genişlet Daralt Kopyala
//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:
Genişlet Daralt Kopyala
#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:
Pazar kapandıktan sonra owner'ın IsPrivateShopOwner() kontrolü hâlâ true dönüyor. Yani; despawn işlemi game/db tarafında private shop owner flag'ini temizlemiyor. Char.cpp veya IsPrivateShopOwner flagının nerede set edildiğini gönderirsen biraz daha detaylı bakılabilir ben sadece gördüğüm kadarını söyledim fazlasıda olabilir .
 
Pazar kapandıktan sonra owner'ın IsPrivateShopOwner() kontrolü hâlâ true dönüyor. Yani; despawn işlemi game/db tarafında private shop owner flag'ini temizlemiyor. Char.cpp veya IsPrivateShopOwner flagının nerede set edildiğini gönderirsen biraz daha detaylı bakılabilir ben sadece gördüğüm kadarını söyledim fazlasıda olabilir .
İlgili olabilecek yerleri konuya eklemeye çalıştım.
 
private_shop_manager.cpp ve .h de paylaşır mısın
private_shop_manager.cpp:
Genişlet Daralt Kopyala
#include "stdafx.h"
#include "private_shop_manager.h"
#include "private_shop.h"
#include "private_shop_util.h"
#include "char.h"
#include "char_manager.h"
#include "desc_client.h"
#include "mob_manager.h"
#include "config.h"
#include "db.h"
#include "item_manager.h"
#include "item.h"
#include "utils.h"
#include "entity.h"
#include "sectree_manager.h"
#include "p2p.h"
#include "buffer_manager.h"
#include "desc_manager.h"
#include "p2p.h"
#include "DragonSoul.h"
#include "log.h"
#include <memory> // <-- unique_ptr için gerekli kütüphane eklendi

void CPrivateShopManager::Destroy()
{
    m_map_privateShop.clear();
}

LPPRIVATE_SHOP CPrivateShopManager::CreatePrivateShop(DWORD dwPID)
{
    if (GetPrivateShop(dwPID))
        return nullptr;

    // C++11 Uyarlaması Yapıldı
    std::unique_ptr<CPrivateShop> upPrivateShop = std::unique_ptr<CPrivateShop>(new CPrivateShop());
    LPPRIVATE_SHOP pPrivateShop = upPrivateShop.get();

    DWORD dwVID = AllocVID();
    upPrivateShop->SetVID(dwVID);

    m_map_privateShop.emplace(dwPID, std::move(upPrivateShop));
    m_map_privateShopVID.emplace(dwVID, pPrivateShop);

    return pPrivateShop;
}

LPPRIVATE_SHOP CPrivateShopManager::GetPrivateShop(DWORD dwPID)
{
    auto it = m_map_privateShop.find(dwPID);
    if (it == m_map_privateShop.end())
        return nullptr;

    return it->second.get();
}

LPPRIVATE_SHOP CPrivateShopManager::GetPrivateShopByOwnerName(const char* c_szOwnerName)
{
    for (auto it = m_map_privateShop.begin(); it != m_map_privateShop.end(); ++it)
    {
        LPPRIVATE_SHOP pPrivateShop = it->second.get();

        if (pPrivateShop->GetOwnerName().compare(c_szOwnerName) == 0)
            return pPrivateShop;
    }

    return nullptr;
}

LPPRIVATE_SHOP CPrivateShopManager::GetPrivateShopByVID(DWORD dwVID)
{
    auto it = m_map_privateShopVID.find(dwVID);
    if (it == m_map_privateShopVID.end())
        return nullptr;

    return it->second;
}

bool CPrivateShopManager::DeletePrivateShop(DWORD dwPID)
{
    auto it = m_map_privateShop.find(dwPID);
    if (it == m_map_privateShop.end())
        return false;

    DWORD dwVID = it->second->GetVID();

    m_map_privateShopVID.erase(dwVID);
    m_map_privateShop.erase(it);
    return true;
}

bool CPrivateShopManager::BuildPrivateShop(LPCHARACTER pShopOwner, const char* c_szTitle, DWORD dwPolyVnum, BYTE bTitleType, BYTE bPageCount, const std::vector<TPrivateShopItem>& c_vec_shopItem)
{
    const CMob* pMobTable = CMobManager::Instance().Get(dwPolyVnum);
    if (!pMobTable)
    {
        sys_err("Cannot find mob table for vnum %u", dwPolyVnum);
        return false;
    }

    LPPRIVATE_SHOP pPrivateShop = CreatePrivateShop(pShopOwner->GetPlayerID());
    if (!pPrivateShop)
    {
        sys_err("Cannot create a private shop instance for player %s %u", pShopOwner->GetName(), pShopOwner->GetPlayerID());
        return false;
    }

    std::vector<TPlayerPrivateShopItem> vec_privateShopItem;
    for (const auto& c_rShopItem : c_vec_shopItem)
    {
        LPITEM pItem = pShopOwner->GetItem(c_rShopItem.TPos);

        TPlayerPrivateShopItem t{};

        CopyItemData(pItem, t);

        t.TPrice.llGold = c_rShopItem.TPrice.llGold;
#ifdef WJ_PRIVATE_SHOP_CHEQUE
        t.TPrice.dwCheque = c_rShopItem.TPrice.dwCheque;
#endif
        t.wPos = c_rShopItem.wDisplayPos;
        t.tCheckin = time(0);

        vec_privateShopItem.push_back(t);
    }

    std::string strTitle(c_szTitle);

    pPrivateShop->SetID(pShopOwner->GetPlayerID());
    pPrivateShop->SetVnum(dwPolyVnum);
    pPrivateShop->SetOwnerName(pShopOwner->GetName());
    pPrivateShop->SetTitle(c_szTitle);
    pPrivateShop->SetTitleType(bTitleType);
    pPrivateShop->SetState(STATE_OPEN);
    pPrivateShop->SetPageCount(bPageCount);

    if (!pPrivateShop->Initialize(vec_privateShopItem))
    {
        sys_err("Cannot initialize items to private shop");
        DeletePrivateShop(pShopOwner->GetPlayerID());

        return false;
    }

    const auto& itemContainer = pPrivateShop->GetItemContainer();
    for (const auto& kv : itemContainer)
        ITEM_MANAGER::Instance().FlushDelayedSave(kv.second);

    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_CREATE;
    WORD wCount = vec_privateShopItem.size();

    TPrivateShop t{};

    t.dwOwner = pShopOwner->GetPlayerID();
    strlcpy(t.szTitle, c_szTitle, sizeof(t.szTitle));
    strlcpy(t.szOwnerName, pShopOwner->GetName(), sizeof(t.szOwnerName));
    t.dwVnum = dwPolyVnum;
    t.bTitleType = bTitleType;
    t.lMapIndex = pShopOwner->GetMapIndex();
    t.lX = pShopOwner->GetX();
    t.lY = pShopOwner->GetY();
    t.bChannel = g_bChannel;
    t.wPort = mother_port;
    t.bState = STATE_OPEN;
    t.llGold = 0;
#ifdef WJ_PRIVATE_SHOP_CHEQUE
    t.dwCheque = 0;
#endif
    t.bPageCount = bPageCount;
    t.tPremiumTime = pShopOwner->GetPremiumRemainSeconds(PREMIUM_PRIVATE_SHOP) + time(0);

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, pShopOwner->GetDesc()->GetHandle(), sizeof(BYTE) + sizeof(TPrivateShop) + sizeof(WORD) + sizeof(TPlayerPrivateShopItem) * wCount);
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&t, sizeof(TPrivateShop));
    db_clientdesc->Packet(&wCount, sizeof(WORD));
    db_clientdesc->Packet(&vec_privateShopItem[0], sizeof(TPlayerPrivateShopItem) * wCount);

    return true;
}

void CPrivateShopManager::BuildPrivateShopResult(DWORD dwPID, TPrivateShop* pPrivateShopTable, bool bSuccess)
{
    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }

    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (!pOwner)
    {
        sys_err("Cannot find private shop owner with id %u", dwPID);
        return;
    }

    pOwner->ClosePrivateShopPanel(true);

    const auto& map_privateShopItem = pPrivateShop->GetItemContainer();
    for (const auto& kv : map_privateShopItem)
    {
        WORD wPos = kv.first;
        LPITEM pItem = kv.second;

        if (bSuccess)
        {
            pItem->SetSkipSave(true);

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop

            pItem->RemoveFromCharacter();
            pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, pItem->GetCell(), 255);

            pItem->SetCell(nullptr, wPos);
            pItem->BindPrivateShop(pPrivateShop);

            TPlayerPrivateShopItem t{};
            CopyItemData(pItem, t);

            pOwner->SetPrivateShopItem(t);

            char szHint[128 + 1]{};
            snprintf(szHint, sizeof(szHint), "%s x%u pos %u gold %lld", pItem->GetName(), pItem->GetCount(), t.wPos, t.TPrice.llGold);
            LogManager::Instance().ItemLog(pOwner, pItem, "PRIVATE SHOP BUILD CHECKIN", szHint);
        }
        else
        {
            pItem->BindPrivateShop(nullptr);
            pItem->SetCheckinTime(0);
            pItem->SetGoldPrice(0);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
            pItem->SetChequePrice(0);
#endif

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop
        }
    }

    if (!bSuccess)
    {
        DeletePrivateShop(dwPID);
        pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot build a personal shop at this moment. "));

        sys_err("Private shop building process stopped for player %u", dwPID);
        return;
    }

    pPrivateShop->Show(pPrivateShopTable->lX, pPrivateShopTable->lY, 0, pPrivateShopTable->lMapIndex);
    pOwner->SetPrivateShopTable(*pPrivateShopTable);

    LogManager::Instance().CharLog(pOwner, 0, "PRIVATE SHOP BUILT", "");

    sys_log(0, "%s PRIVATE_SHOP: SUCCESS Shop entity created", pPrivateShopTable->szOwnerName);
}

void CPrivateShopManager::ClosePrivateShop(LPCHARACTER pShopOwner)
{
    DWORD dwPID = pShopOwner->GetPlayerID();

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        pShopOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You are too far away from your personal shop."));
        return;
    }

    // Cancel if the player is not near his shop character
    long lShopMapIndex = pPrivateShop->GetMapIndex();
    if (pShopOwner->GetMapIndex() != lShopMapIndex)
    {
        pShopOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot close a personal shop from a different location."));
        return;
    }

    if (DISTANCE_APPROX(pPrivateShop->GetX() - pShopOwner->GetX(), pPrivateShop->GetY() - pShopOwner->GetY()) > 3000)
    {
        pShopOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You are too far away from your personal shop."));
        return;
    }

    pPrivateShop->SetClosing(true);
    if (pPrivateShop->TransferItems(pShopOwner))
    {
        // Close the window at customer's client
        pPrivateShop->CleanShopViewers();

        BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_DELETE;

        db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
        db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
        db_clientdesc->Packet(&dwPID, sizeof(DWORD));

        DeletePrivateShop(dwPID);

        pShopOwner->ClosePrivateShop();

        sys_log(0, "%s PRIVATE_SHOP: SUCCESS Shop entity closed", pShopOwner->GetName());
        LogManager::Instance().CharLog(pShopOwner, 0, "PRIVATE SHOP CLOSED", "");
    }
    else
    {
        sys_err("Failed to transfer items back to owner %u", pShopOwner->GetPlayerID());
        pPrivateShop->SetClosing(false);
    }
}

void CPrivateShopManager::SpawnPrivateShop(TPrivateShop* pPrivateShopTable, const std::vector<TPlayerPrivateShopItem>& c_vec_shopItem)
{
    const CMob* pMobTable = CMobManager::Instance().Get(pPrivateShopTable->dwVnum);
    if (!pMobTable)
    {
        sys_err("Cannot find mob table for vnum %u", pPrivateShopTable->dwVnum);
        return;
    }

    if (GetPrivateShop(pPrivateShopTable->dwOwner))
        DeletePrivateShop(pPrivateShopTable->dwOwner);

    LPPRIVATE_SHOP pPrivateShop = CreatePrivateShop(pPrivateShopTable->dwOwner);
    if (!pPrivateShop)
    {
        sys_err("Cannot create a private shop instance for player %s %u", pPrivateShopTable->szOwnerName, pPrivateShopTable->dwOwner);
        return;
    }

    LPSECTREE pSectree = SECTREE_MANAGER::instance().Get(pPrivateShopTable->lMapIndex, pPrivateShopTable->lX, pPrivateShopTable->lY);

    if (!pSectree)
    {
        sys_err("Cannot find sectree %dx%d mapindex %d for private shop %s %d", pPrivateShopTable->lY, pPrivateShopTable->lY, pPrivateShopTable->lMapIndex,
            pPrivateShopTable->szOwnerName, pPrivateShopTable->dwOwner);
        return;
    }

    if (pPrivateShopTable->bState < STATE_OPEN)
    {
        sys_err("Cannot spawn a private shop %u with state %u", pPrivateShopTable->dwOwner, pPrivateShopTable->bState);
        return;
    }

    // Bind data to the private shop
    pPrivateShop->SetID(pPrivateShopTable->dwOwner);
    pPrivateShop->SetVnum(pPrivateShopTable->dwVnum);
    pPrivateShop->SetOwnerName(pPrivateShopTable->szOwnerName);
    pPrivateShop->SetTitle(pPrivateShopTable->szTitle);
    pPrivateShop->SetTitleType(pPrivateShopTable->bTitleType);
    pPrivateShop->SetState(pPrivateShopTable->bState);
    pPrivateShop->SetPageCount(pPrivateShopTable->bPageCount);

    // Create items and transfer them to the private shop
    if (!pPrivateShop->Initialize(c_vec_shopItem, true))
    {
        sys_err("Cannot initialize items to private shop");
        DespawnPrivateShop(pPrivateShopTable->dwOwner);

        sys_log(0, "%s PRIVATE_SHOP: FAILURE Shop entity not spawned", pPrivateShopTable->szOwnerName);
        return;
    }

    pPrivateShop->Show(pPrivateShopTable->lX, pPrivateShopTable->lY, 0, pPrivateShopTable->lMapIndex);

    sys_log(0, "%s PRIVATE_SHOP: SUCCESS Shop entity spawned", pPrivateShopTable->szOwnerName);

    LogManager::Instance().CharLog(pPrivateShopTable->dwOwner, pPrivateShopTable->lX, pPrivateShopTable->lY, 0, "PRIVATE SHOP SPAWN", "", "");
}

void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_DESPAWN;
    DWORD dwOwner = dwPID;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&dwOwner, sizeof(DWORD));

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }

    sys_log(0, "%s PRIVATE_SHOP: Shop entity despawned", pPrivateShop->GetOwnerName().c_str());
    DeletePrivateShop(dwPID);
}

bool CPrivateShopManager::StopShopping(LPCHARACTER pShopViewer)
{
    LPPRIVATE_SHOP pPrivateShop = pShopViewer->GetViewingPrivateShop();
    if (!pPrivateShop)
        return false;

    pPrivateShop->RemoveShopViewer(pShopViewer);
    pShopViewer->SetMyShopTime();

    return true;
}

void CPrivateShopManager::ItemCheckin(LPCHARACTER pOwner, const TPlayerPrivateShopItem* c_pShopItem)
{
    if (db_clientdesc->GetSocket() == INVALID_SOCKET)
        return;

    LPITEM pItem = ITEM_MANAGER::Instance().Find(c_pShopItem->dwID);
    if (!pItem)
    {
        sys_err("Cannot checkin item %u vnum %u for private shop %u (item not found)", c_pShopItem->dwID, c_pShopItem->dwVnum, pOwner->GetPlayerID());
        return;
    }

    if (!pItem->GetOwner())
    {
        sys_err("Cannot checkin item %u vnum %u for private shop %u (owner not found)", c_pShopItem->dwID, c_pShopItem->dwVnum, pOwner->GetPlayerID());
        return;
    }

    if (pItem->GetOwner() != pOwner)
    {
        sys_err("Cannot checkin item %u vnum %u for private shop %u (owner not equal to private shop owner)", c_pShopItem->dwID, c_pShopItem->dwVnum, pOwner->GetPlayerID());
        return;
    }

    pOwner->SetPrivateShopItem(*c_pShopItem);

    // Send check-in update back to db
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_ITEM_CHECKIN_UPDATE;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, pOwner->GetDesc()->GetHandle(), sizeof(BYTE) + sizeof(TPlayerPrivateShopItem));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(c_pShopItem, sizeof(TPlayerPrivateShopItem));

    char szHint[128 + 1]{};
    snprintf(szHint, sizeof(szHint), "%s x%u pos %u gold %lld",
        pItem->GetName(), pItem->GetCount(), c_pShopItem->wPos, c_pShopItem->TPrice.llGold);
    LogManager::Instance().ItemLog(pItem->GetOwner(), pItem, "PRIVATE SHOP CHECKIN", szHint);

    // Do not save the removal of item, will be done later on
    pItem->SetSkipSave(true);
    ITEM_MANAGER::Instance().RemoveItem(pItem);
}

void CPrivateShopManager::ItemCheckout(LPCHARACTER pOwner, WORD wSrcPos, TItemPos TDstPos)
{
    if (db_clientdesc->GetSocket() == INVALID_SOCKET)
        return;

    const TPlayerPrivateShopItem* c_pShopItem = pOwner->GetPrivateShopItem(wSrcPos);

    if (!c_pShopItem)
    {
        sys_err("cannot find private shop item at pos %u player %u", wSrcPos, pOwner->GetPlayerID());
        return;
    }

    LPITEM pItem = ITEM_MANAGER::Instance().Find(c_pShopItem->dwID);

    if (!pItem)
    {
        pItem = ITEM_MANAGER::Instance().CreateItem(c_pShopItem->dwVnum, c_pShopItem->dwCount, c_pShopItem->dwID);
        if (!pItem)
        {
            sys_err("cannot create item by vnum %u (id %u)", c_pShopItem->dwVnum, c_pShopItem->dwID);
            return;
        }

        pItem->OnAfterCreatedItem();
        CopyItemData(*c_pShopItem, pItem);
    }

    // Necessary to avoid AddToCharacter failure
    pItem->SetCell(nullptr, 0);

    // Try to move the item to the owner
    if (!pItem->AddToCharacter(pOwner, TItemPos(TDstPos.window_type, TDstPos.cell)))
    {
        sys_err("Cannot checkout item %u vnum %u from private shop %u", c_pShopItem->dwID, c_pShopItem->dwVnum, pOwner->GetPlayerID());

        // If item had no private shop bound it was re-created and can be removed
        if (!pItem->GetPrivateShop())
            M2_DESTROY_ITEM(pItem);
        else
            pItem->SetCell(nullptr, c_pShopItem->wPos); // Revert the cell back :)

        return;
    }

    // Item was successfully transfered to owner, reset private shop values
    pItem->BindPrivateShop(nullptr);
    pItem->SetGoldPrice(0);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
    pItem->SetChequePrice(0);
#endif

    // Enable saving of the item
    pItem->SetSkipSave(false);

    // Remove the private shop item
    pOwner->RemovePrivateShopItem(wSrcPos);

    // Send check-out update back to db
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_ITEM_CHECKOUT_UPDATE;

    TPlayerItem TItem {};
    CopyItemData(pItem, TItem);

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, pOwner->GetDesc()->GetHandle(), sizeof(BYTE) + sizeof(WORD) + sizeof(TPlayerItem));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&wSrcPos, sizeof(WORD));
    db_clientdesc->Packet(&TItem, sizeof(TPlayerItem));

    char szHint[128 + 1]{};
    snprintf(szHint, sizeof(szHint), "%s x%u", pItem->GetName(), pItem->GetCount());
    LogManager::Instance().ItemLog(pItem->GetOwner(), pItem, "PRIVATE SHOP CHECKOUT", szHint);
}

bool CPrivateShopManager::ItemTransaction(LPCHARACTER pCustomer, TPlayerPrivateShopItem* c_pShopItem)
{
    if (db_clientdesc->GetSocket() == INVALID_SOCKET)
        return false;

    if (!c_pShopItem->dwOwner)
        return false;

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(c_pShopItem->dwOwner);

    // Check if the item already exists, if not create it
    LPITEM pItem = ITEM_MANAGER::Instance().Find(c_pShopItem->dwID);

    if (pPrivateShop && !pItem)
        sys_err("No item data found for item %u vnum %u on private shop %u", c_pShopItem->dwID, c_pShopItem->dwVnum, c_pShopItem->dwOwner);

    bool bNewItem = false;
    if (!pItem)
    {
        pItem = ITEM_MANAGER::Instance().CreateItem(c_pShopItem->dwVnum, c_pShopItem->dwCount, c_pShopItem->dwID);
        if (!pItem)
        {
            sys_err("Cannot create item %u vnum %u", c_pShopItem->dwID, c_pShopItem->dwVnum);

            SendItemTransactionFailedResult(c_pShopItem->dwOwner, c_pShopItem->wPos);
            return false;
        }

        CopyItemData(*c_pShopItem, pItem);
        bNewItem = true;
    }

    // Check if there is enough space for the item
    int iPos = GetEmptyInventory(pCustomer, pItem);

    if (iPos < 0)
    {
        sys_err("Cannot find empty cell for item %u vnum %u", c_pShopItem->dwID, c_pShopItem->dwVnum);

        pCustomer->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough space in your inventory."));
        SendItemTransactionFailedResult(c_pShopItem->dwOwner, c_pShopItem->wPos);

        if (bNewItem)
            M2_DESTROY_ITEM(pItem);

        return false;
    }

    // Was already checked on db?
    if (pCustomer->GetGold() < c_pShopItem->TPrice.llGold)
    {
        sys_log(0, "PRIVATE_SHOP: Insufficient gold at customer %s to buy item %u vnum %u", pCustomer->GetName(), c_pShopItem->dwID, c_pShopItem->dwVnum);

        pCustomer->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Yang."));
        SendItemTransactionFailedResult(c_pShopItem->dwOwner, c_pShopItem->wPos);

        if (bNewItem)
            M2_DESTROY_ITEM(pItem);

        return false;
    }

#ifdef WJ_PRIVATE_SHOP_CHEQUE
    if (static_cast<DWORD>(pCustomer->GetCheque()) < c_pShopItem->TPrice.dwCheque)
    {
        sys_log(0, "PRIVATE_SHOP: Insufficient cheque at customer %s to buy item %u vnum %u", pCustomer->GetName(), c_pShopItem->dwID, c_pShopItem->dwVnum);

        pCustomer->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Won."));
        SendItemTransactionFailedResult(c_pShopItem->dwOwner, c_pShopItem->wPos);
        return false;
    }
#endif

    // Bind data to the item
    pItem->SetSkipSave(true);
    pItem->BindPrivateShop(nullptr); // Break the private shop connection if the item was taken directly from shop (not p2p)

    // Remove private shop data
    pItem->SetGoldPrice(0);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
    pItem->SetChequePrice(0);
#endif
    pItem->SetCheckinTime(0);

    // Reset item's ownership and cell
    pItem->SetCell(nullptr, 0);

    // Enable saving of the item
    pItem->SetSkipSave(false);

    BYTE bWindow = pItem->GetType() == ITEM_DS ? DRAGON_SOUL_INVENTORY : INVENTORY;
    if (!pItem->AddToCharacter(pCustomer, TItemPos(bWindow, iPos)))
    {
        // Bind private shop to the item if it exists on this core
        if (pPrivateShop)
        {
            CopyItemData(*c_pShopItem, pItem);
            pItem->BindPrivateShop(pPrivateShop);
            pItem->SetSkipSave(true);
        }
        else
        {
            M2_DESTROY_ITEM(pItem);
        }

        sys_log(0, "PRIVATE_SHOP: Failed to add item %u vnum %u to customer %s", c_pShopItem->dwID, c_pShopItem->dwVnum, pCustomer->GetName());
        SendItemTransactionFailedResult(c_pShopItem->dwOwner, c_pShopItem->wPos);
        return false;
    }

    // Remove item from the shop before resetting owner/position (if the shop is in another core, request from db will be sent)
    if (pPrivateShop)
        pPrivateShop->RemoveItem(c_pShopItem->wPos);

    pCustomer->PointChange(POINT_GOLD, -c_pShopItem->TPrice.llGold);

#ifdef WJ_PRIVATE_SHOP_CHEQUE
    int iChequePrice = c_pShopItem->TPrice.dwCheque;
    pCustomer->PointChange(POINT_CHEQUE, -iChequePrice);
#endif

    ITEM_MANAGER::Instance().SaveSingleItem(pItem);

    if (pItem->GetCount() > 1)
        pCustomer->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have bought x%d %s."), pItem->GetCount(), pItem->GetName());
    else
        pCustomer->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have bought %s."), pItem->GetName());

    sys_log(0, "PRIVATE_SHOP: SUCCESS Item transaction for customer %s item %u %u from shop %u", pCustomer->GetName(), c_pShopItem->dwID, c_pShopItem->dwVnum, c_pShopItem->dwOwner);

    // Send result back to db
    SendItemTransaction(c_pShopItem, pCustomer);

    char szHint[128 + 1]{};
    snprintf(szHint, sizeof(szHint), "%s x%u (Private Shop %u)", pItem->GetName(), pItem->GetCount(), c_pShopItem->dwOwner);
    LogManager::Instance().ItemLog(pItem->GetOwner(), pItem, "PRIVATE SHOP ITEM TRANSACTION", szHint);

    return true;
}

void CPrivateShopManager::SendItemTransaction(const TPlayerPrivateShopItem* c_pShopItem /* = nullptr */, LPCHARACTER pCustomer /* = nullptr */)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_BUY;

    TPacketGDPrivateShopBuy subPacket{};

    std::memcpy(&subPacket.TItem, c_pShopItem, sizeof(subPacket.TItem));
    strlcpy(subPacket.szCustomerName, pCustomer->GetName(), sizeof(subPacket.szCustomerName));
    subPacket.dwCustomer = pCustomer->GetPlayerID();

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketGDPrivateShopBuy));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&subPacket, sizeof(TPacketGDPrivateShopBuy));
}

void CPrivateShopManager::SendItemTransactionFailedResult(DWORD dwShopID, WORD wPos)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_FAILED_BUY;

    TPacketGDPrivateShopFailedBuy subPacket{};

    subPacket.dwShopID = dwShopID;
    subPacket.wPos = wPos;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketGDPrivateShopFailedBuy));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&subPacket, sizeof(TPacketGDPrivateShopFailedBuy));
}

void CPrivateShopManager::SendItemTransfer(const TPlayerItem* c_pItem)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_ITEM_TRANSFER;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPlayerItem));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(c_pItem, sizeof(TPlayerItem));
}

void CPrivateShopManager::SendItemExpire(LPITEM pItem)
{
    LPPRIVATE_SHOP pPrivateShop = pItem->GetPrivateShop();

    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_ITEM_EXPIRE;

    TPacketGDPrivateShopItemExpire subPacket{};
    subPacket.dwShopID = pPrivateShop->GetID();
    subPacket.wPos = pItem->GetCell();

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketGDPrivateShopItemExpire));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&subPacket, sizeof(TPacketGDPrivateShopItemExpire));

    pPrivateShop->RemoveItem(pItem->GetCell());
}

void CPrivateShopManager::AddSearchItem(LPITEM pItem)
{
    BYTE bItemType = pItem->GetType();
    BYTE bItemSubType = pItem->GetSubType();

    TItemList& itemList = m_map_searchItem[bItemType][bItemSubType];
    itemList.emplace(pItem);
}

void CPrivateShopManager::RemoveSearchItem(LPITEM pItem)
{
    if (!pItem)
        return;

    BYTE bItemType = pItem->GetType();
    BYTE bItemSubType = pItem->GetSubType();

    auto typeIt = m_map_searchItem.find(bItemType);
    if (typeIt == m_map_searchItem.end())
        return;

    TSubTypeItemMap& map_itemSubType = typeIt->second;
    auto subTypeIt = map_itemSubType.find(bItemSubType);
    if (subTypeIt == map_itemSubType.end())
        return;

    TItemList& itemList = subTypeIt->second;

    for (auto it = itemList.begin(); it != itemList.end(); ++it)
    {
        LPITEM pListItem = *it;
        if (pListItem->GetID() == pItem->GetID())
        {
            itemList.erase(it);
            return;
        }
    }
}

bool FilterItem(LPITEM pItem, TPrivateShopSearchFilter& rFilter, bool bUseFilter)
{
    if (!pItem->GetPrivateShop())
    {
        sys_err("Could not find private shop for item %u", pItem->GetID());
        return false;
    }

    if (rFilter.iItemType >= 0)
    {
        if (pItem->GetType() != rFilter.iItemType)
            return false;
    }

    if (rFilter.iItemSubType >= 0)
    {
        if (pItem->GetSubType() != rFilter.iItemSubType)
            return false;
    }

    if (bUseFilter)
    {
        if (rFilter.dwVnum)
        {
            if (pItem->GetVnum() != rFilter.dwVnum)
                return false;
        }

        if (rFilter.iItemType == ITEM_WEAPON || rFilter.iItemType == ITEM_ARMOR)
        {
            if (rFilter.bMinRefine > 0)
            {
                if ((pItem->GetVnum() % 10) < rFilter.bMinRefine) return false;
            }

            if (rFilter.bMaxRefine > 0)
            {
                if ((pItem->GetVnum() % 10) > rFilter.bMaxRefine) return false;
            }
        }

        if (rFilter.iJob >= 0)
        {
            switch (rFilter.iJob)
            {
            case JOB_WARRIOR:
                if (pItem->GetAntiFlag() & ITEM_ANTIFLAG_WARRIOR)
                    return false;
                break;

            case JOB_ASSASSIN:
                if (pItem->GetAntiFlag() & ITEM_ANTIFLAG_ASSASSIN)
                    return false;
                break;

            case JOB_SHAMAN:
                if (pItem->GetAntiFlag() & ITEM_ANTIFLAG_SHAMAN)
                    return false;
                break;

            case JOB_SURA:
                if (pItem->GetAntiFlag() & ITEM_ANTIFLAG_SURA)
                    return false;

                break;
            }
        }

        if (rFilter.dwMinLevel > 0)
        {
            if (pItem->GetLevelLimit() && static_cast<DWORD>(pItem->GetLevelLimit()) < rFilter.dwMinLevel) return false;
        }

        if (rFilter.dwMaxLevel > 0)
        {
            if (static_cast<DWORD>(pItem->GetLevelLimit()) > rFilter.dwMaxLevel) return false;
        }

        if (rFilter.llMinGold > pItem->GetGoldPrice() ||
            rFilter.llMaxGold < pItem->GetGoldPrice())
        {
            return false;
        }

#ifdef WJ_PRIVATE_SHOP_CHEQUE
        if (rFilter.wMinCheque > pItem->GetChequePrice() ||
            rFilter.wMaxCheque < pItem->GetChequePrice())
        {
            return false;
        }
#endif
    }

    return true;
}

void CPrivateShopManager::SearchItem(LPDESC pCustomerDesc, TPrivateShopSearchFilter& rFilter, bool bUseFilter, TEMP_BUFFER* pBuf /* = nullptr */)
{
    TEMP_BUFFER buf {};
    DWORD dwCount = 0;
    const static size_t SAFE_RECV_BUFSIZE = 8192;

    /*
        1. Item vnum search
        2. Seller name search
        3. Item type/subtype search
    */
    if (rFilter.dwVnum)
    {
        TItemTable* pItemTable = ITEM_MANAGER::Instance().GetTable(rFilter.dwVnum);
        if (!pItemTable)
            return;

        rFilter.iItemType = pItemTable->bType;
        rFilter.iItemSubType = pItemTable->bSubType;

        auto typeIt = m_map_searchItem.find(rFilter.iItemType);
        if (typeIt == m_map_searchItem.end())
            return;

        TSubTypeItemMap& map_itemSubType = typeIt->second;
        auto subTypeIt = map_itemSubType.find(rFilter.iItemSubType);
        if (subTypeIt == map_itemSubType.end())
            return;

        TItemList& itemList = subTypeIt->second;

        for (const auto& pItem : itemList)
        {
            if (buf.size() + sizeof(TPrivateShopSearchData) > SAFE_RECV_BUFSIZE)
                break;

            if (FilterItem(pItem, rFilter, bUseFilter))
            {
                TPrivateShopSearchData item{};
                CopyItemData(pItem, item);

                if (pCustomerDesc)
                    buf.write(&item, sizeof(TPrivateShopSearchData));
                else if (pBuf)
                    pBuf->write(&item, sizeof(TPrivateShopSearchData));

                ++dwCount;
            }
        }
    }
    else if (rFilter.iItemType >= 0)
    {
        auto typeIt = m_map_searchItem.find(rFilter.iItemType);
        if (typeIt == m_map_searchItem.end())
            return;

        TSubTypeItemMap& map_itemSubType = typeIt->second;

        // Search by type-subtype
        if (rFilter.iItemSubType >= 0)
        {
            auto subTypeIt = map_itemSubType.find(rFilter.iItemSubType);
            if (subTypeIt == map_itemSubType.end())
                return;

            TItemList& itemList = subTypeIt->second;
            for (const auto& pItem : itemList)
            {
                if (buf.size() + sizeof(TPrivateShopSearchData) > SAFE_RECV_BUFSIZE)
                    break;

                if (FilterItem(pItem, rFilter, bUseFilter))
                {
                    TPrivateShopSearchData item{};
                    CopyItemData(pItem, item);

                    if (pCustomerDesc)
                        buf.write(&item, sizeof(TPrivateShopSearchData));
                    else if (pBuf)
                        pBuf->write(&item, sizeof(TPrivateShopSearchData));

                    ++dwCount;
                }
            }
        }
        // Search by type
        else
        {
            for (const auto& kv : map_itemSubType)
            {
                for (const auto& pItem : kv.second)
                {
                    if (buf.size() + sizeof(TPrivateShopSearchData) > SAFE_RECV_BUFSIZE)
                        break;

                    if (FilterItem(pItem, rFilter, bUseFilter))
                    {
                        TPrivateShopSearchData item{};
                        CopyItemData(pItem, item);

                        if (pCustomerDesc)
                            buf.write(&item, sizeof(TPrivateShopSearchData));
                        else if (pBuf)
                            pBuf->write(&item, sizeof(TPrivateShopSearchData));

                        ++dwCount;
                    }
                }
            }
        }
    }

    if (pCustomerDesc)
    {
        if (!dwCount)
            return;

        TPacketGCPrivateShop mainPacket{};
        mainPacket.bHeader = HEADER_GC_PRIVATE_SHOP;
        mainPacket.wSize = sizeof(TPacketGCPrivateShop) + dwCount * sizeof(TPrivateShopSearchData);
        mainPacket.bSubHeader = SUBHEADER_GC_PRIVATE_SHOP_SEARCH_RESULT;

        pCustomerDesc->BufferedPacket(&mainPacket, sizeof(TPacketGCPrivateShop));
        pCustomerDesc->LargePacket(buf.read_peek(), buf.size());
    }
}

private_shop_manager.h:
Genişlet Daralt Kopyala
#pragma once
#include <unordered_map>
#include <unordered_set>
#include "../../common/tables.h"
#include "packet.h"
#include <memory>

class CItem;
class CPrivateShop;
class TEMP_BUFFER;
class CPrivateShopManager : public singleton<CPrivateShopManager>
{
    public:

        CPrivateShopManager() = default;
        ~CPrivateShopManager() = default;

        void                Destroy();

        LPPRIVATE_SHOP        CreatePrivateShop(DWORD dwPID);
        LPPRIVATE_SHOP        GetPrivateShop(DWORD dwPID);
        LPPRIVATE_SHOP        GetPrivateShopByOwnerName(const char* c_szOwnerName);
        LPPRIVATE_SHOP        GetPrivateShopByVID(DWORD dwVID);
        bool                DeletePrivateShop(DWORD dwPID);
        DWORD                AllocVID() { return ++m_dwVIDCount; }

        bool                BuildPrivateShop(LPCHARACTER pShopOwner, const char* c_szTitle, DWORD dwPolyVnum, BYTE bTitleType, BYTE bPageCount, const std::vector<TPrivateShopItem>& c_vec_shopItem);
        void                BuildPrivateShopResult(DWORD dwPID, TPrivateShop* pPrivateShopTable, bool bSuccess);
        void                ClosePrivateShop(LPCHARACTER pShopOwner);

        void                SpawnPrivateShop(TPrivateShop* pTab, const std::vector<TPlayerPrivateShopItem>& c_vec_shopItem);
        void                DespawnPrivateShop(DWORD dwPID);

        bool                StopShopping(LPCHARACTER pShopViewer);

        void                ItemCheckin(LPCHARACTER pOwner, const TPlayerPrivateShopItem* c_pShopItem);
        void                ItemCheckout(LPCHARACTER pOwner, WORD wSrcPos, TItemPos TDstPos);

        bool                ItemTransaction(LPCHARACTER pCustomer, TPlayerPrivateShopItem* c_pShopItem);
        void                SendItemTransaction(const TPlayerPrivateShopItem* c_pShopItem, LPCHARACTER pCustomer);
        void                SendItemTransactionFailedResult(DWORD dwShopID, WORD wPos);
        void                SendItemTransfer(const TPlayerItem* c_pItem);
        void                SendItemExpire(LPITEM pItem);

        void                AddSearchItem(LPITEM pItem);
        void                RemoveSearchItem(LPITEM pItem);
        void                SearchItem(LPDESC pCustomerDesc, TPrivateShopSearchFilter& rFilter, bool bUseFilter, TEMP_BUFFER* pBuf = nullptr);

        typedef std::unordered_map<DWORD, std::unique_ptr<CPrivateShop> >    TPrivateShopMap;
        typedef std::unordered_map<DWORD, LPPRIVATE_SHOP>                    TPrivateShopVIDMap;
        typedef std::unordered_map<DWORD, TItemPrice>                        TMarketPriceMap;

        typedef std::unordered_set<LPITEM>                    TItemList;
        typedef std::unordered_map<BYTE, TItemList>            TSubTypeItemMap;
        typedef std::unordered_map<BYTE, TSubTypeItemMap>    TTypeItemMap;

    private:
        DWORD                m_dwVIDCount;
        TPrivateShopMap        m_map_privateShop;
        TPrivateShopVIDMap    m_map_privateShopVID;
        TTypeItemMap        m_map_searchItem;
};
 
burada eksik gördüm:
Genişlet Daralt Kopyala
void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_DESPAWN;
    DWORD dwOwner = dwPID;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&dwOwner, sizeof(DWORD));

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }
//eklenen kısım
    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (pOwner)
        pOwner->ClosePrivateShop();
//eklenen kısım
    sys_log(0, "%s PRIVATE_SHOP: Shop entity despawned", pPrivateShop->GetOwnerName().c_str());
    DeletePrivateShop(dwPID);
}

DeletePrivateShop sadece managerdaki mapten siliyor, owner character'ındaki m_privateShopTable.dwOwner'ı sıfırlamıyor. Bu yüzden IsPrivateShopOwner hala true dönüyor.

Bende bunu ekledim ;
LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
if (pOwner)
pOwner->ClosePrivateShop();


ClosePrivateShop() zaten memset(&amp;m_privateShopTable, 0, yapıyor yani dwOwner sıfırlanması ve IsPrivateShopun artık false dönmesi lazım .

Bir dene olmazsa tekrar kontrol ederiz.
 
burada eksik gördüm:
Genişlet Daralt Kopyala
void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID)
{
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_DESPAWN;
    DWORD dwOwner = dwPID;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&dwOwner, sizeof(DWORD));

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }
//eklenen kısım
    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (pOwner)
        pOwner->ClosePrivateShop();
//eklenen kısım
    sys_log(0, "%s PRIVATE_SHOP: Shop entity despawned", pPrivateShop->GetOwnerName().c_str());
    DeletePrivateShop(dwPID);
}

DeletePrivateShop sadece managerdaki mapten siliyor, owner character'ındaki m_privateShopTable.dwOwner'ı sıfırlamıyor. Bu yüzden IsPrivateShopOwner hala true dönüyor.

Bende bunu ekledim ;
LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
if (pOwner)
pOwner->ClosePrivateShop();


ClosePrivateShop() zaten memset(&amp;m_privateShopTable, 0, yapıyor yani dwOwner sıfırlanması ve IsPrivateShopun artık false dönmesi lazım .

Bir dene olmazsa tekrar kontrol ederiz.
Hocam bu çalışmadı, hem if satırına hem dışında fonksiyon içerisine sys_log ve sys_err satırları koydum onlar da çalışmadı. Galiba direkt void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID) içine girmiyor.

/usr/game/cores/db/syslog:
Genişlet Daralt Kopyala
Jun  5 04:49:20 :: QID_AFFECT 6
Jun  5 04:49:20 :: QID_PRIVATE_SHOP_ITEM 6
Jun  5 04:49:20 :: PRIVATE_SHOP_ITEM_LOAD: count 0 pid 2
Jun  5 04:49:20 :: QID_PRIVATE_SHOP 6
Jun  5 04:49:21 :: [    20600] return 0/0/6 async 0/0/0
Jun  5 04:49:26 :: [    20650] return 0/0/0 async 0/0/0
Jun  5 04:49:31 :: [    20700] return 0/0/0 async 0/0/0
Jun  5 04:49:36 :: [    20750] return 0/0/0 async 0/0/0
Jun  5 04:49:41 :: [    20800] return 0/0/0 async 0/0/0
Jun  5 04:49:46 :: [    20850] return 0/0/0 async 0/0/0
Jun  5 04:49:51 :: [    20900] return 0/0/0 async 0/0/0
Jun  5 04:49:56 :: [    20950] return 0/0/0 async 0/0/0
Jun  5 04:50:01 :: [    21000] return 0/0/0 async 0/0/0
Jun  5 04:50:04 :: PRIVATE_SHOP: Building private shop 2
Jun  5 04:50:04 :: Re-creating private shop for owner 2
Jun  5 04:50:04 :: PRIVATE_SHOP: Added item 10000293 pos 23 vnum 50708 to private shop 2
Jun  5 04:50:04 :: PRIVATE_SHOP: Private shop 2 successfully created
Jun  5 04:50:04 :: PRIVATE_SHOP: Private shop 2 successfully built
Jun  5 04:50:06 :: [    21050] return 0/0/0 async 0/0/0
Jun  5 04:50:11 :: [    21100] return 0/0/0 async 0/0/0
Jun  5 04:50:16 :: [    21150] return 0/0/0 async 0/0/0
Jun  5 04:50:18 :: PRIVATE_SHOP: Buy request forwarded to game for private shop 2 customer 3 item pos 23 item 50708 yang 1000 won 0
Jun  5 04:50:19 :: PRIVATE_SHOP: Item bought from private shop 2 pos 23 gold 1000 won 0 by pid 3
Jun  5 04:50:19 :: PRIVATE_SHOP: Despawning item empty private shop 2 by item sale
Jun  5 04:50:19 :: PRIVATE_SHOP: Sending despawn update to owner 2
Jun  5 04:50:21 :: [    21200] return 0/0/0 async 0/0/0
Jun  5 04:50:26 :: [    21250] return 0/0/0 async 0/0/0
Jun  5 04:50:31 :: [    21300] return 0/0/0 async 0/0/0
Jun  5 04:50:36 :: [    21350] return 0/0/0 async 0/0/0
Jun  5 04:50:41 :: [    21400] return 0/0/0 async 0/0/0
Jun  5 04:50:46 :: [    21450] return 0/0/0 async 0/0/0
 
ekli olan bir filesten karşılaştır hocam şuan ben neyi nereye ekledin göremiyorum sadece gördüğüm bir kısımı söyledim daha belki çıktıkça çıkar detaylı bakmak lazım
 
Merhaba,
sysloga baktığımda herhangi bir pzar kapanma ibaresi yok. Mesela şu şekilde;
PRIVATE_SHOP: Close shop
PRIVATE_SHOP: Owner cleared
PRIVATE_SHOP: Set state closed
PRIVATE_SHOP: CHARACTER::ClosePrivateShop()
Yani demek oluyoki ClosePrivateShop fonksiyonu hiç çalışmıyor. Ayrıca razu v5 eğer değiştirmediysen mysql kullanıyor. Mysql veri yazarken biraz süre geçmesi gerekiyor veritabanında o bir hata vs sorun değil. Mysqldan kaynaklı bir gecikme.
Şimdi asıl hatamıza gelecek olursak.
Erto'nun dediği kısmen doğru, ancak zaten owner sıfırlanıyor. O fonksiyon çalışmadığı için sıfırlayamıyor.
Bakınız;
char.cpp:
Genişlet Daralt Kopyala
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."));
}

Dolayısıyla dediğim gibi ClosePrivateShop() hiç çağrılmıyor. Syslog bunu destekliyor. Çünkü loglarda Sending despawn update to owner 3 var ama ClosePrivateShop sonrası yok.
İlk kontrol etmemiz gereken yer;
PRIVATE_SHOP: Sending despawn update to owner 3

Kısmı, bunuda srcde Sending despawn update to owner diye arat,

C++:
Genişlet Daralt Kopyala
if (LPCHARACTER ch = CHARACTER_MANAGER::Instance().FindByPID(dwOwner))
{
 .....
}

Bu tarz bir fonksiyonun içinde bulabilirsin. Bu fonksiyon içerisinde,
ch->ClosePrivateShop();

Bu tarz birşey eklimi.

Hatta şöyle birşeyde yapabilirsin. Bunu altdaki ile değiştir. Çıkan log kaydı SHOP CHECK PID 3 OWNER 3 bu olursa %100 teşhisimiz doğru.
Yani Owner field temizlenmemiş. Eğer SHOP CHECK PID 3 OWNER 0 böyle çıkarsa farklı bir yerde farklı kontoller var demektir.
char.h:
Genişlet Daralt Kopyala
        bool                IsPrivateShopOwner() { return m_privateShopTable.dwOwner != 0; }
Bu şekilde kontrol kodlarını ekle;
char.h:
Genişlet Daralt Kopyala
bool CHARACTER::IsPrivateShopOwner()
{
    sys_err("SHOP CHECK PID %u OWNER %u",
        GetPlayerID(),
        m_privateShopTable.dwOwner);

    return m_privateShopTable.dwOwner != 0;
}
 
Merhaba,
sysloga baktığımda herhangi bir pzar kapanma ibaresi yok. Mesela şu şekilde;
PRIVATE_SHOP: Close shop
PRIVATE_SHOP: Owner cleared
PRIVATE_SHOP: Set state closed
PRIVATE_SHOP: CHARACTER::ClosePrivateShop()
Yani demek oluyoki ClosePrivateShop fonksiyonu hiç çalışmıyor. Ayrıca razu v5 eğer değiştirmediysen mysql kullanıyor. Mysql veri yazarken biraz süre geçmesi gerekiyor veritabanında o bir hata vs sorun değil. Mysqldan kaynaklı bir gecikme.
Şimdi asıl hatamıza gelecek olursak.
Erto'nun dediği kısmen doğru, ancak zaten owner sıfırlanıyor. O fonksiyon çalışmadığı için sıfırlayamıyor.
Bakınız;
char.cpp:
Genişlet Daralt Kopyala
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."));
}

Dolayısıyla dediğim gibi ClosePrivateShop() hiç çağrılmıyor. Syslog bunu destekliyor. Çünkü loglarda Sending despawn update to owner 3 var ama ClosePrivateShop sonrası yok.
İlk kontrol etmemiz gereken yer;


Kısmı, bunuda srcde Sending despawn update to owner diye arat,

C++:
Genişlet Daralt Kopyala
if (LPCHARACTER ch = CHARACTER_MANAGER::Instance().FindByPID(dwOwner))
{
 .....
}

Bu tarz bir fonksiyonun içinde bulabilirsin. Bu fonksiyon içerisinde,
ch->ClosePrivateShop();

Bu tarz birşey eklimi.

Hatta şöyle birşeyde yapabilirsin. Bunu altdaki ile değiştir. Çıkan log kaydı SHOP CHECK PID 3 OWNER 3 bu olursa %100 teşhisimiz doğru.
Yani Owner field temizlenmemiş. Eğer SHOP CHECK PID 3 OWNER 0 böyle çıkarsa farklı bir yerde farklı kontoller var demektir.
char.h:
Genişlet Daralt Kopyala
        bool                IsPrivateShopOwner() { return m_privateShopTable.dwOwner != 0; }
Bu şekilde kontrol kodlarını ekle;
char.h:
Genişlet Daralt Kopyala
bool CHARACTER::IsPrivateShopOwner()
{
    sys_err("SHOP CHECK PID %u OWNER %u",
        GetPlayerID(),
        m_privateShopTable.dwOwner);

    return m_privateShopTable.dwOwner != 0;
}

Bahsetmiş olduğunuz char.h kontrollerini ekledim. Syslog kısmında sizin de dediğiniz gibi pazarı açmadan önce SHOP CHECK PID 4 OWNER 0, pazar kapandıktan sonra paketle etkileşime geçince SHOP CHECK PID 4 OWNER 4 basıyor.
char.h Değişiklik:
Genişlet Daralt Kopyala
        bool IsPrivateShopOwner()
        {
            sys_err("SHOP CHECK PID %u OWNER %u",
            GetPlayerID(),
            m_privateShopTable.dwOwner);

            return m_privateShopTable.dwOwner != 0;
        }
/usr/game/cores/channel1/syslog:
Genişlet Daralt Kopyala
Jun  5 08:55:38 :: KucukAdam: USE_ITEM Paket (inven 1, cell: 2)
SYSERR: Jun  5 08:55:38 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 0
SYSERR: Jun  5 08:55:48 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 0
Jun  5 08:55:48 :: KucukAdam PRIVATE_SHOP: STATE CHANGE 0 -> 2
Jun  5 08:55:48 :: KucukAdam PRIVATE_SHOP: SUCCESS Shop entity created
Jun  5 08:55:52 :: KucukAdam PRIVATE_SHOP: VIEWER ADDED name Melih pid 3
Jun  5 08:55:52 :: reallocating buffer to 16384, current 1024
SYSERR: Jun  5 08:55:54 :: locale_find: LOCALE_ERROR: "You have bought %s.";
Jun  5 08:55:54 :: PRIVATE_SHOP: SUCCESS Item transaction for customer Melih item 10000658 189 from shop 4
SYSERR: Jun  5 08:55:54 :: locale_find: LOCALE_ERROR: "You have sold x%d %s for %s Yangs.";
Jun  5 08:55:54 :: KucukAdam PRIVATE_SHOP: REMOVED VIEWERS
Jun  5 08:55:55 :: SpawnMob: cannot create monster at non-exist sectree 405100 x 656600 (map 61)
Jun  5 08:56:00 :: GLOBAL_TIME: Jun  5 08:56:00 time_gap 0
Jun  5 08:56:03 :: Melih: ITEM_SPLIT Paket (window: 1, cell : 7) -> (window:1, cell 22) count 1
Jun  5 08:56:05 :: CInputMain()::Exchange()  SubHeader 0
Jun  5 08:56:06 :: CInputMain()::Exchange()  SubHeader 1
Jun  5 08:56:06 :: EXCHANGE AddItem success Paket pos(1, 22) 2
Jun  5 08:56:06 :: CInputMain()::Exchange()  SubHeader 4
Jun  5 08:56:06 :: CInputMain()::Exchange() ==> ACCEPT
Jun  5 08:56:07 :: CInputMain()::Exchange()  SubHeader 4
Jun  5 08:56:07 :: CInputMain()::Exchange() ==> ACCEPT
Jun  5 08:56:08 :: KucukAdam: USE_ITEM Paket (inven 1, cell: 2)
SYSERR: Jun  5 08:56:08 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 4

Sending despawn update to owner çıktısını kodlar içinde arattığımda ise sadece ClientManagerPrivateShop.cpp içerisinde bulabildim. Dediğiniz gibi içerisinde ClosePrivateShop() ile ilgili bir şey yok. Rehberi de kontrol ettim bu şekilde eklenmiş. Oyuncu aktifken sadece state durumunu değiştiriyor, değilken DeletePrivateShop() çağırıyor.
İlgili kısım:

ClientManagerPrivateShop.cpp:
Genişlet Daralt Kopyala
// Called upon last item checkout / last item sale
void CClientManager::PrivateShopGameDespawn(LPPRIVATE_SHOP pPrivateShop)
{
    BYTE bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE;

    CPeer* pOwnerPeer = GetPeer(pPrivateShop->GetOwnerPeerHandle());
    CPeer* pShopPeer = GetPeer(pPrivateShop->GetShopPeerHandle());

    TPacketDGPrivateShopStateUpdate subPacket {};
    subPacket.dwPID = pPrivateShop->GetOwner();;
    subPacket.bState = STATE_CLOSED;

    pPrivateShop->ChangeState(STATE_CLOSED);

    if (pOwnerPeer)
    {
        pOwnerPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, pPrivateShop->GetOwnerHandle(), sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pOwnerPeer->Encode(&bSubHeader, sizeof(BYTE));
        pOwnerPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));

        sys_log(0, "PRIVATE_SHOP: Sending despawn update to owner %u",     subPacket.dwPID);
    }
    else
    {
        // Flush private shop data immediately and delete the instance if owner is offline
        if (GetPrivateShopCache(pPrivateShop->GetOwner()))
            FlushPrivateShopCache(pPrivateShop->GetOwner());

        if (GetPrivateShopItemCacheSet(pPrivateShop->GetOwner()))
            FlushPrivateShopItemCacheSet(pPrivateShop->GetOwner());

        if (IsPrivateShopPremiumEvent(pPrivateShop->GetOwner()))
            PrivateShopEndPremiumEvent(pPrivateShop->GetOwner());

        DeletePrivateShop(pPrivateShop->GetOwner());

        sys_log(0, "PRIVATE_SHOP: Deleting despawned private shop %u", subPacket.dwPID);
    }

    if (pShopPeer && pShopPeer != pOwnerPeer)
    {
        pShopPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pShopPeer->Encode(&bSubHeader, sizeof(BYTE));
        pShopPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));
    }
}
 
Bahsetmiş olduğunuz char.h kontrollerini ekledim. Syslog kısmında sizin de dediğiniz gibi pazarı açmadan önce SHOP CHECK PID 4 OWNER 0, pazar kapandıktan sonra paketle etkileşime geçince SHOP CHECK PID 4 OWNER 4 basıyor.
char.h Değişiklik:
Genişlet Daralt Kopyala
        bool IsPrivateShopOwner()
        {
            sys_err("SHOP CHECK PID %u OWNER %u",
            GetPlayerID(),
            m_privateShopTable.dwOwner);

            return m_privateShopTable.dwOwner != 0;
        }
/usr/game/cores/channel1/syslog:
Genişlet Daralt Kopyala
Jun  5 08:55:38 :: KucukAdam: USE_ITEM Paket (inven 1, cell: 2)
SYSERR: Jun  5 08:55:38 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 0
SYSERR: Jun  5 08:55:48 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 0
Jun  5 08:55:48 :: KucukAdam PRIVATE_SHOP: STATE CHANGE 0 -> 2
Jun  5 08:55:48 :: KucukAdam PRIVATE_SHOP: SUCCESS Shop entity created
Jun  5 08:55:52 :: KucukAdam PRIVATE_SHOP: VIEWER ADDED name Melih pid 3
Jun  5 08:55:52 :: reallocating buffer to 16384, current 1024
SYSERR: Jun  5 08:55:54 :: locale_find: LOCALE_ERROR: "You have bought %s.";
Jun  5 08:55:54 :: PRIVATE_SHOP: SUCCESS Item transaction for customer Melih item 10000658 189 from shop 4
SYSERR: Jun  5 08:55:54 :: locale_find: LOCALE_ERROR: "You have sold x%d %s for %s Yangs.";
Jun  5 08:55:54 :: KucukAdam PRIVATE_SHOP: REMOVED VIEWERS
Jun  5 08:55:55 :: SpawnMob: cannot create monster at non-exist sectree 405100 x 656600 (map 61)
Jun  5 08:56:00 :: GLOBAL_TIME: Jun  5 08:56:00 time_gap 0
Jun  5 08:56:03 :: Melih: ITEM_SPLIT Paket (window: 1, cell : 7) -> (window:1, cell 22) count 1
Jun  5 08:56:05 :: CInputMain()::Exchange()  SubHeader 0
Jun  5 08:56:06 :: CInputMain()::Exchange()  SubHeader 1
Jun  5 08:56:06 :: EXCHANGE AddItem success Paket pos(1, 22) 2
Jun  5 08:56:06 :: CInputMain()::Exchange()  SubHeader 4
Jun  5 08:56:06 :: CInputMain()::Exchange() ==> ACCEPT
Jun  5 08:56:07 :: CInputMain()::Exchange()  SubHeader 4
Jun  5 08:56:07 :: CInputMain()::Exchange() ==> ACCEPT
Jun  5 08:56:08 :: KucukAdam: USE_ITEM Paket (inven 1, cell: 2)
SYSERR: Jun  5 08:56:08 :: IsPrivateShopOwner: SHOP CHECK PID 4 OWNER 4

Sending despawn update to owner çıktısını kodlar içinde arattığımda ise sadece ClientManagerPrivateShop.cpp içerisinde bulabildim. Dediğiniz gibi içerisinde ClosePrivateShop() ile ilgili bir şey yok. Rehberi de kontrol ettim bu şekilde eklenmiş. Oyuncu aktifken sadece state durumunu değiştiriyor, değilken DeletePrivateShop() çağırıyor.
İlgili kısım:

ClientManagerPrivateShop.cpp:
Genişlet Daralt Kopyala
// Called upon last item checkout / last item sale
void CClientManager::PrivateShopGameDespawn(LPPRIVATE_SHOP pPrivateShop)
{
    BYTE bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE;

    CPeer* pOwnerPeer = GetPeer(pPrivateShop->GetOwnerPeerHandle());
    CPeer* pShopPeer = GetPeer(pPrivateShop->GetShopPeerHandle());

    TPacketDGPrivateShopStateUpdate subPacket {};
    subPacket.dwPID = pPrivateShop->GetOwner();;
    subPacket.bState = STATE_CLOSED;

    pPrivateShop->ChangeState(STATE_CLOSED);

    if (pOwnerPeer)
    {
        pOwnerPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, pPrivateShop->GetOwnerHandle(), sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pOwnerPeer->Encode(&bSubHeader, sizeof(BYTE));
        pOwnerPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));

        sys_log(0, "PRIVATE_SHOP: Sending despawn update to owner %u",     subPacket.dwPID);
    }
    else
    {
        // Flush private shop data immediately and delete the instance if owner is offline
        if (GetPrivateShopCache(pPrivateShop->GetOwner()))
            FlushPrivateShopCache(pPrivateShop->GetOwner());

        if (GetPrivateShopItemCacheSet(pPrivateShop->GetOwner()))
            FlushPrivateShopItemCacheSet(pPrivateShop->GetOwner());

        if (IsPrivateShopPremiumEvent(pPrivateShop->GetOwner()))
            PrivateShopEndPremiumEvent(pPrivateShop->GetOwner());

        DeletePrivateShop(pPrivateShop->GetOwner());

        sys_log(0, "PRIVATE_SHOP: Deleting despawned private shop %u", subPacket.dwPID);
    }

    if (pShopPeer && pShopPeer != pOwnerPeer)
    {
        pShopPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pShopPeer->Encode(&bSubHeader, sizeof(BYTE));
        pShopPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));
    }
}
PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE bu yada TPacketDGPrivateShopStateUpdate bunun geçtiği case bloklarını atarmısın. Birde input_db.cpp eklersen güzel olur.
 
PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE geçtiği kısımlar:
input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

ClientManagerPrivateShop.cpp:
Genişlet Daralt Kopyala
void CClientManager::PrivateShopModifyRequest(CPeer* pPeer, DWORD dwHandle, const char* c_szData)
{
    const DWORD dwPID = *reinterpret_cast<const DWORD*>(c_szData);
    BYTE bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE;

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop || pPrivateShop->GetState() == STATE_CLOSED)
    {
        bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_NO_SHOP;
        pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE));
        pPeer->Encode(&bSubHeader, sizeof(BYTE));

        sys_err("Cannot find private shop %u", dwPID);
        return;
    }

    CPeer* pShopPeer = GetPeer(pPrivateShop->GetShopPeerHandle());
    if (!pShopPeer)
    {
        bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_SHOP_NOT_AVAILABLE;
        pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE));
        pPeer->Encode(&bSubHeader, sizeof(BYTE));

        sys_err("Cannot find private shop peer for private shop %u", dwPID);
        return;
    }

    // Update state of the shop
    BYTE bState = pPrivateShop->GetState();
    if (bState == STATE_OPEN)
    {
        pPrivateShop->ChangeState(STATE_MODIFY);
        bState = STATE_MODIFY;

        sys_log(0, "PRIVATE_SHOP: State changed to modify for private shop %u", dwPID);
    }
    else if (bState == STATE_MODIFY)
    {
        pPrivateShop->ChangeState(STATE_OPEN);
        bState = STATE_OPEN;

        sys_log(0, "PRIVATE_SHOP: State changed to open for private shop %u", dwPID);
    }

    //Send the result back to owner (and shop if it is on the same peer)

    TPacketDGPrivateShopStateUpdate subPacket {};
    subPacket.dwPID = dwPID;
    subPacket.bState = bState;

    pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
    pPeer->Encode(&bSubHeader, sizeof(BYTE));
    pPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));

    // Not needed to be sent twice if both player&shop are on the same peer
    if (pPeer != pShopPeer)
    {
        pShopPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pShopPeer->Encode(&bSubHeader, sizeof(BYTE));
        pShopPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));
    }
}



input_db.cpp full:
Genişlet Daralt Kopyala
#include "stdafx.h"
#include "constants.h"
#include "config.h"
#include "utils.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "item.h"
#include "item_manager.h"
#include "packet.h"
#include "protocol.h"
#include "mob_manager.h"
#include "shop_manager.h"
#include "sectree_manager.h"
#include "skill.h"
#include "questmanager.h"
#include "p2p.h"
#include "guild.h"
#include "guild_manager.h"
#include "start_position.h"
#include "party.h"
#include "refine.h"
#include "banword.h"
#include "priv_manager.h"
#include "db.h"
#include "building.h"
#include "login_sim.h"
#include "wedding.h"
#include "login_data.h"
#include "unique_item.h"
#include "affect.h"
#include "castle.h"
#ifdef WJ_PREMIUM_PRIVATE_SHOP
#include "private_shop_manager.h"
#include "private_shop.h"
#include "private_shop_util.h"
#endif
#include "motion.h"

#include "dev_log.h"

#include "log.h"

#include "horsename_manager.h"
#include "pcbang.h"
#include "gm.h"
#include "panama.h"
#include "map_location.h"

#include "XTrapManager.h"

#include "DragonSoul.h"

extern BYTE        g_bAuthServer;
extern void gm_insert(const char * name, BYTE level);
extern BYTE    gm_get_level(const char * name, const char * host, const char* account );
extern void gm_host_insert(const char * host);

#define MAPNAME_DEFAULT    "none"

bool GetServerLocation(TAccountTable & rTab, BYTE bEmpire)
{
    bool bFound = false;

    for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
    {
        if (0 == rTab.players[i].dwID)
            continue;

        bFound = true;
        long lIndex = 0;

        if (!CMapLocation::instance().Get(rTab.players[i].x,
                    rTab.players[i].y,
                    lIndex,
                    rTab.players[i].lAddr,
                    rTab.players[i].wPort))
        {
            sys_err("location error name %s mapindex %d %d x %d empire %d",
                    rTab.players[i].szName, lIndex, rTab.players[i].x, rTab.players[i].y, rTab.bEmpire);

            rTab.players[i].x = EMPIRE_START_X(rTab.bEmpire);
            rTab.players[i].y = EMPIRE_START_Y(rTab.bEmpire);

            lIndex = 0;

            if (!CMapLocation::instance().Get(rTab.players[i].x, rTab.players[i].y, lIndex, rTab.players[i].lAddr, rTab.players[i].wPort))
            {
                sys_err("cannot find server for mapindex %d %d x %d (name %s)",
                        lIndex,
                        rTab.players[i].x,
                        rTab.players[i].y,
                        rTab.players[i].szName);

                continue;
            }
        }

        struct in_addr in;
        in.s_addr = rTab.players[i].lAddr;
        sys_log(0, "success to %s:%d", inet_ntoa(in), rTab.players[i].wPort);
    }

    return bFound;
}

extern std::map<DWORD, CLoginSim *> g_sim;
extern std::map<DWORD, CLoginSim *> g_simByPID;

void CInputDB::LoginSuccess(DWORD dwHandle, const char *data)
{
    sys_log(0, "LoginSuccess");

    TAccountTable * pTab = (TAccountTable *) data;

    itertype(g_sim) it = g_sim.find(pTab->id);
    if (g_sim.end() != it)
    {
        sys_log(0, "CInputDB::LoginSuccess - already exist sim [%s]", pTab->login);
        it->second->SendLoad();
        return;
    }

    LPDESC d = DESC_MANAGER::instance().FindByHandle(dwHandle);

    if (!d)
    {
        sys_log(0, "CInputDB::LoginSuccess - cannot find handle [%s]", pTab->login);

        TLogoutPacket pack;

        strlcpy(pack.login, pTab->login, sizeof(pack.login));
        db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));
        return;
    }

    if (strcmp(pTab->status, "OK")) // OK가 아니면
    {
        sys_log(0, "CInputDB::LoginSuccess - status[%s] is not OK [%s]", pTab->status, pTab->login);

        TLogoutPacket pack;

        strlcpy(pack.login, pTab->login, sizeof(pack.login));
        db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));

        LoginFailure(d, pTab->status);
        return;
    }

    for (int i = 0; i != PLAYER_PER_ACCOUNT; ++i)
    {
        TSimplePlayer& player = pTab->players[i];
        sys_log(0, "\tplayer(%s).job(%d)", player.szName, player.byJob);
    }

    bool bFound = GetServerLocation(*pTab, pTab->bEmpire);

    d->BindAccountTable(pTab);

    if (!bFound) // 캐릭터가 없으면 랜덤한 제국으로 보낸다.. -_-
    {
        TPacketGCEmpire pe;
        pe.bHeader = HEADER_GC_EMPIRE;
        pe.bEmpire = number(1, 3);
        d->Packet(&pe, sizeof(pe));
    }
    else
    {
        TPacketGCEmpire pe;
        pe.bHeader = HEADER_GC_EMPIRE;
        pe.bEmpire = d->GetEmpire();
        d->Packet(&pe, sizeof(pe));
    }

    d->SetPhase(PHASE_SELECT);
    d->SendLoginSuccessPacket();

    sys_log(0, "InputDB::login_success: %s", pTab->login);
}

void CInputDB::PlayerCreateFailure(LPDESC d, BYTE bType)
{
    if (!d)
        return;

    TPacketGCCreateFailure pack;

    pack.header    = HEADER_GC_CHARACTER_CREATE_FAILURE;
    pack.bType    = bType;

    d->Packet(&pack, sizeof(pack));
}

void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data)
{
    if (!d)
        return;

    TPacketDGCreateSuccess * pPacketDB = (TPacketDGCreateSuccess *) data;

    if (pPacketDB->bAccountCharacterIndex >= PLAYER_PER_ACCOUNT)
    {
        d->Packet(encode_byte(HEADER_GC_CHARACTER_CREATE_FAILURE), 1);
        return;
    }

    long lIndex = 0;

    if (!CMapLocation::instance().Get(pPacketDB->player.x,
                pPacketDB->player.y,
                lIndex,
                pPacketDB->player.lAddr,
                pPacketDB->player.wPort))
    {
        sys_err("InputDB::PlayerCreateSuccess: cannot find server for mapindex %d %d x %d (name %s)",
                lIndex,
                pPacketDB->player.x,
                pPacketDB->player.y,
                pPacketDB->player.szName);
    }

    TAccountTable & r_Tab = d->GetAccountTable();
    r_Tab.players[pPacketDB->bAccountCharacterIndex] = pPacketDB->player;

    TPacketGCPlayerCreateSuccess pack;

    pack.header = HEADER_GC_CHARACTER_CREATE_SUCCESS;
    pack.bAccountCharacterIndex = pPacketDB->bAccountCharacterIndex;
    pack.player = pPacketDB->player;

    d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess));

    // 기본 무기와 귀환부를 지급
    TPlayerItem t;
    memset(&t, 0, sizeof(t));

    if (china_event_server)
    {
        t.window    = INVENTORY;
        t.count    = 1;
        t.owner    = r_Tab.players[pPacketDB->bAccountCharacterIndex].dwID;

        //무사: 자인갑+3,철편투구+3,금편신발+3,남만도+3,백금목걸이+3, 흑단귀걸이+3, 소산부+3, 오각패+3, 흑단팔찌+3
        //자객:영린+3,연환두건+3,금편신발+3,마안도+3,화안궁+3,옥목걸이+3, 옥귀걸이+3, 오각패+3, 흑단팔찌+3
        //수라:음양갑+3,애희투구+3,금편신발+3,남만도+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3
        //무당:서천의+3,태을모+3,금편신발+3,자린선+3,매화령+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3

        struct SInitialItem
        {
            DWORD dwVnum;
            BYTE pos;
        };

        const int MAX_INITIAL_ITEM = 9;

        static SInitialItem initialItems[JOB_MAX_NUM][MAX_INITIAL_ITEM] =
        {
            { {11243,    2}, {12223,    3}, {15103,    4}, {   93,    1}, {16143,    8}, {17103,    9}, { 3083,    0}, {13193,    11}, {14103, 12}, },
            { {11443,    0}, {12363,    3}, {15103,    4}, { 1053,    2}, { 2083,    1}, {16083,    7}, {17083,    8}, {13193,    9}, {14103,    10}, },
            { {11643,    0}, {12503,    2}, {15103,    3}, {   93,    1}, {16123,    4}, {17143,    7}, {13193,    8}, {14103,    9}, {    0,    0}, },
            { {11843,    0}, {12643,    1}, {15103,    2}, { 7083,    3}, { 5053,    4}, {16123,    6}, {17143,    7}, {13193,    8}, {14103,    9}, },
        };

        int job = pPacketDB->player.byJob;
        for (int i=0; i < MAX_INITIAL_ITEM; i++)
        {
            if (initialItems[job][i].dwVnum == 0)
                continue;

            t.id    = ITEM_MANAGER::instance().GetNewID();
            t.pos    = initialItems[job][i].pos;
            t.vnum    = initialItems[job][i].dwVnum;

            db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_SAVE, 0, sizeof(TPlayerItem));
            db_clientdesc->Packet(&t, sizeof(TPlayerItem));
        }
    }

    LogManager::instance().CharLog(pack.player.dwID, 0, 0, 0, "CREATE PLAYER", "", d->GetHostName());
}

void CInputDB::PlayerDeleteSuccess(LPDESC d, const char * data)
{
    if (!d)
        return;

    BYTE account_index;
    account_index = decode_byte(data);
    d->BufferedPacket(encode_byte(HEADER_GC_CHARACTER_DELETE_SUCCESS),    1);
    d->Packet(encode_byte(account_index),            1);

    d->GetAccountTable().players[account_index].dwID = 0;
}

void CInputDB::PlayerDeleteFail(LPDESC d)
{
    if (!d)
        return;

    d->Packet(encode_byte(HEADER_GC_CHARACTER_DELETE_WRONG_SOCIAL_ID),    1);
    //d->Packet(encode_byte(account_index),            1);

    //d->GetAccountTable().players[account_index].dwID = 0;
}

void CInputDB::ChangeName(LPDESC d, const char * data)
{
    if (!d)
        return;

    TPacketDGChangeName * p = (TPacketDGChangeName *) data;

    TAccountTable & r = d->GetAccountTable();

    if (!r.id)
        return;

    for (size_t i = 0; i < PLAYER_PER_ACCOUNT; ++i)
        if (r.players[i].dwID == p->pid)
        {
            strlcpy(r.players[i].szName, p->name, sizeof(r.players[i].szName));
            r.players[i].bChangeName = 0;

            TPacketGCChangeName pgc;

            pgc.header = HEADER_GC_CHANGE_NAME;
            pgc.pid = p->pid;
            strlcpy(pgc.name, p->name, sizeof(pgc.name));

            d->Packet(&pgc, sizeof(TPacketGCChangeName));
            break;
        }
}

void CInputDB::PlayerLoad(LPDESC d, const char * data)
{
    TPlayerTable * pTab = (TPlayerTable *) data;

    if (!d)
        return;

    long lMapIndex = pTab->lMapIndex;
    PIXEL_POSITION pos;

    if (lMapIndex == 0)
    {
        lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(pTab->x, pTab->y);

        if (lMapIndex == 0) // 좌표를 찾을 수 없다.
        {
            lMapIndex = EMPIRE_START_MAP(d->GetAccountTable().bEmpire);
            pos.x = EMPIRE_START_X(d->GetAccountTable().bEmpire);
            pos.y = EMPIRE_START_Y(d->GetAccountTable().bEmpire);
        }
        else
        {
            pos.x = pTab->x;
            pos.y = pTab->y;
        }
    }
    pTab->lMapIndex = lMapIndex;

    // Private 맵에 있었는데, Private 맵이 사라진 상태라면 출구로 돌아가야 한다.
    // ----
    // 근데 출구로 돌아가야 한다면서... 왜 출구가 아니라 private map 상에 대응되는 pulic map의 위치를 찾냐고...
    // 역사를 모르니... 또 하드코딩 한다.
    // 아귀동굴이면, 출구로...
    // by rtsummit
    if (!SECTREE_MANAGER::instance().GetValidLocation(pTab->lMapIndex, pTab->x, pTab->y, lMapIndex, pos, d->GetEmpire()))
    {
        sys_err("InputDB::PlayerLoad : cannot find valid location %d x %d (name: %s)", pTab->x, pTab->y, pTab->name);
        d->SetPhase(PHASE_CLOSE);
        return;
    }

    pTab->x = pos.x;
    pTab->y = pos.y;
    pTab->lMapIndex = lMapIndex;

    if (d->GetCharacter() || d->IsPhase(PHASE_GAME))
    {
        LPCHARACTER p = d->GetCharacter();
        sys_err("login state already has main state (character %s %p)", p->GetName(), get_pointer(p));
        return;
    }

    if (NULL != CHARACTER_MANAGER::Instance().FindPC(pTab->name))
    {
        sys_err("InputDB: PlayerLoad : %s already exist in game", pTab->name);
        return;
    }

    LPCHARACTER ch = CHARACTER_MANAGER::instance().CreateCharacter(pTab->name, pTab->id);

    ch->BindDesc(d);
    ch->SetPlayerProto(pTab);
    ch->SetEmpire(d->GetEmpire());

    d->BindCharacter(ch);
    
    {
        // P2P Login
        TPacketGGLogin p;

        p.bHeader = HEADER_GG_LOGIN;
        strlcpy(p.szName, ch->GetName(), sizeof(p.szName));
        p.dwPID = ch->GetPlayerID();
        p.bEmpire = ch->GetEmpire();
        p.lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(ch->GetX(), ch->GetY());
        p.bChannel = g_bChannel;

        P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogin));

        char buf[51];
        snprintf(buf, sizeof(buf), "%s %d %d %ld %d",
                inet_ntoa(ch->GetDesc()->GetAddr().sin_addr), ch->GetGold(), g_bChannel, ch->GetMapIndex(), ch->GetAlignment());
        LogManager::instance().CharLog(ch, 0, "LOGIN", buf);

        if (LC_IsYMIR() || LC_IsKorea() || LC_IsBrazil() || LC_IsJapan())
        {
            LogManager::instance().LoginLog(true,
                    ch->GetDesc()->GetAccountTable().id, ch->GetPlayerID(), ch->GetLevel(), ch->GetJob(), ch->GetRealPoint(POINT_PLAYTIME));

            if (LC_IsBrazil() != true )
            {
                ch->SetPCBang(CPCBangManager::instance().IsPCBangIP(ch->GetDesc()->GetHostName()));
            }
        }
    }

    d->SetPhase(PHASE_LOADING);
    ch->MainCharacterPacket();

    long lPublicMapIndex = lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex;

    //Send Supplementary Data Block if new map requires security packages in loading this map
    const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lPublicMapIndex);
    if( rMapRgn )
    {
        DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( d, rMapRgn->strMapName.c_str() );   
    }
    //if (!map_allow_find(lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex) || !CheckEmpire(ch, lMapIndex))
    if (!map_allow_find(lPublicMapIndex))
    {
        sys_err("InputDB::PlayerLoad : entering %d map is not allowed here (name: %s, empire %u)",
                lMapIndex, pTab->name, d->GetEmpire());

        ch->SetWarpLocation(EMPIRE_START_MAP(d->GetEmpire()),
                EMPIRE_START_X(d->GetEmpire()) / 100,
                EMPIRE_START_Y(d->GetEmpire()) / 100);

        d->SetPhase(PHASE_CLOSE);
        return;
    }

    quest::CQuestManager::instance().BroadcastEventFlagOnLogin(ch);

    for (int i = 0; i < QUICKSLOT_MAX_NUM; ++i)
        ch->SetQuickslot(i, pTab->quickslot[i]);

    ch->PointsPacket();
    ch->SkillLevelPacket();

    sys_log(0, "InputDB: player_load %s %dx%dx%d LEVEL %d MOV_SPEED %d JOB %d ATG %d DFG %d GMLv %d",
            pTab->name,
            ch->GetX(), ch->GetY(), ch->GetZ(),
            ch->GetLevel(),
            ch->GetPoint(POINT_MOV_SPEED),
            ch->GetJob(),
            ch->GetPoint(POINT_ATT_GRADE),
            ch->GetPoint(POINT_DEF_GRADE),
            ch->GetGMLevel());

    ch->QuerySafeboxSize();

    CXTrapManager::instance().CreateClientSession( ch );
}

void CInputDB::Boot(const char* data)
{
    signal_timer_disable();

    // 패킷 사이즈 체크
    DWORD dwPacketSize = decode_4bytes(data);
    data += 4;

    // 패킷 버전 체크
    BYTE bVersion = decode_byte(data);
    data += 1;

    sys_log(0, "BOOT: PACKET: %d", dwPacketSize);
    sys_log(0, "BOOT: VERSION: %d", bVersion);
    if (bVersion != 6)
    {
        sys_err("boot version error");
        thecore_shutdown();
    }

    sys_log(0, "sizeof(TMobTable) = %d", sizeof(TMobTable));
    sys_log(0, "sizeof(TItemTable) = %d", sizeof(TItemTable));
    sys_log(0, "sizeof(TShopTable) = %d", sizeof(TShopTable));
    sys_log(0, "sizeof(TSkillTable) = %d", sizeof(TSkillTable));
    sys_log(0, "sizeof(TRefineTable) = %d", sizeof(TRefineTable));
    sys_log(0, "sizeof(TItemAttrTable) = %d", sizeof(TItemAttrTable));
    sys_log(0, "sizeof(TItemRareTable) = %d", sizeof(TItemAttrTable));
    sys_log(0, "sizeof(TBanwordTable) = %d", sizeof(TBanwordTable));
    sys_log(0, "sizeof(TLand) = %d", sizeof(building::TLand));
    sys_log(0, "sizeof(TObjectProto) = %d", sizeof(building::TObjectProto));
    sys_log(0, "sizeof(TObject) = %d", sizeof(building::TObject));
    //ADMIN_MANAGER
    sys_log(0, "sizeof(TAdminManager) = %d", sizeof (TAdminInfo) );
    //END_ADMIN_MANAGER

    WORD size;

    /*
     * MOB
     */

    if (decode_2bytes(data)!=sizeof(TMobTable))
    {
        sys_err("mob table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: MOB: %d", size);

    if (size)
    {
        CMobManager::instance().Initialize((TMobTable *) data, size);
        data += size * sizeof(TMobTable);
    }

    /*
     * ITEM
     */

    if (decode_2bytes(data) != sizeof(TItemTable))
    {
        sys_err("item table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM: %d", size);


    if (size)
    {
        ITEM_MANAGER::instance().Initialize((TItemTable *) data, size);
        data += size * sizeof(TItemTable);
    }

    /*
     * SHOP
     */

    if (decode_2bytes(data) != sizeof(TShopTable))
    {
        sys_err("shop table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: SHOP: %d", size);


    if (size)
    {
        if (!CShopManager::instance().Initialize((TShopTable *) data, size))
        {
            sys_err("shop table Initialize error");
            thecore_shutdown();
            return;
        }
        data += size * sizeof(TShopTable);
    }

    /*
     * SKILL
     */

    if (decode_2bytes(data) != sizeof(TSkillTable))
    {
        sys_err("skill table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: SKILL: %d", size);

    if (size)
    {
        if (!CSkillManager::instance().Initialize((TSkillTable *) data, size))
        {
            sys_err("cannot initialize skill table");
            thecore_shutdown();
            return;
        }

        data += size * sizeof(TSkillTable);
    }
    /*
     * REFINE RECIPE
     */
    if (decode_2bytes(data) != sizeof(TRefineTable))
    {
        sys_err("refine table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: REFINE: %d", size);

    if (size)
    {
        CRefineManager::instance().Initialize((TRefineTable*) data, size);
        data += size * sizeof(TRefineTable);
    }

    /*
     * ITEM ATTR
     */
    if (decode_2bytes(data) != sizeof(TItemAttrTable))
    {
        sys_err("item attr table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM_ATTR: %d", size);

    if (size)
    {
        TItemAttrTable * p = (TItemAttrTable *) data;

        for (int i = 0; i < size; ++i, ++p)
        {
            if (p->dwApplyIndex >= MAX_APPLY_NUM)
                continue;

            g_map_itemAttr[p->dwApplyIndex] = *p;
            sys_log(0, "ITEM_ATTR[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
        }
    }

    data += size * sizeof(TItemAttrTable);


    /*
     * ITEM RARE
     */
    if (decode_2bytes(data) != sizeof(TItemAttrTable))
    {
        sys_err("item rare table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM_RARE: %d", size);

    if (size)
    {
        TItemAttrTable * p = (TItemAttrTable *) data;

        for (int i = 0; i < size; ++i, ++p)
        {
            if (p->dwApplyIndex >= MAX_APPLY_NUM)
                continue;

            g_map_itemRare[p->dwApplyIndex] = *p;
            sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
        }
    }

    data += size * sizeof(TItemAttrTable);


    /*
     * BANWORDS
     */

    if (decode_2bytes(data) != sizeof(TBanwordTable))
    {
        sys_err("ban word table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;

    CBanwordManager::instance().Initialize((TBanwordTable *) data, size);
    data += size * sizeof(TBanwordTable);

    {
        using namespace building;

        /*
         * LANDS
         */

        if (decode_2bytes(data) != sizeof(TLand))
        {
            sys_err("land table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        TLand * kLand = (TLand *) data;
        data += size * sizeof(TLand);

        for (WORD i = 0; i < size; ++i, ++kLand)
            CManager::instance().LoadLand(kLand);

        /*
         * OBJECT PROTO
         */

        if (decode_2bytes(data) != sizeof(TObjectProto))
        {
            sys_err("object proto table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        CManager::instance().LoadObjectProto((TObjectProto *) data, size);
        data += size * sizeof(TObjectProto);

        /*
         * OBJECT
         */
        if (decode_2bytes(data) != sizeof(TObject))
        {
            sys_err("object table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        TObject * kObj = (TObject *) data;
        data += size * sizeof(TObject);

        for (WORD i = 0; i < size; ++i, ++kObj)
            CManager::instance().LoadObject(kObj, true);
    }
    set_global_time(*(time_t *) data);
    data += sizeof(time_t);

    if (decode_2bytes(data) != sizeof(TItemIDRangeTable) )
    {
        sys_err("ITEM ID RANGE size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;

    TItemIDRangeTable* range = (TItemIDRangeTable*) data;
    data += size * sizeof(TItemIDRangeTable);

    TItemIDRangeTable* rangespare = (TItemIDRangeTable*) data;
    data += size * sizeof(TItemIDRangeTable);

    //ADMIN_MANAGER
    //관리자 등록
    int ChunkSize = decode_2bytes(data );
    data += 2;
    int HostSize = decode_2bytes(data );
    data += 2;
    sys_log(0, "GM Value Count %d %d", HostSize, ChunkSize  );
    for (int n = 0; n < HostSize; ++n )
    {
        gm_new_host_inert(data );
        sys_log(0, "GM HOST : IP[%s] ", data );       
        data += ChunkSize;
    }
    
    
    data += 2;
    int adminsize = decode_2bytes(data );
    data += 2;

    for (int n = 0; n < adminsize; ++n )
    {
        tAdminInfo& rAdminInfo = *(tAdminInfo*)data;

        gm_new_insert(rAdminInfo );
        
        data += sizeof(rAdminInfo );
    }
    
    //END_ADMIN_MANAGER
        

    WORD endCheck=decode_2bytes(data);
    if (endCheck != 0xffff)
    {
        sys_err("boot packet end check error [%x]!=0xffff", endCheck);
        thecore_shutdown();
        return;
    }
    else
        sys_log(0, "boot packet end check ok [%x]==0xffff", endCheck );
    data +=2;

    if (!ITEM_MANAGER::instance().SetMaxItemID(*range))
    {
        sys_err("not enough item id contact your administrator!");
        thecore_shutdown();
        return;
    }

    if (!ITEM_MANAGER::instance().SetMaxSpareItemID(*rangespare))
    {
        sys_err("not enough item id for spare contact your administrator!");
        thecore_shutdown();
        return;
    }



    // LOCALE_SERVICE
    const int FILE_NAME_LEN = 256;
    char szCommonDropItemFileName[FILE_NAME_LEN];
    char szETCDropItemFileName[FILE_NAME_LEN];
    char szMOBDropItemFileName[FILE_NAME_LEN];
    char szDropItemGroupFileName[FILE_NAME_LEN];
    char szSpecialItemGroupFileName[FILE_NAME_LEN];
    char szMapIndexFileName[FILE_NAME_LEN];
    char szItemVnumMaskTableFileName[FILE_NAME_LEN];
    char szDragonSoulTableFileName[FILE_NAME_LEN];

    snprintf(szCommonDropItemFileName, sizeof(szCommonDropItemFileName),
            "%s/common_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szETCDropItemFileName, sizeof(szETCDropItemFileName),
            "%s/etc_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szMOBDropItemFileName, sizeof(szMOBDropItemFileName),
            "%s/mob_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szSpecialItemGroupFileName, sizeof(szSpecialItemGroupFileName),
            "%s/special_item_group.txt", LocaleService_GetBasePath().c_str());
    snprintf(szDropItemGroupFileName, sizeof(szDropItemGroupFileName),
            "%s/drop_item_group.txt", LocaleService_GetBasePath().c_str());
    snprintf(szMapIndexFileName, sizeof(szMapIndexFileName),
            "%s/index", LocaleService_GetMapPath().c_str());
    snprintf(szItemVnumMaskTableFileName, sizeof(szItemVnumMaskTableFileName),
            "%s/ori_to_new_table.txt", LocaleService_GetBasePath().c_str());
    snprintf(szDragonSoulTableFileName, sizeof(szDragonSoulTableFileName),
            "%s/dragon_soul_table.txt", LocaleService_GetBasePath().c_str());

    sys_log(0, "Initializing Informations of Cube System");
    if (!Cube_InformationInitialize())
    {
        sys_err("cannot init cube infomation.");
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: CommonDropItem: %s", szCommonDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadCommonDropItemFile(szCommonDropItemFileName))
    {
        sys_err("cannot load CommonDropItem: %s", szCommonDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: ETCDropItem: %s", szETCDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadEtcDropItemFile(szETCDropItemFileName))
    {
        sys_err("cannot load ETCDropItem: %s", szETCDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: DropItemGroup: %s", szDropItemGroupFileName);
    if (!ITEM_MANAGER::instance().ReadDropItemGroup(szDropItemGroupFileName))
    {
        sys_err("cannot load DropItemGroup: %s", szDropItemGroupFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: SpecialItemGroup: %s", szSpecialItemGroupFileName);
    if (!ITEM_MANAGER::instance().ReadSpecialDropItemFile(szSpecialItemGroupFileName))
    {
        sys_err("cannot load SpecialItemGroup: %s", szSpecialItemGroupFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: ItemVnumMaskTable : %s", szItemVnumMaskTableFileName);
    if (!ITEM_MANAGER::instance().ReadItemVnumMaskTable(szItemVnumMaskTableFileName))
    {
        sys_log(0, "Could not open MaskItemTable");
    }

    sys_log(0, "LoadLocaleFile: MOBDropItemFile: %s", szMOBDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadMonsterDropItemGroup(szMOBDropItemFileName))
    {
        sys_err("cannot load MOBDropItemFile: %s", szMOBDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: MapIndex: %s", szMapIndexFileName);
    if (!SECTREE_MANAGER::instance().Build(szMapIndexFileName, LocaleService_GetMapPath().c_str()))
    {
        sys_err("cannot load MapIndex: %s", szMapIndexFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: DragonSoulTable: %s", szDragonSoulTableFileName);
    if (!DSManager::instance().ReadDragonSoulTableFile(szDragonSoulTableFileName))
    {
        sys_err("cannot load DragonSoulTable: %s", szDragonSoulTableFileName);
        //thecore_shutdown();
        //return;
    }

    // END_OF_LOCALE_SERVICE


    building::CManager::instance().FinalizeBoot();

    CMotionManager::instance().Build();

    signal_timer_enable(30);

    if (test_server)
    {
        CMobManager::instance().DumpRegenCount("mob_count");
    }

    CPCBangManager::instance().RequestUpdateIPList(0);

    // castle_boot
    castle_boot();
#ifdef WJ_PREMIUM_PRIVATE_SHOP
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_INIT;
    db_clientdesc->DBPacket(HEADER_GD_PRIVATE_SHOP, 0, &bSubHeader, sizeof(bSubHeader));
#endif
}

EVENTINFO(quest_login_event_info)
{
    DWORD dwPID;

    quest_login_event_info()
    : dwPID( 0 )
    {
    }
};

EVENTFUNC(quest_login_event)
{
    quest_login_event_info* info = dynamic_cast<quest_login_event_info*>( event->info );

    if ( info == NULL )
    {
        sys_err( "quest_login_event> <Factor> Null pointer" );
        return 0;
    }

    DWORD dwPID = info->dwPID;

    LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);

    if (!ch)
        return 0;

    LPDESC d = ch->GetDesc();

    if (!d)
        return 0;

    if (d->IsPhase(PHASE_HANDSHAKE) ||
        d->IsPhase(PHASE_LOGIN) ||
        d->IsPhase(PHASE_SELECT) ||
        d->IsPhase(PHASE_DEAD) ||
        d->IsPhase(PHASE_LOADING))
    {
        return PASSES_PER_SEC(1);
    }
    else if (d->IsPhase(PHASE_CLOSE))
    {
        return 0;
    }
    else if (d->IsPhase(PHASE_GAME))
    {
        sys_log(0, "QUEST_LOAD: Login pc %d by event", ch->GetPlayerID());
        quest::CQuestManager::instance().Login(ch->GetPlayerID());
        return 0;
    }
    else
    {
        sys_err(0, "input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
        return 0;
    }
}

void CInputDB::QuestLoad(LPDESC d, const char * c_pData)
{
    if (NULL == d)
        return;

    LPCHARACTER ch = d->GetCharacter();

    if (NULL == ch)
        return;

    const DWORD dwCount = decode_4bytes(c_pData);

    const TQuestTable* pQuestTable = reinterpret_cast<const TQuestTable*>(c_pData+4);

    if (NULL != pQuestTable)
    {
        if (dwCount != 0)
        {
            if (ch->GetPlayerID() != pQuestTable[0].dwPID)
            {
                sys_err("PID differs %u %u", ch->GetPlayerID(), pQuestTable[0].dwPID);
                return;
            }
        }

        sys_log(0, "QUEST_LOAD: count %d", dwCount);

        quest::PC * pkPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());

        if (!pkPC)
        {
            sys_err("null quest::PC with id %u", pQuestTable[0].dwPID);
            return;
        }

        if (pkPC->IsLoaded())
            return;

        for (unsigned int i = 0; i < dwCount; ++i)
        {
            std::string st(pQuestTable[i].szName);

            st += ".";
            st += pQuestTable[i].szState;

            sys_log(0,  "            %s %d", st.c_str(), pQuestTable[i].lValue);
            pkPC->SetFlag(st.c_str(), pQuestTable[i].lValue, false);
        }

        pkPC->SetLoaded();
        pkPC->Build();

        if (ch->GetDesc()->IsPhase(PHASE_GAME))
        {
            sys_log(0, "QUEST_LOAD: Login pc %d", pQuestTable[0].dwPID);
            quest::CQuestManager::instance().Login(pQuestTable[0].dwPID);
        }
        else
        {
            quest_login_event_info* info = AllocEventInfo<quest_login_event_info>();
            info->dwPID = ch->GetPlayerID();

            event_create(quest_login_event, info, PASSES_PER_SEC(1));
        }
    }   
}

void CInputDB::SafeboxLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    TSafeboxTable * p = (TSafeboxTable *) c_pData;

    if (d->GetAccountTable().id != p->dwID)
    {
        sys_err("SafeboxLoad: safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
        return;
    }

    if (!d->GetCharacter())
        return;

    BYTE bSize = 1;

    LPCHARACTER ch = d->GetCharacter();

    //PREVENT_TRADE_WINDOW
    if (ch->GetShopOwner() || ch->GetExchange() || ch->GetMyShop() || ch->IsCubeOpen() )
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른거래창이 열린상태에서는 창고를 열수가 없습니다." ) );
        d->GetCharacter()->CancelSafeboxLoad();
        return;
    }
    //END_PREVENT_TRADE_WINDOW

    // ADD_PREMIUM
    if (d->GetCharacter()->GetPremiumRemainSeconds(PREMIUM_SAFEBOX) > 0 ||
            d->GetCharacter()->IsEquipUniqueGroup(UNIQUE_GROUP_LARGE_SAFEBOX))
        bSize = 3;
    // END_OF_ADD_PREMIUM

    //if (d->GetCharacter()->IsEquipUniqueItem(UNIQUE_ITEM_SAFEBOX_EXPAND))
    //bSize = 3; // 창고확장권

    //d->GetCharacter()->LoadSafebox(p->bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
    d->GetCharacter()->LoadSafebox(bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
}

void CInputDB::SafeboxChangeSize(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    BYTE bSize = *(BYTE *) c_pData;

    if (!d->GetCharacter())
        return;

    d->GetCharacter()->ChangeSafeboxSize(bSize);
}

//
// @version    05/06/20 Bang2ni - ReqSafeboxLoad 의 취소
//
void CInputDB::SafeboxWrongPassword(LPDESC d)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    TPacketCGSafeboxWrongPassword p;
    p.bHeader = HEADER_GC_SAFEBOX_WRONG_PASSWORD;
    d->Packet(&p, sizeof(p));

    d->GetCharacter()->CancelSafeboxLoad();
}

void CInputDB::SafeboxChangePasswordAnswer(LPDESC d, const char* c_pData)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    TSafeboxChangePasswordPacketAnswer* p = (TSafeboxChangePasswordPacketAnswer*) c_pData;
    if (p->flag)
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 창고 비밀번호가 변경되었습니다."));
    }
    else
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 기존 비밀번호가 틀렸습니다."));
    }
}

void CInputDB::MallLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    TSafeboxTable * p = (TSafeboxTable *) c_pData;

    if (d->GetAccountTable().id != p->dwID)
    {
        sys_err("safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
        return;
    }

    if (!d->GetCharacter())
        return;

    d->GetCharacter()->LoadMall(p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
}

void CInputDB::LoginAlready(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    // INTERNATIONAL_VERSION 이미 접속중이면 접속 끊음
    {
        TPacketDGLoginAlready * p = (TPacketDGLoginAlready *) c_pData;

        LPDESC d2 = DESC_MANAGER::instance().FindByLoginName(p->szLogin);

        if (d2)
            d2->DisconnectOfSameLogin();
        else
        {
            TPacketGGDisconnect pgg;

            pgg.bHeader = HEADER_GG_DISCONNECT;
            strlcpy(pgg.szLogin, p->szLogin, sizeof(pgg.szLogin));

            P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGDisconnect));
        }
    }
    // END_OF_INTERNATIONAL_VERSION

    LoginFailure(d, "ALREADY");
}

void CInputDB::EmpireSelect(LPDESC d, const char * c_pData)
{
    sys_log(0, "EmpireSelect %p", get_pointer(d));

    if (!d)
        return;

    TAccountTable & rTable = d->GetAccountTable();
    rTable.bEmpire = *(BYTE *) c_pData;

    TPacketGCEmpire pe;
    pe.bHeader = HEADER_GC_EMPIRE;
    pe.bEmpire = rTable.bEmpire;
    d->Packet(&pe, sizeof(pe));

    for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
        if (rTable.players[i].dwID)
        {
            rTable.players[i].x = EMPIRE_START_X(rTable.bEmpire);
            rTable.players[i].y = EMPIRE_START_Y(rTable.bEmpire);
        }

    GetServerLocation(d->GetAccountTable(), rTable.bEmpire);

    d->SendLoginSuccessPacket();
}

void CInputDB::MapLocations(const char * c_pData)
{
    BYTE bCount = *(BYTE *) (c_pData++);

    sys_log(0, "InputDB::MapLocations %d", bCount);

    TMapLocation * pLoc = (TMapLocation *) c_pData;

    while (bCount--)
    {
        for (int i = 0; i < 32; ++i)
        {
            if (0 == pLoc->alMaps[i])
                break;

            CMapLocation::instance().Insert(pLoc->alMaps[i], pLoc->szHost, pLoc->wPort);
        }

        pLoc++;
    }
}

void CInputDB::P2P(const char * c_pData)
{
    extern LPFDWATCH main_fdw;

    TPacketDGP2P * p = (TPacketDGP2P *) c_pData;

    P2P_MANAGER& mgr = P2P_MANAGER::instance();

    if (false == DESC_MANAGER::instance().IsP2PDescExist(p->szHost, p->wPort))
    {
        LPCLIENT_DESC pkDesc = NULL;
        sys_log(0, "InputDB:P2P %s:%u", p->szHost, p->wPort);
        pkDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, p->szHost, p->wPort, PHASE_P2P, false);
        mgr.RegisterConnector(pkDesc);
        pkDesc->SetP2P(p->szHost, p->wPort, p->bChannel);
    }
}

void CInputDB::GuildLoad(const char * c_pData)
{
    CGuildManager::instance().LoadGuild(*(DWORD *) c_pData);
}

void CInputDB::GuildSkillUpdate(const char* c_pData)
{
    TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;

    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
    {
        g->UpdateSkill(p->skill_point, p->skill_levels);
        g->GuildPointChange(POINT_SP, p->amount, p->save?true:false);
    }
}

void CInputDB::GuildWar(const char* c_pData)
{
    TPacketGuildWar * p = (TPacketGuildWar*) c_pData;

    sys_log(0, "InputDB::GuildWar %u %u state %d", p->dwGuildFrom, p->dwGuildTo, p->bWar);

    switch (p->bWar)
    {
        case GUILD_WAR_SEND_DECLARE:
        case GUILD_WAR_RECV_DECLARE:
            CGuildManager::instance().DeclareWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        case GUILD_WAR_REFUSE:
            CGuildManager::instance().RefuseWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_WAIT_START:
            CGuildManager::instance().WaitStartWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_CANCEL:
            CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_ON_WAR:
            CGuildManager::instance().StartWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_END:
            CGuildManager::instance().EndWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_OVER:
            CGuildManager::instance().WarOver(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        case GUILD_WAR_RESERVE:
            CGuildManager::instance().ReserveWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        default:
            sys_err("Unknown guild war state");
            break;
    }
}

void CInputDB::GuildWarScore(const char* c_pData)
{
    TPacketGuildWarScore* p = (TPacketGuildWarScore*) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuildGainPoint);
    g->SetWarScoreAgainstTo(p->dwGuildOpponent, p->lScore);
}

void CInputDB::GuildSkillRecharge()
{
    CGuildManager::instance().SkillRecharge();
}

void CInputDB::GuildExpUpdate(const char* c_pData)
{
    TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;
    sys_log(1, "GuildExpUpdate %d", p->amount);

    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
        g->GuildPointChange(POINT_EXP, p->amount);
}

void CInputDB::GuildAddMember(const char* c_pData)
{
    TPacketDGGuildMember * p = (TPacketDGGuildMember *) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->AddMember(p);
}

void CInputDB::GuildRemoveMember(const char* c_pData)
{
    TPacketGuild* p=(TPacketGuild*)c_pData;
    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->RemoveMember(p->dwInfo);
}

void CInputDB::GuildChangeGrade(const char* c_pData)
{
    TPacketGuild* p=(TPacketGuild*)c_pData;
    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->P2PChangeGrade((BYTE)p->dwInfo);
}

void CInputDB::GuildChangeMemberData(const char* c_pData)
{
    sys_log(0, "Recv GuildChangeMemberData");
    TPacketGuildChangeMemberData * p = (TPacketGuildChangeMemberData *) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
        g->ChangeMemberData(p->pid, p->offer, p->level, p->grade);
}

void CInputDB::GuildDisband(const char* c_pData)
{
    TPacketGuild * p = (TPacketGuild*) c_pData;
    CGuildManager::instance().DisbandGuild(p->dwGuild);
}

void CInputDB::GuildLadder(const char* c_pData)
{
    TPacketGuildLadder* p = (TPacketGuildLadder*) c_pData;
    sys_log(0, "Recv GuildLadder %u %d / w %d d %d l %d", p->dwGuild, p->lLadderPoint, p->lWin, p->lDraw, p->lLoss);
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);

    g->SetLadderPoint(p->lLadderPoint);
    g->SetWarData(p->lWin, p->lDraw, p->lLoss);
}

void CInputDB::ItemLoad(LPDESC d, const char * c_pData)
{
    LPCHARACTER ch;

    if (!d || !(ch = d->GetCharacter()))
        return;

    if (ch->IsItemLoaded())
        return;

    DWORD dwCount = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    sys_log(0, "ITEM_LOAD: COUNT %s %u", ch->GetName(), dwCount);

    std::vector<LPITEM> v;

    TPlayerItem * p = (TPlayerItem *) c_pData;

    for (DWORD i = 0; i < dwCount; ++i, ++p)
    {
        LPITEM item = ITEM_MANAGER::instance().CreateItem(p->vnum, p->count, p->id);

        if (!item)
        {
            sys_err("cannot create item by vnum %u (name %s id %u)", p->vnum, ch->GetName(), p->id);
            continue;
        }

        item->SetSkipSave(true);
        item->SetSockets(p->alSockets);
        item->SetAttributes(p->aAttr);

        if ((p->window == INVENTORY && ch->GetInventoryItem(p->pos)) ||
                (p->window == EQUIPMENT && ch->GetWear(p->pos)))
        {
            sys_log(0, "ITEM_RESTORE: %s %s", ch->GetName(), item->GetName());
            v.push_back(item);
        }
        else
        {
            switch (p->window)
            {
                case INVENTORY:
                case DRAGON_SOUL_INVENTORY:
                #ifdef ENABLE_SPLIT_INVENTORY_SYSTEM
                case SKILL_BOOK_INVENTORY:
                case UPGRADE_ITEMS_INVENTORY:
                case STONE_INVENTORY:
                case BOX_INVENTORY:
                case EFSUN_INVENTORY:
                case CICEK_INVENTORY:
                #endif
                    item->AddToCharacter(ch, TItemPos(p->window, p->pos));
                    break;

                case EQUIPMENT:
                    if (item->CheckItemUseLevel(ch->GetLevel()) == true )
                    {
                        if (item->EquipTo(ch, p->pos) == false )
                        {
                            v.push_back(item);
                        }
                    }
                    else
                    {
                        v.push_back(item);
                    }
                    break;
            }
        }

        if (false == item->OnAfterCreatedItem())
            sys_err("Failed to call ITEM::OnAfterCreatedItem (vnum: %d, id: %d)", item->GetVnum(), item->GetID());

        item->SetSkipSave(false);
    }

    itertype(v) it = v.begin();

    while (it != v.end())
    {
        LPITEM item = *(it++);

        int pos = ch->GetEmptyInventory(item->GetSize());

        if (pos < 0)
        {
            PIXEL_POSITION coord;
            coord.x = ch->GetX();
            coord.y = ch->GetY();

            item->AddToGround(ch->GetMapIndex(), coord);
            item->SetOwnership(ch, 180);
            item->StartDestroyEvent();
        }
        else
            item->AddToCharacter(ch, TItemPos(INVENTORY, pos));
    }

    ch->CheckMaximumPoints();
    ch->PointsPacket();

    ch->SetItemLoaded();
}

void CInputDB::AffectLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    LPCHARACTER ch = d->GetCharacter();

    DWORD dwPID = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    DWORD dwCount = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    if (ch->GetPlayerID() != dwPID)
        return;

    ch->LoadAffect(dwCount, (TPacketAffectElement *) c_pData);
    
}
    


void CInputDB::PartyCreate(const char* c_pData)
{
    TPacketPartyCreate* p = (TPacketPartyCreate*) c_pData;
    CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);
}

void CInputDB::PartyDelete(const char* c_pData)
{
    TPacketPartyDelete* p = (TPacketPartyDelete*) c_pData;
    CPartyManager::instance().P2PDeleteParty(p->dwLeaderPID);
}

void CInputDB::PartyAdd(const char* c_pData)
{
    TPacketPartyAdd* p = (TPacketPartyAdd*) c_pData;
    CPartyManager::instance().P2PJoinParty(p->dwLeaderPID, p->dwPID, p->bState);
}

void CInputDB::PartyRemove(const char* c_pData)
{
    TPacketPartyRemove* p = (TPacketPartyRemove*) c_pData;
    CPartyManager::instance().P2PQuitParty(p->dwPID);
}

void CInputDB::PartyStateChange(const char* c_pData)
{
    TPacketPartyStateChange * p = (TPacketPartyStateChange *) c_pData;
    LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);

    if (!pParty)
        return;

    pParty->SetRole(p->dwPID, p->bRole, p->bFlag);
}

void CInputDB::PartySetMemberLevel(const char* c_pData)
{
    TPacketPartySetMemberLevel* p = (TPacketPartySetMemberLevel*) c_pData;
    LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);

    if (!pParty)
        return;

    pParty->P2PSetMemberLevel(p->dwPID, p->bLevel);
}

void CInputDB::Time(const char * c_pData)
{
    set_global_time(*(time_t *) c_pData);
}

void CInputDB::ReloadProto(const char * c_pData)
{
    WORD wSize;

    /*
     * Skill
     */
    wSize = decode_2bytes(c_pData);
    c_pData += sizeof(WORD);
    if (wSize) CSkillManager::instance().Initialize((TSkillTable *) c_pData, wSize);
    c_pData += sizeof(TSkillTable) * wSize;

    /*
     * Banwords
     */

    wSize = decode_2bytes(c_pData);
    c_pData += sizeof(WORD);
    CBanwordManager::instance().Initialize((TBanwordTable *) c_pData, wSize);
    c_pData += sizeof(TBanwordTable) * wSize;

    /*
     * ITEM
     */
    wSize = decode_2bytes(c_pData);
    c_pData += 2;
    sys_log(0, "RELOAD: ITEM: %d", wSize);

    if (wSize)
    {
        ITEM_MANAGER::instance().Initialize((TItemTable *) c_pData, wSize);
        c_pData += wSize * sizeof(TItemTable);
    }

    /*
     * MONSTER
     */
    wSize = decode_2bytes(c_pData);
    c_pData += 2;
    sys_log(0, "RELOAD: MOB: %d", wSize);

    if (wSize)
    {
        CMobManager::instance().Initialize((TMobTable *) c_pData, wSize);
        c_pData += wSize * sizeof(TMobTable);
    }

    CMotionManager::instance().Build();

    CHARACTER_MANAGER::instance().for_each_pc(std::mem_fun(&CHARACTER::ComputePoints));
}

void CInputDB::GuildSkillUsableChange(const char* c_pData)
{
    TPacketGuildSkillUsableChange* p = (TPacketGuildSkillUsableChange*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    g->SkillUsableChange(p->dwSkillVnum, p->bUsable?true:false);
}

void CInputDB::AuthLogin(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    BYTE bResult = *(BYTE *) c_pData;

    TPacketGCAuthSuccess ptoc;

    ptoc.bHeader = HEADER_GC_AUTH_SUCCESS;

    if (bResult)
    {
        // Panama 암호화 팩에 필요한 키 보내기
        SendPanamaList(d);
        ptoc.dwLoginKey = d->GetLoginKey();

        //NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_-
        //Send Client Package CryptKey
        {
            DESC_MANAGER::instance().SendClientPackageCryptKey(d);
            DESC_MANAGER::instance().SendClientPackageSDBToLoadMap(d, MAPNAME_DEFAULT);
        }
    }
    else
    {
        ptoc.dwLoginKey = 0;
    }

    ptoc.bResult = bResult;

    d->Packet(&ptoc, sizeof(TPacketGCAuthSuccess));
    sys_log(0, "AuthLogin result %u key %u", bResult, d->GetLoginKey());
}


void CInputDB::ChangeEmpirePriv(const char* c_pData)
{
    TPacketDGChangeEmpirePriv* p = (TPacketDGChangeEmpirePriv*) c_pData;

    // ADD_EMPIRE_PRIV_TIME
    CPrivManager::instance().GiveEmpirePriv(p->empire, p->type, p->value, p->bLog, p->end_time_sec);
    // END_OF_ADD_EMPIRE_PRIV_TIME
}

/**
 * @version 05/06/08    Bang2ni - 지속시간 추가
 */
void CInputDB::ChangeGuildPriv(const char* c_pData)
{
    TPacketDGChangeGuildPriv* p = (TPacketDGChangeGuildPriv*) c_pData;

    // ADD_GUILD_PRIV_TIME
    CPrivManager::instance().GiveGuildPriv(p->guild_id, p->type, p->value, p->bLog, p->end_time_sec);
    // END_OF_ADD_GUILD_PRIV_TIME
}

void CInputDB::ChangeCharacterPriv(const char* c_pData)
{
    TPacketDGChangeCharacterPriv* p = (TPacketDGChangeCharacterPriv*) c_pData;
    CPrivManager::instance().GiveCharacterPriv(p->pid, p->type, p->value, p->bLog);
}

void CInputDB::MoneyLog(const char* c_pData)
{
    TPacketMoneyLog * p = (TPacketMoneyLog *) c_pData;

    if (p->type == 4) // QUEST_MONEY_LOG_SKIP
        return;

    if (g_bAuthServer ==true )
        return;

    LogManager::instance().MoneyLog(p->type, p->vnum, p->gold);
}

void CInputDB::GuildMoneyChange(const char* c_pData)
{
    TPacketDGGuildMoneyChange* p = (TPacketDGGuildMoneyChange*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
    if (g)
    {
        g->RecvMoneyChange(p->iTotalGold);
    }
}

void CInputDB::GuildWithdrawMoney(const char* c_pData)
{
    TPacketDGGuildMoneyWithdraw* p = (TPacketDGGuildMoneyWithdraw*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
    if (g)
    {
        g->RecvWithdrawMoneyGive(p->iChangeGold);
    }
}

void CInputDB::SetEventFlag(const char* c_pData)
{
    TPacketSetEventFlag* p = (TPacketSetEventFlag*) c_pData;
    quest::CQuestManager::instance().SetEventFlag(p->szFlagName, p->lValue);
}

void CInputDB::CreateObject(const char * c_pData)
{
    using namespace building;
    CManager::instance().LoadObject((TObject *) c_pData);
}

void CInputDB::DeleteObject(const char * c_pData)
{
    using namespace building;
    CManager::instance().DeleteObject(*(DWORD *) c_pData);
}

void CInputDB::UpdateLand(const char * c_pData)
{
    using namespace building;
    CManager::instance().UpdateLand((TLand *) c_pData);
}

void CInputDB::Notice(const char * c_pData)
{
    extern void SendNotice(const char * c_pszBuf);

    char szBuf[256+1];
    strlcpy(szBuf, c_pData, sizeof(szBuf));

    sys_log(0, "InputDB:: Notice: %s", szBuf);

    //SendNotice(LC_TEXT(szBuf));
    SendNotice(szBuf);
}

void CInputDB::GuildWarReserveAdd(TGuildWarReserve * p)
{
    CGuildManager::instance().ReserveWarAdd(p);
}

void CInputDB::GuildWarReserveDelete(DWORD dwID)
{
    CGuildManager::instance().ReserveWarDelete(dwID);
}

void CInputDB::GuildWarBet(TPacketGDGuildWarBet * p)
{
    CGuildManager::instance().ReserveWarBet(p);
}

void CInputDB::MarriageAdd(TPacketMarriageAdd * p)
{
    sys_log(0, "MarriageAdd %u %u %u %s %s", p->dwPID1, p->dwPID2, (DWORD)p->tMarryTime, p->szName1, p->szName2);
    marriage::CManager::instance().Add(p->dwPID1, p->dwPID2, p->tMarryTime, p->szName1, p->szName2);
}

void CInputDB::MarriageUpdate(TPacketMarriageUpdate * p)
{
    sys_log(0, "MarriageUpdate %u %u %d %d", p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
    marriage::CManager::instance().Update(p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
}

void CInputDB::MarriageRemove(TPacketMarriageRemove * p)
{
    sys_log(0, "MarriageRemove %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().Remove(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingRequest(TPacketWeddingRequest* p)
{
    marriage::WeddingManager::instance().Request(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingReady(TPacketWeddingReady* p)
{
    sys_log(0, "WeddingReady %u %u %u", p->dwPID1, p->dwPID2, p->dwMapIndex);
    marriage::CManager::instance().WeddingReady(p->dwPID1, p->dwPID2, p->dwMapIndex);
}

void CInputDB::WeddingStart(TPacketWeddingStart* p)
{
    sys_log(0, "WeddingStart %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().WeddingStart(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingEnd(TPacketWeddingEnd* p)
{
    sys_log(0, "WeddingEnd %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().WeddingEnd(p->dwPID1, p->dwPID2);
}

// MYSHOP_PRICE_LIST
void CInputDB::MyshopPricelistRes(LPDESC d, const TPacketMyshopPricelistHeader* p )
{
    LPCHARACTER ch;

    if (!d || !(ch = d->GetCharacter()) )
        return;

    sys_log(0, "RecvMyshopPricelistRes name[%s]", ch->GetName());
    ch->UseSilkBotaryReal(p );

}
// END_OF_MYSHOP_PRICE_LIST


//RELOAD_ADMIN
void CInputDB::ReloadAdmin(const char * c_pData )
{
    gm_new_clear();
    int ChunkSize = decode_2bytes(c_pData );
    c_pData += 2;
    int HostSize = decode_2bytes(c_pData );
    c_pData += 2;
    
    for (int n = 0; n < HostSize; ++n )
    {
        gm_new_host_inert(c_pData );
        c_pData += ChunkSize;
    }
    
    
    c_pData += 2;
    int size =     decode_2bytes(c_pData );
    c_pData += 2;
    
    for (int n = 0; n < size; ++n )
    {
        tAdminInfo& rAdminInfo = *(tAdminInfo*)c_pData;

        gm_new_insert(rAdminInfo );

        c_pData += sizeof (tAdminInfo );
    
        LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindPC(rAdminInfo.m_szName );
        if (pChar )
        {
            pChar->SetGMLevel();
        }
    }
    
}
//END_RELOAD_ADMIN

////////////////////////////////////////////////////////////////////
// Analyze
// @version    05/06/10 Bang2ni - 아이템 가격정보 리스트 패킷(HEADER_DG_MYSHOP_PRICELIST_RES) 처리루틴 추가.
////////////////////////////////////////////////////////////////////
int CInputDB::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
{
    switch (bHeader)
    {
    case HEADER_DG_BOOT:
        Boot(c_pData);
        break;

    case HEADER_DG_LOGIN_SUCCESS:
        LoginSuccess(m_dwHandle, c_pData);
        break;

    case HEADER_DG_LOGIN_NOT_EXIST:
        LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "NOID");
        break;

    case HEADER_DG_LOGIN_WRONG_PASSWD:
        LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "WRONGPWD");
        break;

    case HEADER_DG_LOGIN_ALREADY:
        LoginAlready(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_LOAD_SUCCESS:
        PlayerLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_CREATE_SUCCESS:
        PlayerCreateSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_CREATE_FAILED:
        PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 0);
        break;

    case HEADER_DG_PLAYER_CREATE_ALREADY:
        PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 1);
        break;

    case HEADER_DG_PLAYER_DELETE_SUCCESS:
        PlayerDeleteSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_LOAD_FAILED:
        //sys_log(0, "PLAYER_LOAD_FAILED");
        break;

    case HEADER_DG_PLAYER_DELETE_FAILED:
        //sys_log(0, "PLAYER_DELETE_FAILED");
        PlayerDeleteFail(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
        break;

    case HEADER_DG_ITEM_LOAD:
        ItemLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_QUEST_LOAD:
        QuestLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_AFFECT_LOAD:
        AffectLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_LOAD:
        SafeboxLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_CHANGE_SIZE:
        SafeboxChangeSize(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_WRONG_PASSWORD:
        SafeboxWrongPassword(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
        break;

    case HEADER_DG_SAFEBOX_CHANGE_PASSWORD_ANSWER:
        SafeboxChangePasswordAnswer(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_MALL_LOAD:
        MallLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_EMPIRE_SELECT:
        EmpireSelect(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_MAP_LOCATIONS:
        MapLocations(c_pData);
        break;

    case HEADER_DG_P2P:
        P2P(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_UPDATE:
        GuildSkillUpdate(c_pData);
        break;

    case HEADER_DG_GUILD_LOAD:
        GuildLoad(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_RECHARGE:
        GuildSkillRecharge();
        break;

    case HEADER_DG_GUILD_EXP_UPDATE:
        GuildExpUpdate(c_pData);
        break;

    case HEADER_DG_PARTY_CREATE:
        PartyCreate(c_pData);
        break;

    case HEADER_DG_PARTY_DELETE:
        PartyDelete(c_pData);
        break;

    case HEADER_DG_PARTY_ADD:
        PartyAdd(c_pData);
        break;

    case HEADER_DG_PARTY_REMOVE:
        PartyRemove(c_pData);
        break;

    case HEADER_DG_PARTY_STATE_CHANGE:
        PartyStateChange(c_pData);
        break;

    case HEADER_DG_PARTY_SET_MEMBER_LEVEL:
        PartySetMemberLevel(c_pData);   
        break;

    case HEADER_DG_TIME:
        Time(c_pData);
        break;

    case HEADER_DG_GUILD_ADD_MEMBER:
        GuildAddMember(c_pData);
        break;

    case HEADER_DG_GUILD_REMOVE_MEMBER:
        GuildRemoveMember(c_pData);
        break;

    case HEADER_DG_GUILD_CHANGE_GRADE:
        GuildChangeGrade(c_pData);
        break;

    case HEADER_DG_GUILD_CHANGE_MEMBER_DATA:
        GuildChangeMemberData(c_pData);
        break;

    case HEADER_DG_GUILD_DISBAND:
        GuildDisband(c_pData);
        break;

    case HEADER_DG_RELOAD_PROTO:
        ReloadProto(c_pData);
        break;

    case HEADER_DG_GUILD_WAR:
        GuildWar(c_pData);
        break;

    case HEADER_DG_GUILD_WAR_SCORE:
        GuildWarScore(c_pData);
        break;

    case HEADER_DG_GUILD_LADDER:
        GuildLadder(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_USABLE_CHANGE:
        GuildSkillUsableChange(c_pData);
        break;

    case HEADER_DG_CHANGE_NAME:
        ChangeName(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_AUTH_LOGIN:
        AuthLogin(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_CHANGE_EMPIRE_PRIV:
        ChangeEmpirePriv(c_pData);
        break;

    case HEADER_DG_CHANGE_GUILD_PRIV:
        ChangeGuildPriv(c_pData);
        break;

    case HEADER_DG_CHANGE_CHARACTER_PRIV:
        ChangeCharacterPriv(c_pData);
        break;

    case HEADER_DG_MONEY_LOG:
        MoneyLog(c_pData);
        break;

    case HEADER_DG_GUILD_WITHDRAW_MONEY_GIVE:
        GuildWithdrawMoney(c_pData);
        break;

    case HEADER_DG_GUILD_MONEY_CHANGE:
        GuildMoneyChange(c_pData);
        break;

    case HEADER_DG_SET_EVENT_FLAG:
        SetEventFlag(c_pData);
        break;

    case HEADER_DG_CREATE_OBJECT:
        CreateObject(c_pData);
        break;

    case HEADER_DG_DELETE_OBJECT:
        DeleteObject(c_pData);
        break;

    case HEADER_DG_UPDATE_LAND:
        UpdateLand(c_pData);
        break;

    case HEADER_DG_NOTICE:
        Notice(c_pData);
        break;

    case HEADER_DG_GUILD_WAR_RESERVE_ADD:
        GuildWarReserveAdd((TGuildWarReserve *) c_pData);
        break;

    case HEADER_DG_GUILD_WAR_RESERVE_DEL:
        GuildWarReserveDelete(*(DWORD *) c_pData);
        break;

    case HEADER_DG_GUILD_WAR_BET:
        GuildWarBet((TPacketGDGuildWarBet *) c_pData);
        break;

    case HEADER_DG_MARRIAGE_ADD:
        MarriageAdd((TPacketMarriageAdd*) c_pData);
        break;

    case HEADER_DG_MARRIAGE_UPDATE:
        MarriageUpdate((TPacketMarriageUpdate*) c_pData);
        break;

    case HEADER_DG_MARRIAGE_REMOVE:
        MarriageRemove((TPacketMarriageRemove*) c_pData);
        break;

    case HEADER_DG_WEDDING_REQUEST:
        WeddingRequest((TPacketWeddingRequest*) c_pData);
        break;

    case HEADER_DG_WEDDING_READY:
        WeddingReady((TPacketWeddingReady*) c_pData);
        break;

    case HEADER_DG_WEDDING_START:
        WeddingStart((TPacketWeddingStart*) c_pData);
        break;

    case HEADER_DG_WEDDING_END:
        WeddingEnd((TPacketWeddingEnd*) c_pData);
        break;

        // MYSHOP_PRICE_LIST
    case HEADER_DG_MYSHOP_PRICELIST_RES:
        MyshopPricelistRes(DESC_MANAGER::instance().FindByHandle(m_dwHandle), (TPacketMyshopPricelistHeader*) c_pData );
        break;
        // END_OF_MYSHOP_PRICE_LIST
        //
    // RELOAD_ADMIN
    case HEADER_DG_RELOAD_ADMIN:
        ReloadAdmin(c_pData );       
        break;
    //END_RELOAD_ADMIN


    case HEADER_DG_ACK_CHANGE_GUILD_MASTER :
        this->GuildChangeMaster((TPacketChangeGuildMaster*) c_pData);
        break;   
    case HEADER_DG_ACK_SPARE_ITEM_ID_RANGE :
        ITEM_MANAGER::instance().SetMaxSpareItemID(*((TItemIDRangeTable*)c_pData) );
        break;

    case HEADER_DG_UPDATE_HORSE_NAME :
    case HEADER_DG_ACK_HORSE_NAME :
        CHorseNameManager::instance().UpdateHorseName(
                ((TPacketUpdateHorseName*)c_pData)->dwPlayerID,
                ((TPacketUpdateHorseName*)c_pData)->szHorseName);
        break;

    case HEADER_DG_NEED_LOGIN_LOG:
        DetailLog( (TPacketNeedLoginLogInfo*) c_pData );
        break;
    // 독일 선물 기능 테스트
    case HEADER_DG_ITEMAWARD_INFORMER:
        ItemAwardInformer((TPacketItemAwardInfromer*) c_pData);
        break;
    case HEADER_DG_RESPOND_CHANNELSTATUS:
        RespondChannelStatus(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;
#ifdef WJ_PREMIUM_PRIVATE_SHOP
    case HEADER_DG_PRIVATE_SHOP:
        PrivateShop(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;
#endif
    default:
        return (-1);
    }

    return 0;
}

bool CInputDB::Process(LPDESC d, const void * orig, int bytes, int & r_iBytesProceed)
{
    const char *    c_pData = (const char *) orig;
    BYTE        bHeader, bLastHeader = 0;
    int            iSize;
    int            iLastPacketLen = 0;

    for (m_iBufferLeft = bytes; m_iBufferLeft > 0;)
    {
        if (m_iBufferLeft < 9)
            return true;

        bHeader        = *((BYTE *) (c_pData));    // 1
        m_dwHandle    = *((DWORD *) (c_pData + 1));    // 4
        iSize        = *((DWORD *) (c_pData + 5));    // 4

        sys_log(1, "DBCLIENT: header %d handle %d size %d bytes %d", bHeader, m_dwHandle, iSize, bytes);

        if (m_iBufferLeft - 9 < iSize)
            return true;

        const char * pRealData = (c_pData + 9);

        if (Analyze(d, bHeader, pRealData) < 0)
        {
            sys_err("in InputDB: UNKNOWN HEADER: %d, LAST HEADER: %d(%d), REMAIN BYTES: %d, DESC: %d",
                    bHeader, bLastHeader, iLastPacketLen, m_iBufferLeft, d->GetSocket());

            //printdata((BYTE*) orig, bytes);
            //d->SetPhase(PHASE_CLOSE);
        }

        c_pData        += 9 + iSize;
        m_iBufferLeft    -= 9 + iSize;
        r_iBytesProceed    += 9 + iSize;

        iLastPacketLen    = 9 + iSize;
        bLastHeader    = bHeader;
    }

    return true;
}

void CInputDB::GuildChangeMaster(TPacketChangeGuildMaster* p)
{
    CGuildManager::instance().ChangeMaster(p->dwGuildID);
}

void CInputDB::DetailLog(const TPacketNeedLoginLogInfo* info)
{
    if (true == LC_IsEurope() || true == LC_IsYMIR() || true == LC_IsKorea() )
    {
        LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID( info->dwPlayerID );

        if (NULL != pChar)
        {
            LogManager::instance().DetailLoginLog(true, pChar);
        }
    }
}

void CInputDB::ItemAwardInformer(TPacketItemAwardInfromer *data)
{   
    LPDESC d = DESC_MANAGER::instance().FindByLoginName(data->login);    //login정보
    
    if(d == NULL)
        return;
    else
    {
        if (d->GetCharacter())
        {
            LPCHARACTER ch = d->GetCharacter();   
            ch->SetItemAward_vnum(data->vnum);    // ch 에 임시 저장해놨다가 QuestLoad 함수에서 처리
            ch->SetItemAward_cmd(data->command);       

            if(d->IsPhase(PHASE_GAME))            //게임페이즈일때
            {
                quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum());    //questmanager 호출
            }
        }
    }
}

void CInputDB::RespondChannelStatus(LPDESC desc, const char* pcData)
{
    if (!desc) {
        return;
    }
    const int nSize = decode_4bytes(pcData);
    pcData += sizeof(nSize);

    BYTE bHeader = HEADER_GC_RESPOND_CHANNELSTATUS;
    desc->BufferedPacket(&bHeader, sizeof(BYTE));
    desc->BufferedPacket(&nSize, sizeof(nSize));
    if (0 < nSize) {
        desc->BufferedPacket(pcData, sizeof(TChannelStatus)*nSize);
    }
    BYTE bSuccess = 1;
    desc->Packet(&bSuccess, sizeof(bSuccess));
    desc->SetChannelStatusRequested(false);
}
#ifdef WJ_PREMIUM_PRIVATE_SHOP
void CInputDB::PrivateShop(LPDESC d, const char* c_pData)
{
    const BYTE bSubHeader = *reinterpret_cast<const BYTE*>(c_pData);
    c_pData += sizeof(BYTE);

    switch (bSubHeader)
    {
        case PRIVATE_SHOP_DG_SUBHEADER_CREATE_RESULT:
        {
            TPacketDGPrivateShopCreateResult* p = (TPacketDGPrivateShopCreateResult*)c_pData;

            CPrivateShopManager::Instance().BuildPrivateShopResult(p->privateShopTable.dwOwner, &p->privateShopTable, p->bSuccess);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NO_SHOP:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You do not have an open personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CLOSE_RESULT_BALANCE_AVAILABLE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You must withdraw your earnings before you can close your personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_DESTROY:
        {
            if (d && d->GetCharacter())
                CPrivateShopManager::Instance().ClosePrivateShop(d->GetCharacter());
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SPAWN:
        {
            TPrivateShop* pPrivateShopTable = (TPrivateShop*)c_pData;
            c_pData += sizeof(TPrivateShop);

            const WORD wCount = *reinterpret_cast<const WORD*>(c_pData);
            c_pData += sizeof(WORD);

            TPlayerPrivateShopItem* pShopItem = (TPlayerPrivateShopItem*)c_pData;

            std::vector<TPlayerPrivateShopItem> vec_shopItem;
            for (int i = 0; i < wCount; ++i, ++pShopItem)
                vec_shopItem.push_back(*pShopItem);

            CPrivateShopManager::Instance().SpawnPrivateShop(pPrivateShopTable, vec_shopItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_DESPAWN:
        {
            const DWORD dwPID = *reinterpret_cast<const DWORD*>(c_pData);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwPID);
            if (!pPrivateShop)
                return;

            LogManager::Instance().CharLog(dwPID, 0, 0, 0, "PRIVATE SHOP DESPAWN", "", "");
            CPrivateShopManager::Instance().DeletePrivateShop(dwPID);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_LOAD:
        {
            if (!d || !d->GetCharacter())
                return;

            TPrivateShop* pPrivateShopTable = (TPrivateShop*)c_pData;
            d->GetCharacter()->SetPrivateShopTable(*pPrivateShopTable);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_LOAD:
        {
            if (!d || !d->GetCharacter())
                return;

            const WORD wCount = *reinterpret_cast<const WORD*>(c_pData);
            c_pData += sizeof(WORD);

            TPlayerPrivateShopItem* pShopItem = (TPlayerPrivateShopItem*)c_pData;

            for (int i = 0; i < wCount; ++i, ++pShopItem)
            {
                d->GetCharacter()->SetPrivateShopItem(*pShopItem);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_FALSE_ITEM:
        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKIN_FALSE_ITEM:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("This item is currently unavailable."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_FALSE_PRICE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Refresh your search result to sync price of the item."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_MODIFY_STATE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot buy an item while a personal shop is in a modifying state."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_NO_GOLD:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Yang."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_NO_CHEQUE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Won."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_REQUEST:
        {
            TPacketDGPrivateShopBuyRequest* p = (TPacketDGPrivateShopBuyRequest*)c_pData;

            if (d && d->GetCharacter())
                CPrivateShopManager::Instance().ItemTransaction(d->GetCharacter(), &p->TRequestedItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_REMOVE_ITEM:
        {
            const DWORD dwShopID = *reinterpret_cast<const DWORD*>(c_pData);
            c_pData += sizeof(DWORD);

            const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwShopID);
            if (!pPrivateShop)
                return;

            pPrivateShop->RemoveItem(wPos);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ADD_ITEM:
        {
            const DWORD dwShopID = *reinterpret_cast<const DWORD*>(c_pData);
            c_pData += sizeof(DWORD);

            const TPlayerPrivateShopItem TPrivateShopItem = *(TPlayerPrivateShopItem*)c_pData;

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwShopID);
            if (!pPrivateShop)
                return;

            sys_err("Adding item to private shop!");
            pPrivateShop->ItemCheckin(TPrivateShopItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_WITHDRAW_RESULT_NO_BALANCE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("There is no money to collect."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NOT_MODIFY_STATE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot manage personal shop's content while it is not in a modifying state."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_WITHDRAW:
        {
            const TPacketDGPrivateShopWithdraw* p = (TPacketDGPrivateShopWithdraw*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->WithdrawPrivateShop(p->llGold, p->dwCheque);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_PRICE_CHANGE:
        {
            const TPacketPrivateShopItemPriceChange* p = (TPacketPrivateShopItemPriceChange*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopItemPrice(p->wPos, p->TPrice.llGold, p->TPrice.dwCheque);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwShopID);
            if (pPrivateShop)
                pPrivateShop->ChangeItemPrice(p->wPos, p->TPrice.llGold, p->TPrice.dwCheque);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_MOVE:
        {
            const TPacketPrivateShopItemMove* p = (TPacketPrivateShopItemMove*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopItemPos(p->wPos, p->wChangePos);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwShopID);
            if (pPrivateShop)
                pPrivateShop->MoveItem(p->wPos, p->wChangePos);
        };
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CANNOT_MOVE_ITEM:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot move the item to that position."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKIN_REQ:
        {
            const TPacketDGPrivateShopItemCheckin* p = (TPacketDGPrivateShopItemCheckin*)c_pData;

            if (d && d->GetCharacter())
            {
                CPrivateShopManager::Instance().ItemCheckin(d->GetCharacter(), &p->TItem);
            }

        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKOUT_REQ:
        {
            const TPacketDGPrivateShopItemCheckout* p = (TPacketDGPrivateShopItemCheckout*)c_pData;

            if (d && d->GetCharacter())
            {
                CPrivateShopManager::Instance().ItemCheckout(d->GetCharacter(), p->wSrcPos, p->TDstPos);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_EXPIRE:
        {
            const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);

            if (d && d->GetCharacter())
            {
                // Notify the player and remove the private shop item
                d->GetCharacter()->ItemExpireUpdate(wPos);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SHOP_NOT_AVAILABLE:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Your personal shop is currently unavailable."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_TITLE_CHANGE:
        {
            const TPacketPrivateShopTitleChange* p = (TPacketPrivateShopTitleChange*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopTitle(p->szTitle);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->ChangeTitle(p->szTitle);

        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CLOSE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ClosePrivateShop();
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NO_AVAILABLE_SPACE:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot place any more items in your personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SALE_UPDATE:
        {
            const TPacketDGPrivateShopSaleUpdate* p = (TPacketDGPrivateShopSaleUpdate*)c_pData;

            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->SaleUpdate(p->TItem, p->szCustomerName);
        }
        break;
    }
}
#endif
 
PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE geçtiği kısımlar:
input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

ClientManagerPrivateShop.cpp:
Genişlet Daralt Kopyala
void CClientManager::PrivateShopModifyRequest(CPeer* pPeer, DWORD dwHandle, const char* c_szData)
{
    const DWORD dwPID = *reinterpret_cast<const DWORD*>(c_szData);
    BYTE bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE;

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop || pPrivateShop->GetState() == STATE_CLOSED)
    {
        bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_NO_SHOP;
        pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE));
        pPeer->Encode(&bSubHeader, sizeof(BYTE));

        sys_err("Cannot find private shop %u", dwPID);
        return;
    }

    CPeer* pShopPeer = GetPeer(pPrivateShop->GetShopPeerHandle());
    if (!pShopPeer)
    {
        bSubHeader = PRIVATE_SHOP_DG_SUBHEADER_SHOP_NOT_AVAILABLE;
        pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE));
        pPeer->Encode(&bSubHeader, sizeof(BYTE));

        sys_err("Cannot find private shop peer for private shop %u", dwPID);
        return;
    }

    // Update state of the shop
    BYTE bState = pPrivateShop->GetState();
    if (bState == STATE_OPEN)
    {
        pPrivateShop->ChangeState(STATE_MODIFY);
        bState = STATE_MODIFY;

        sys_log(0, "PRIVATE_SHOP: State changed to modify for private shop %u", dwPID);
    }
    else if (bState == STATE_MODIFY)
    {
        pPrivateShop->ChangeState(STATE_OPEN);
        bState = STATE_OPEN;

        sys_log(0, "PRIVATE_SHOP: State changed to open for private shop %u", dwPID);
    }

    //Send the result back to owner (and shop if it is on the same peer)

    TPacketDGPrivateShopStateUpdate subPacket {};
    subPacket.dwPID = dwPID;
    subPacket.bState = bState;

    pPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, dwHandle, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
    pPeer->Encode(&bSubHeader, sizeof(BYTE));
    pPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));

    // Not needed to be sent twice if both player&shop are on the same peer
    if (pPeer != pShopPeer)
    {
        pShopPeer->EncodeHeader(HEADER_DG_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(TPacketDGPrivateShopStateUpdate));
        pShopPeer->Encode(&bSubHeader, sizeof(BYTE));
        pShopPeer->Encode(&subPacket, sizeof(TPacketDGPrivateShopStateUpdate));
    }
}



input_db.cpp full:
Genişlet Daralt Kopyala
#include "stdafx.h"
#include "constants.h"
#include "config.h"
#include "utils.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "item.h"
#include "item_manager.h"
#include "packet.h"
#include "protocol.h"
#include "mob_manager.h"
#include "shop_manager.h"
#include "sectree_manager.h"
#include "skill.h"
#include "questmanager.h"
#include "p2p.h"
#include "guild.h"
#include "guild_manager.h"
#include "start_position.h"
#include "party.h"
#include "refine.h"
#include "banword.h"
#include "priv_manager.h"
#include "db.h"
#include "building.h"
#include "login_sim.h"
#include "wedding.h"
#include "login_data.h"
#include "unique_item.h"
#include "affect.h"
#include "castle.h"
#ifdef WJ_PREMIUM_PRIVATE_SHOP
#include "private_shop_manager.h"
#include "private_shop.h"
#include "private_shop_util.h"
#endif
#include "motion.h"

#include "dev_log.h"

#include "log.h"

#include "horsename_manager.h"
#include "pcbang.h"
#include "gm.h"
#include "panama.h"
#include "map_location.h"

#include "XTrapManager.h"

#include "DragonSoul.h"

extern BYTE        g_bAuthServer;
extern void gm_insert(const char * name, BYTE level);
extern BYTE    gm_get_level(const char * name, const char * host, const char* account );
extern void gm_host_insert(const char * host);

#define MAPNAME_DEFAULT    "none"

bool GetServerLocation(TAccountTable & rTab, BYTE bEmpire)
{
    bool bFound = false;

    for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
    {
        if (0 == rTab.players[i].dwID)
            continue;

        bFound = true;
        long lIndex = 0;

        if (!CMapLocation::instance().Get(rTab.players[i].x,
                    rTab.players[i].y,
                    lIndex,
                    rTab.players[i].lAddr,
                    rTab.players[i].wPort))
        {
            sys_err("location error name %s mapindex %d %d x %d empire %d",
                    rTab.players[i].szName, lIndex, rTab.players[i].x, rTab.players[i].y, rTab.bEmpire);

            rTab.players[i].x = EMPIRE_START_X(rTab.bEmpire);
            rTab.players[i].y = EMPIRE_START_Y(rTab.bEmpire);

            lIndex = 0;

            if (!CMapLocation::instance().Get(rTab.players[i].x, rTab.players[i].y, lIndex, rTab.players[i].lAddr, rTab.players[i].wPort))
            {
                sys_err("cannot find server for mapindex %d %d x %d (name %s)",
                        lIndex,
                        rTab.players[i].x,
                        rTab.players[i].y,
                        rTab.players[i].szName);

                continue;
            }
        }

        struct in_addr in;
        in.s_addr = rTab.players[i].lAddr;
        sys_log(0, "success to %s:%d", inet_ntoa(in), rTab.players[i].wPort);
    }

    return bFound;
}

extern std::map<DWORD, CLoginSim *> g_sim;
extern std::map<DWORD, CLoginSim *> g_simByPID;

void CInputDB::LoginSuccess(DWORD dwHandle, const char *data)
{
    sys_log(0, "LoginSuccess");

    TAccountTable * pTab = (TAccountTable *) data;

    itertype(g_sim) it = g_sim.find(pTab->id);
    if (g_sim.end() != it)
    {
        sys_log(0, "CInputDB::LoginSuccess - already exist sim [%s]", pTab->login);
        it->second->SendLoad();
        return;
    }

    LPDESC d = DESC_MANAGER::instance().FindByHandle(dwHandle);

    if (!d)
    {
        sys_log(0, "CInputDB::LoginSuccess - cannot find handle [%s]", pTab->login);

        TLogoutPacket pack;

        strlcpy(pack.login, pTab->login, sizeof(pack.login));
        db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));
        return;
    }

    if (strcmp(pTab->status, "OK")) // OK가 아니면
    {
        sys_log(0, "CInputDB::LoginSuccess - status[%s] is not OK [%s]", pTab->status, pTab->login);

        TLogoutPacket pack;

        strlcpy(pack.login, pTab->login, sizeof(pack.login));
        db_clientdesc->DBPacket(HEADER_GD_LOGOUT, dwHandle, &pack, sizeof(pack));

        LoginFailure(d, pTab->status);
        return;
    }

    for (int i = 0; i != PLAYER_PER_ACCOUNT; ++i)
    {
        TSimplePlayer& player = pTab->players[i];
        sys_log(0, "\tplayer(%s).job(%d)", player.szName, player.byJob);
    }

    bool bFound = GetServerLocation(*pTab, pTab->bEmpire);

    d->BindAccountTable(pTab);

    if (!bFound) // 캐릭터가 없으면 랜덤한 제국으로 보낸다.. -_-
    {
        TPacketGCEmpire pe;
        pe.bHeader = HEADER_GC_EMPIRE;
        pe.bEmpire = number(1, 3);
        d->Packet(&pe, sizeof(pe));
    }
    else
    {
        TPacketGCEmpire pe;
        pe.bHeader = HEADER_GC_EMPIRE;
        pe.bEmpire = d->GetEmpire();
        d->Packet(&pe, sizeof(pe));
    }

    d->SetPhase(PHASE_SELECT);
    d->SendLoginSuccessPacket();

    sys_log(0, "InputDB::login_success: %s", pTab->login);
}

void CInputDB::PlayerCreateFailure(LPDESC d, BYTE bType)
{
    if (!d)
        return;

    TPacketGCCreateFailure pack;

    pack.header    = HEADER_GC_CHARACTER_CREATE_FAILURE;
    pack.bType    = bType;

    d->Packet(&pack, sizeof(pack));
}

void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data)
{
    if (!d)
        return;

    TPacketDGCreateSuccess * pPacketDB = (TPacketDGCreateSuccess *) data;

    if (pPacketDB->bAccountCharacterIndex >= PLAYER_PER_ACCOUNT)
    {
        d->Packet(encode_byte(HEADER_GC_CHARACTER_CREATE_FAILURE), 1);
        return;
    }

    long lIndex = 0;

    if (!CMapLocation::instance().Get(pPacketDB->player.x,
                pPacketDB->player.y,
                lIndex,
                pPacketDB->player.lAddr,
                pPacketDB->player.wPort))
    {
        sys_err("InputDB::PlayerCreateSuccess: cannot find server for mapindex %d %d x %d (name %s)",
                lIndex,
                pPacketDB->player.x,
                pPacketDB->player.y,
                pPacketDB->player.szName);
    }

    TAccountTable & r_Tab = d->GetAccountTable();
    r_Tab.players[pPacketDB->bAccountCharacterIndex] = pPacketDB->player;

    TPacketGCPlayerCreateSuccess pack;

    pack.header = HEADER_GC_CHARACTER_CREATE_SUCCESS;
    pack.bAccountCharacterIndex = pPacketDB->bAccountCharacterIndex;
    pack.player = pPacketDB->player;

    d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess));

    // 기본 무기와 귀환부를 지급
    TPlayerItem t;
    memset(&t, 0, sizeof(t));

    if (china_event_server)
    {
        t.window    = INVENTORY;
        t.count    = 1;
        t.owner    = r_Tab.players[pPacketDB->bAccountCharacterIndex].dwID;

        //무사: 자인갑+3,철편투구+3,금편신발+3,남만도+3,백금목걸이+3, 흑단귀걸이+3, 소산부+3, 오각패+3, 흑단팔찌+3
        //자객:영린+3,연환두건+3,금편신발+3,마안도+3,화안궁+3,옥목걸이+3, 옥귀걸이+3, 오각패+3, 흑단팔찌+3
        //수라:음양갑+3,애희투구+3,금편신발+3,남만도+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3
        //무당:서천의+3,태을모+3,금편신발+3,자린선+3,매화령+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3

        struct SInitialItem
        {
            DWORD dwVnum;
            BYTE pos;
        };

        const int MAX_INITIAL_ITEM = 9;

        static SInitialItem initialItems[JOB_MAX_NUM][MAX_INITIAL_ITEM] =
        {
            { {11243,    2}, {12223,    3}, {15103,    4}, {   93,    1}, {16143,    8}, {17103,    9}, { 3083,    0}, {13193,    11}, {14103, 12}, },
            { {11443,    0}, {12363,    3}, {15103,    4}, { 1053,    2}, { 2083,    1}, {16083,    7}, {17083,    8}, {13193,    9}, {14103,    10}, },
            { {11643,    0}, {12503,    2}, {15103,    3}, {   93,    1}, {16123,    4}, {17143,    7}, {13193,    8}, {14103,    9}, {    0,    0}, },
            { {11843,    0}, {12643,    1}, {15103,    2}, { 7083,    3}, { 5053,    4}, {16123,    6}, {17143,    7}, {13193,    8}, {14103,    9}, },
        };

        int job = pPacketDB->player.byJob;
        for (int i=0; i < MAX_INITIAL_ITEM; i++)
        {
            if (initialItems[job][i].dwVnum == 0)
                continue;

            t.id    = ITEM_MANAGER::instance().GetNewID();
            t.pos    = initialItems[job][i].pos;
            t.vnum    = initialItems[job][i].dwVnum;

            db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_SAVE, 0, sizeof(TPlayerItem));
            db_clientdesc->Packet(&t, sizeof(TPlayerItem));
        }
    }

    LogManager::instance().CharLog(pack.player.dwID, 0, 0, 0, "CREATE PLAYER", "", d->GetHostName());
}

void CInputDB::PlayerDeleteSuccess(LPDESC d, const char * data)
{
    if (!d)
        return;

    BYTE account_index;
    account_index = decode_byte(data);
    d->BufferedPacket(encode_byte(HEADER_GC_CHARACTER_DELETE_SUCCESS),    1);
    d->Packet(encode_byte(account_index),            1);

    d->GetAccountTable().players[account_index].dwID = 0;
}

void CInputDB::PlayerDeleteFail(LPDESC d)
{
    if (!d)
        return;

    d->Packet(encode_byte(HEADER_GC_CHARACTER_DELETE_WRONG_SOCIAL_ID),    1);
    //d->Packet(encode_byte(account_index),            1);

    //d->GetAccountTable().players[account_index].dwID = 0;
}

void CInputDB::ChangeName(LPDESC d, const char * data)
{
    if (!d)
        return;

    TPacketDGChangeName * p = (TPacketDGChangeName *) data;

    TAccountTable & r = d->GetAccountTable();

    if (!r.id)
        return;

    for (size_t i = 0; i < PLAYER_PER_ACCOUNT; ++i)
        if (r.players[i].dwID == p->pid)
        {
            strlcpy(r.players[i].szName, p->name, sizeof(r.players[i].szName));
            r.players[i].bChangeName = 0;

            TPacketGCChangeName pgc;

            pgc.header = HEADER_GC_CHANGE_NAME;
            pgc.pid = p->pid;
            strlcpy(pgc.name, p->name, sizeof(pgc.name));

            d->Packet(&pgc, sizeof(TPacketGCChangeName));
            break;
        }
}

void CInputDB::PlayerLoad(LPDESC d, const char * data)
{
    TPlayerTable * pTab = (TPlayerTable *) data;

    if (!d)
        return;

    long lMapIndex = pTab->lMapIndex;
    PIXEL_POSITION pos;

    if (lMapIndex == 0)
    {
        lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(pTab->x, pTab->y);

        if (lMapIndex == 0) // 좌표를 찾을 수 없다.
        {
            lMapIndex = EMPIRE_START_MAP(d->GetAccountTable().bEmpire);
            pos.x = EMPIRE_START_X(d->GetAccountTable().bEmpire);
            pos.y = EMPIRE_START_Y(d->GetAccountTable().bEmpire);
        }
        else
        {
            pos.x = pTab->x;
            pos.y = pTab->y;
        }
    }
    pTab->lMapIndex = lMapIndex;

    // Private 맵에 있었는데, Private 맵이 사라진 상태라면 출구로 돌아가야 한다.
    // ----
    // 근데 출구로 돌아가야 한다면서... 왜 출구가 아니라 private map 상에 대응되는 pulic map의 위치를 찾냐고...
    // 역사를 모르니... 또 하드코딩 한다.
    // 아귀동굴이면, 출구로...
    // by rtsummit
    if (!SECTREE_MANAGER::instance().GetValidLocation(pTab->lMapIndex, pTab->x, pTab->y, lMapIndex, pos, d->GetEmpire()))
    {
        sys_err("InputDB::PlayerLoad : cannot find valid location %d x %d (name: %s)", pTab->x, pTab->y, pTab->name);
        d->SetPhase(PHASE_CLOSE);
        return;
    }

    pTab->x = pos.x;
    pTab->y = pos.y;
    pTab->lMapIndex = lMapIndex;

    if (d->GetCharacter() || d->IsPhase(PHASE_GAME))
    {
        LPCHARACTER p = d->GetCharacter();
        sys_err("login state already has main state (character %s %p)", p->GetName(), get_pointer(p));
        return;
    }

    if (NULL != CHARACTER_MANAGER::Instance().FindPC(pTab->name))
    {
        sys_err("InputDB: PlayerLoad : %s already exist in game", pTab->name);
        return;
    }

    LPCHARACTER ch = CHARACTER_MANAGER::instance().CreateCharacter(pTab->name, pTab->id);

    ch->BindDesc(d);
    ch->SetPlayerProto(pTab);
    ch->SetEmpire(d->GetEmpire());

    d->BindCharacter(ch);
 
    {
        // P2P Login
        TPacketGGLogin p;

        p.bHeader = HEADER_GG_LOGIN;
        strlcpy(p.szName, ch->GetName(), sizeof(p.szName));
        p.dwPID = ch->GetPlayerID();
        p.bEmpire = ch->GetEmpire();
        p.lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(ch->GetX(), ch->GetY());
        p.bChannel = g_bChannel;

        P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogin));

        char buf[51];
        snprintf(buf, sizeof(buf), "%s %d %d %ld %d",
                inet_ntoa(ch->GetDesc()->GetAddr().sin_addr), ch->GetGold(), g_bChannel, ch->GetMapIndex(), ch->GetAlignment());
        LogManager::instance().CharLog(ch, 0, "LOGIN", buf);

        if (LC_IsYMIR() || LC_IsKorea() || LC_IsBrazil() || LC_IsJapan())
        {
            LogManager::instance().LoginLog(true,
                    ch->GetDesc()->GetAccountTable().id, ch->GetPlayerID(), ch->GetLevel(), ch->GetJob(), ch->GetRealPoint(POINT_PLAYTIME));

            if (LC_IsBrazil() != true )
            {
                ch->SetPCBang(CPCBangManager::instance().IsPCBangIP(ch->GetDesc()->GetHostName()));
            }
        }
    }

    d->SetPhase(PHASE_LOADING);
    ch->MainCharacterPacket();

    long lPublicMapIndex = lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex;

    //Send Supplementary Data Block if new map requires security packages in loading this map
    const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lPublicMapIndex);
    if( rMapRgn )
    {
        DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( d, rMapRgn->strMapName.c_str() );
    }
    //if (!map_allow_find(lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex) || !CheckEmpire(ch, lMapIndex))
    if (!map_allow_find(lPublicMapIndex))
    {
        sys_err("InputDB::PlayerLoad : entering %d map is not allowed here (name: %s, empire %u)",
                lMapIndex, pTab->name, d->GetEmpire());

        ch->SetWarpLocation(EMPIRE_START_MAP(d->GetEmpire()),
                EMPIRE_START_X(d->GetEmpire()) / 100,
                EMPIRE_START_Y(d->GetEmpire()) / 100);

        d->SetPhase(PHASE_CLOSE);
        return;
    }

    quest::CQuestManager::instance().BroadcastEventFlagOnLogin(ch);

    for (int i = 0; i < QUICKSLOT_MAX_NUM; ++i)
        ch->SetQuickslot(i, pTab->quickslot[i]);

    ch->PointsPacket();
    ch->SkillLevelPacket();

    sys_log(0, "InputDB: player_load %s %dx%dx%d LEVEL %d MOV_SPEED %d JOB %d ATG %d DFG %d GMLv %d",
            pTab->name,
            ch->GetX(), ch->GetY(), ch->GetZ(),
            ch->GetLevel(),
            ch->GetPoint(POINT_MOV_SPEED),
            ch->GetJob(),
            ch->GetPoint(POINT_ATT_GRADE),
            ch->GetPoint(POINT_DEF_GRADE),
            ch->GetGMLevel());

    ch->QuerySafeboxSize();

    CXTrapManager::instance().CreateClientSession( ch );
}

void CInputDB::Boot(const char* data)
{
    signal_timer_disable();

    // 패킷 사이즈 체크
    DWORD dwPacketSize = decode_4bytes(data);
    data += 4;

    // 패킷 버전 체크
    BYTE bVersion = decode_byte(data);
    data += 1;

    sys_log(0, "BOOT: PACKET: %d", dwPacketSize);
    sys_log(0, "BOOT: VERSION: %d", bVersion);
    if (bVersion != 6)
    {
        sys_err("boot version error");
        thecore_shutdown();
    }

    sys_log(0, "sizeof(TMobTable) = %d", sizeof(TMobTable));
    sys_log(0, "sizeof(TItemTable) = %d", sizeof(TItemTable));
    sys_log(0, "sizeof(TShopTable) = %d", sizeof(TShopTable));
    sys_log(0, "sizeof(TSkillTable) = %d", sizeof(TSkillTable));
    sys_log(0, "sizeof(TRefineTable) = %d", sizeof(TRefineTable));
    sys_log(0, "sizeof(TItemAttrTable) = %d", sizeof(TItemAttrTable));
    sys_log(0, "sizeof(TItemRareTable) = %d", sizeof(TItemAttrTable));
    sys_log(0, "sizeof(TBanwordTable) = %d", sizeof(TBanwordTable));
    sys_log(0, "sizeof(TLand) = %d", sizeof(building::TLand));
    sys_log(0, "sizeof(TObjectProto) = %d", sizeof(building::TObjectProto));
    sys_log(0, "sizeof(TObject) = %d", sizeof(building::TObject));
    //ADMIN_MANAGER
    sys_log(0, "sizeof(TAdminManager) = %d", sizeof (TAdminInfo) );
    //END_ADMIN_MANAGER

    WORD size;

    /*
     * MOB
     */

    if (decode_2bytes(data)!=sizeof(TMobTable))
    {
        sys_err("mob table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: MOB: %d", size);

    if (size)
    {
        CMobManager::instance().Initialize((TMobTable *) data, size);
        data += size * sizeof(TMobTable);
    }

    /*
     * ITEM
     */

    if (decode_2bytes(data) != sizeof(TItemTable))
    {
        sys_err("item table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM: %d", size);


    if (size)
    {
        ITEM_MANAGER::instance().Initialize((TItemTable *) data, size);
        data += size * sizeof(TItemTable);
    }

    /*
     * SHOP
     */

    if (decode_2bytes(data) != sizeof(TShopTable))
    {
        sys_err("shop table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: SHOP: %d", size);


    if (size)
    {
        if (!CShopManager::instance().Initialize((TShopTable *) data, size))
        {
            sys_err("shop table Initialize error");
            thecore_shutdown();
            return;
        }
        data += size * sizeof(TShopTable);
    }

    /*
     * SKILL
     */

    if (decode_2bytes(data) != sizeof(TSkillTable))
    {
        sys_err("skill table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: SKILL: %d", size);

    if (size)
    {
        if (!CSkillManager::instance().Initialize((TSkillTable *) data, size))
        {
            sys_err("cannot initialize skill table");
            thecore_shutdown();
            return;
        }

        data += size * sizeof(TSkillTable);
    }
    /*
     * REFINE RECIPE
     */
    if (decode_2bytes(data) != sizeof(TRefineTable))
    {
        sys_err("refine table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: REFINE: %d", size);

    if (size)
    {
        CRefineManager::instance().Initialize((TRefineTable*) data, size);
        data += size * sizeof(TRefineTable);
    }

    /*
     * ITEM ATTR
     */
    if (decode_2bytes(data) != sizeof(TItemAttrTable))
    {
        sys_err("item attr table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM_ATTR: %d", size);

    if (size)
    {
        TItemAttrTable * p = (TItemAttrTable *) data;

        for (int i = 0; i < size; ++i, ++p)
        {
            if (p->dwApplyIndex >= MAX_APPLY_NUM)
                continue;

            g_map_itemAttr[p->dwApplyIndex] = *p;
            sys_log(0, "ITEM_ATTR[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
        }
    }

    data += size * sizeof(TItemAttrTable);


    /*
     * ITEM RARE
     */
    if (decode_2bytes(data) != sizeof(TItemAttrTable))
    {
        sys_err("item rare table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;
    sys_log(0, "BOOT: ITEM_RARE: %d", size);

    if (size)
    {
        TItemAttrTable * p = (TItemAttrTable *) data;

        for (int i = 0; i < size; ++i, ++p)
        {
            if (p->dwApplyIndex >= MAX_APPLY_NUM)
                continue;

            g_map_itemRare[p->dwApplyIndex] = *p;
            sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb);
        }
    }

    data += size * sizeof(TItemAttrTable);


    /*
     * BANWORDS
     */

    if (decode_2bytes(data) != sizeof(TBanwordTable))
    {
        sys_err("ban word table size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;

    CBanwordManager::instance().Initialize((TBanwordTable *) data, size);
    data += size * sizeof(TBanwordTable);

    {
        using namespace building;

        /*
         * LANDS
         */

        if (decode_2bytes(data) != sizeof(TLand))
        {
            sys_err("land table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        TLand * kLand = (TLand *) data;
        data += size * sizeof(TLand);

        for (WORD i = 0; i < size; ++i, ++kLand)
            CManager::instance().LoadLand(kLand);

        /*
         * OBJECT PROTO
         */

        if (decode_2bytes(data) != sizeof(TObjectProto))
        {
            sys_err("object proto table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        CManager::instance().LoadObjectProto((TObjectProto *) data, size);
        data += size * sizeof(TObjectProto);

        /*
         * OBJECT
         */
        if (decode_2bytes(data) != sizeof(TObject))
        {
            sys_err("object table size error");
            thecore_shutdown();
            return;
        }
        data += 2;

        size = decode_2bytes(data);
        data += 2;

        TObject * kObj = (TObject *) data;
        data += size * sizeof(TObject);

        for (WORD i = 0; i < size; ++i, ++kObj)
            CManager::instance().LoadObject(kObj, true);
    }
    set_global_time(*(time_t *) data);
    data += sizeof(time_t);

    if (decode_2bytes(data) != sizeof(TItemIDRangeTable) )
    {
        sys_err("ITEM ID RANGE size error");
        thecore_shutdown();
        return;
    }
    data += 2;

    size = decode_2bytes(data);
    data += 2;

    TItemIDRangeTable* range = (TItemIDRangeTable*) data;
    data += size * sizeof(TItemIDRangeTable);

    TItemIDRangeTable* rangespare = (TItemIDRangeTable*) data;
    data += size * sizeof(TItemIDRangeTable);

    //ADMIN_MANAGER
    //관리자 등록
    int ChunkSize = decode_2bytes(data );
    data += 2;
    int HostSize = decode_2bytes(data );
    data += 2;
    sys_log(0, "GM Value Count %d %d", HostSize, ChunkSize  );
    for (int n = 0; n < HostSize; ++n )
    {
        gm_new_host_inert(data );
        sys_log(0, "GM HOST : IP[%s] ", data );   
        data += ChunkSize;
    }
 
 
    data += 2;
    int adminsize = decode_2bytes(data );
    data += 2;

    for (int n = 0; n < adminsize; ++n )
    {
        tAdminInfo& rAdminInfo = *(tAdminInfo*)data;

        gm_new_insert(rAdminInfo );
    
        data += sizeof(rAdminInfo );
    }
 
    //END_ADMIN_MANAGER
    

    WORD endCheck=decode_2bytes(data);
    if (endCheck != 0xffff)
    {
        sys_err("boot packet end check error [%x]!=0xffff", endCheck);
        thecore_shutdown();
        return;
    }
    else
        sys_log(0, "boot packet end check ok [%x]==0xffff", endCheck );
    data +=2;

    if (!ITEM_MANAGER::instance().SetMaxItemID(*range))
    {
        sys_err("not enough item id contact your administrator!");
        thecore_shutdown();
        return;
    }

    if (!ITEM_MANAGER::instance().SetMaxSpareItemID(*rangespare))
    {
        sys_err("not enough item id for spare contact your administrator!");
        thecore_shutdown();
        return;
    }



    // LOCALE_SERVICE
    const int FILE_NAME_LEN = 256;
    char szCommonDropItemFileName[FILE_NAME_LEN];
    char szETCDropItemFileName[FILE_NAME_LEN];
    char szMOBDropItemFileName[FILE_NAME_LEN];
    char szDropItemGroupFileName[FILE_NAME_LEN];
    char szSpecialItemGroupFileName[FILE_NAME_LEN];
    char szMapIndexFileName[FILE_NAME_LEN];
    char szItemVnumMaskTableFileName[FILE_NAME_LEN];
    char szDragonSoulTableFileName[FILE_NAME_LEN];

    snprintf(szCommonDropItemFileName, sizeof(szCommonDropItemFileName),
            "%s/common_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szETCDropItemFileName, sizeof(szETCDropItemFileName),
            "%s/etc_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szMOBDropItemFileName, sizeof(szMOBDropItemFileName),
            "%s/mob_drop_item.txt", LocaleService_GetBasePath().c_str());
    snprintf(szSpecialItemGroupFileName, sizeof(szSpecialItemGroupFileName),
            "%s/special_item_group.txt", LocaleService_GetBasePath().c_str());
    snprintf(szDropItemGroupFileName, sizeof(szDropItemGroupFileName),
            "%s/drop_item_group.txt", LocaleService_GetBasePath().c_str());
    snprintf(szMapIndexFileName, sizeof(szMapIndexFileName),
            "%s/index", LocaleService_GetMapPath().c_str());
    snprintf(szItemVnumMaskTableFileName, sizeof(szItemVnumMaskTableFileName),
            "%s/ori_to_new_table.txt", LocaleService_GetBasePath().c_str());
    snprintf(szDragonSoulTableFileName, sizeof(szDragonSoulTableFileName),
            "%s/dragon_soul_table.txt", LocaleService_GetBasePath().c_str());

    sys_log(0, "Initializing Informations of Cube System");
    if (!Cube_InformationInitialize())
    {
        sys_err("cannot init cube infomation.");
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: CommonDropItem: %s", szCommonDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadCommonDropItemFile(szCommonDropItemFileName))
    {
        sys_err("cannot load CommonDropItem: %s", szCommonDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: ETCDropItem: %s", szETCDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadEtcDropItemFile(szETCDropItemFileName))
    {
        sys_err("cannot load ETCDropItem: %s", szETCDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: DropItemGroup: %s", szDropItemGroupFileName);
    if (!ITEM_MANAGER::instance().ReadDropItemGroup(szDropItemGroupFileName))
    {
        sys_err("cannot load DropItemGroup: %s", szDropItemGroupFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: SpecialItemGroup: %s", szSpecialItemGroupFileName);
    if (!ITEM_MANAGER::instance().ReadSpecialDropItemFile(szSpecialItemGroupFileName))
    {
        sys_err("cannot load SpecialItemGroup: %s", szSpecialItemGroupFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: ItemVnumMaskTable : %s", szItemVnumMaskTableFileName);
    if (!ITEM_MANAGER::instance().ReadItemVnumMaskTable(szItemVnumMaskTableFileName))
    {
        sys_log(0, "Could not open MaskItemTable");
    }

    sys_log(0, "LoadLocaleFile: MOBDropItemFile: %s", szMOBDropItemFileName);
    if (!ITEM_MANAGER::instance().ReadMonsterDropItemGroup(szMOBDropItemFileName))
    {
        sys_err("cannot load MOBDropItemFile: %s", szMOBDropItemFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: MapIndex: %s", szMapIndexFileName);
    if (!SECTREE_MANAGER::instance().Build(szMapIndexFileName, LocaleService_GetMapPath().c_str()))
    {
        sys_err("cannot load MapIndex: %s", szMapIndexFileName);
        thecore_shutdown();
        return;
    }

    sys_log(0, "LoadLocaleFile: DragonSoulTable: %s", szDragonSoulTableFileName);
    if (!DSManager::instance().ReadDragonSoulTableFile(szDragonSoulTableFileName))
    {
        sys_err("cannot load DragonSoulTable: %s", szDragonSoulTableFileName);
        //thecore_shutdown();
        //return;
    }

    // END_OF_LOCALE_SERVICE


    building::CManager::instance().FinalizeBoot();

    CMotionManager::instance().Build();

    signal_timer_enable(30);

    if (test_server)
    {
        CMobManager::instance().DumpRegenCount("mob_count");
    }

    CPCBangManager::instance().RequestUpdateIPList(0);

    // castle_boot
    castle_boot();
#ifdef WJ_PREMIUM_PRIVATE_SHOP
    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_INIT;
    db_clientdesc->DBPacket(HEADER_GD_PRIVATE_SHOP, 0, &bSubHeader, sizeof(bSubHeader));
#endif
}

EVENTINFO(quest_login_event_info)
{
    DWORD dwPID;

    quest_login_event_info()
    : dwPID( 0 )
    {
    }
};

EVENTFUNC(quest_login_event)
{
    quest_login_event_info* info = dynamic_cast<quest_login_event_info*>( event->info );

    if ( info == NULL )
    {
        sys_err( "quest_login_event> <Factor> Null pointer" );
        return 0;
    }

    DWORD dwPID = info->dwPID;

    LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);

    if (!ch)
        return 0;

    LPDESC d = ch->GetDesc();

    if (!d)
        return 0;

    if (d->IsPhase(PHASE_HANDSHAKE) ||
        d->IsPhase(PHASE_LOGIN) ||
        d->IsPhase(PHASE_SELECT) ||
        d->IsPhase(PHASE_DEAD) ||
        d->IsPhase(PHASE_LOADING))
    {
        return PASSES_PER_SEC(1);
    }
    else if (d->IsPhase(PHASE_CLOSE))
    {
        return 0;
    }
    else if (d->IsPhase(PHASE_GAME))
    {
        sys_log(0, "QUEST_LOAD: Login pc %d by event", ch->GetPlayerID());
        quest::CQuestManager::instance().Login(ch->GetPlayerID());
        return 0;
    }
    else
    {
        sys_err(0, "input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
        return 0;
    }
}

void CInputDB::QuestLoad(LPDESC d, const char * c_pData)
{
    if (NULL == d)
        return;

    LPCHARACTER ch = d->GetCharacter();

    if (NULL == ch)
        return;

    const DWORD dwCount = decode_4bytes(c_pData);

    const TQuestTable* pQuestTable = reinterpret_cast<const TQuestTable*>(c_pData+4);

    if (NULL != pQuestTable)
    {
        if (dwCount != 0)
        {
            if (ch->GetPlayerID() != pQuestTable[0].dwPID)
            {
                sys_err("PID differs %u %u", ch->GetPlayerID(), pQuestTable[0].dwPID);
                return;
            }
        }

        sys_log(0, "QUEST_LOAD: count %d", dwCount);

        quest::PC * pkPC = quest::CQuestManager::instance().GetPCForce(ch->GetPlayerID());

        if (!pkPC)
        {
            sys_err("null quest::PC with id %u", pQuestTable[0].dwPID);
            return;
        }

        if (pkPC->IsLoaded())
            return;

        for (unsigned int i = 0; i < dwCount; ++i)
        {
            std::string st(pQuestTable[i].szName);

            st += ".";
            st += pQuestTable[i].szState;

            sys_log(0,  "            %s %d", st.c_str(), pQuestTable[i].lValue);
            pkPC->SetFlag(st.c_str(), pQuestTable[i].lValue, false);
        }

        pkPC->SetLoaded();
        pkPC->Build();

        if (ch->GetDesc()->IsPhase(PHASE_GAME))
        {
            sys_log(0, "QUEST_LOAD: Login pc %d", pQuestTable[0].dwPID);
            quest::CQuestManager::instance().Login(pQuestTable[0].dwPID);
        }
        else
        {
            quest_login_event_info* info = AllocEventInfo<quest_login_event_info>();
            info->dwPID = ch->GetPlayerID();

            event_create(quest_login_event, info, PASSES_PER_SEC(1));
        }
    }
}

void CInputDB::SafeboxLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    TSafeboxTable * p = (TSafeboxTable *) c_pData;

    if (d->GetAccountTable().id != p->dwID)
    {
        sys_err("SafeboxLoad: safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
        return;
    }

    if (!d->GetCharacter())
        return;

    BYTE bSize = 1;

    LPCHARACTER ch = d->GetCharacter();

    //PREVENT_TRADE_WINDOW
    if (ch->GetShopOwner() || ch->GetExchange() || ch->GetMyShop() || ch->IsCubeOpen() )
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른거래창이 열린상태에서는 창고를 열수가 없습니다." ) );
        d->GetCharacter()->CancelSafeboxLoad();
        return;
    }
    //END_PREVENT_TRADE_WINDOW

    // ADD_PREMIUM
    if (d->GetCharacter()->GetPremiumRemainSeconds(PREMIUM_SAFEBOX) > 0 ||
            d->GetCharacter()->IsEquipUniqueGroup(UNIQUE_GROUP_LARGE_SAFEBOX))
        bSize = 3;
    // END_OF_ADD_PREMIUM

    //if (d->GetCharacter()->IsEquipUniqueItem(UNIQUE_ITEM_SAFEBOX_EXPAND))
    //bSize = 3; // 창고확장권

    //d->GetCharacter()->LoadSafebox(p->bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
    d->GetCharacter()->LoadSafebox(bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
}

void CInputDB::SafeboxChangeSize(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    BYTE bSize = *(BYTE *) c_pData;

    if (!d->GetCharacter())
        return;

    d->GetCharacter()->ChangeSafeboxSize(bSize);
}

//
// @version    05/06/20 Bang2ni - ReqSafeboxLoad 의 취소
//
void CInputDB::SafeboxWrongPassword(LPDESC d)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    TPacketCGSafeboxWrongPassword p;
    p.bHeader = HEADER_GC_SAFEBOX_WRONG_PASSWORD;
    d->Packet(&p, sizeof(p));

    d->GetCharacter()->CancelSafeboxLoad();
}

void CInputDB::SafeboxChangePasswordAnswer(LPDESC d, const char* c_pData)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    TSafeboxChangePasswordPacketAnswer* p = (TSafeboxChangePasswordPacketAnswer*) c_pData;
    if (p->flag)
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 창고 비밀번호가 변경되었습니다."));
    }
    else
    {
        d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 기존 비밀번호가 틀렸습니다."));
    }
}

void CInputDB::MallLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    TSafeboxTable * p = (TSafeboxTable *) c_pData;

    if (d->GetAccountTable().id != p->dwID)
    {
        sys_err("safebox has different id %u != %u", d->GetAccountTable().id, p->dwID);
        return;
    }

    if (!d->GetCharacter())
        return;

    d->GetCharacter()->LoadMall(p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable)));
}

void CInputDB::LoginAlready(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    // INTERNATIONAL_VERSION 이미 접속중이면 접속 끊음
    {
        TPacketDGLoginAlready * p = (TPacketDGLoginAlready *) c_pData;

        LPDESC d2 = DESC_MANAGER::instance().FindByLoginName(p->szLogin);

        if (d2)
            d2->DisconnectOfSameLogin();
        else
        {
            TPacketGGDisconnect pgg;

            pgg.bHeader = HEADER_GG_DISCONNECT;
            strlcpy(pgg.szLogin, p->szLogin, sizeof(pgg.szLogin));

            P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGDisconnect));
        }
    }
    // END_OF_INTERNATIONAL_VERSION

    LoginFailure(d, "ALREADY");
}

void CInputDB::EmpireSelect(LPDESC d, const char * c_pData)
{
    sys_log(0, "EmpireSelect %p", get_pointer(d));

    if (!d)
        return;

    TAccountTable & rTable = d->GetAccountTable();
    rTable.bEmpire = *(BYTE *) c_pData;

    TPacketGCEmpire pe;
    pe.bHeader = HEADER_GC_EMPIRE;
    pe.bEmpire = rTable.bEmpire;
    d->Packet(&pe, sizeof(pe));

    for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
        if (rTable.players[i].dwID)
        {
            rTable.players[i].x = EMPIRE_START_X(rTable.bEmpire);
            rTable.players[i].y = EMPIRE_START_Y(rTable.bEmpire);
        }

    GetServerLocation(d->GetAccountTable(), rTable.bEmpire);

    d->SendLoginSuccessPacket();
}

void CInputDB::MapLocations(const char * c_pData)
{
    BYTE bCount = *(BYTE *) (c_pData++);

    sys_log(0, "InputDB::MapLocations %d", bCount);

    TMapLocation * pLoc = (TMapLocation *) c_pData;

    while (bCount--)
    {
        for (int i = 0; i < 32; ++i)
        {
            if (0 == pLoc->alMaps[i])
                break;

            CMapLocation::instance().Insert(pLoc->alMaps[i], pLoc->szHost, pLoc->wPort);
        }

        pLoc++;
    }
}

void CInputDB::P2P(const char * c_pData)
{
    extern LPFDWATCH main_fdw;

    TPacketDGP2P * p = (TPacketDGP2P *) c_pData;

    P2P_MANAGER& mgr = P2P_MANAGER::instance();

    if (false == DESC_MANAGER::instance().IsP2PDescExist(p->szHost, p->wPort))
    {
        LPCLIENT_DESC pkDesc = NULL;
        sys_log(0, "InputDB:P2P %s:%u", p->szHost, p->wPort);
        pkDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, p->szHost, p->wPort, PHASE_P2P, false);
        mgr.RegisterConnector(pkDesc);
        pkDesc->SetP2P(p->szHost, p->wPort, p->bChannel);
    }
}

void CInputDB::GuildLoad(const char * c_pData)
{
    CGuildManager::instance().LoadGuild(*(DWORD *) c_pData);
}

void CInputDB::GuildSkillUpdate(const char* c_pData)
{
    TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;

    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
    {
        g->UpdateSkill(p->skill_point, p->skill_levels);
        g->GuildPointChange(POINT_SP, p->amount, p->save?true:false);
    }
}

void CInputDB::GuildWar(const char* c_pData)
{
    TPacketGuildWar * p = (TPacketGuildWar*) c_pData;

    sys_log(0, "InputDB::GuildWar %u %u state %d", p->dwGuildFrom, p->dwGuildTo, p->bWar);

    switch (p->bWar)
    {
        case GUILD_WAR_SEND_DECLARE:
        case GUILD_WAR_RECV_DECLARE:
            CGuildManager::instance().DeclareWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        case GUILD_WAR_REFUSE:
            CGuildManager::instance().RefuseWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_WAIT_START:
            CGuildManager::instance().WaitStartWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_CANCEL:
            CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_ON_WAR:
            CGuildManager::instance().StartWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_END:
            CGuildManager::instance().EndWar(p->dwGuildFrom, p->dwGuildTo);
            break;

        case GUILD_WAR_OVER:
            CGuildManager::instance().WarOver(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        case GUILD_WAR_RESERVE:
            CGuildManager::instance().ReserveWar(p->dwGuildFrom, p->dwGuildTo, p->bType);
            break;

        default:
            sys_err("Unknown guild war state");
            break;
    }
}

void CInputDB::GuildWarScore(const char* c_pData)
{
    TPacketGuildWarScore* p = (TPacketGuildWarScore*) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuildGainPoint);
    g->SetWarScoreAgainstTo(p->dwGuildOpponent, p->lScore);
}

void CInputDB::GuildSkillRecharge()
{
    CGuildManager::instance().SkillRecharge();
}

void CInputDB::GuildExpUpdate(const char* c_pData)
{
    TPacketGuildSkillUpdate * p = (TPacketGuildSkillUpdate *) c_pData;
    sys_log(1, "GuildExpUpdate %d", p->amount);

    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
        g->GuildPointChange(POINT_EXP, p->amount);
}

void CInputDB::GuildAddMember(const char* c_pData)
{
    TPacketDGGuildMember * p = (TPacketDGGuildMember *) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->AddMember(p);
}

void CInputDB::GuildRemoveMember(const char* c_pData)
{
    TPacketGuild* p=(TPacketGuild*)c_pData;
    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->RemoveMember(p->dwInfo);
}

void CInputDB::GuildChangeGrade(const char* c_pData)
{
    TPacketGuild* p=(TPacketGuild*)c_pData;
    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    if (g)
        g->P2PChangeGrade((BYTE)p->dwInfo);
}

void CInputDB::GuildChangeMemberData(const char* c_pData)
{
    sys_log(0, "Recv GuildChangeMemberData");
    TPacketGuildChangeMemberData * p = (TPacketGuildChangeMemberData *) c_pData;
    CGuild * g = CGuildManager::instance().TouchGuild(p->guild_id);

    if (g)
        g->ChangeMemberData(p->pid, p->offer, p->level, p->grade);
}

void CInputDB::GuildDisband(const char* c_pData)
{
    TPacketGuild * p = (TPacketGuild*) c_pData;
    CGuildManager::instance().DisbandGuild(p->dwGuild);
}

void CInputDB::GuildLadder(const char* c_pData)
{
    TPacketGuildLadder* p = (TPacketGuildLadder*) c_pData;
    sys_log(0, "Recv GuildLadder %u %d / w %d d %d l %d", p->dwGuild, p->lLadderPoint, p->lWin, p->lDraw, p->lLoss);
    CGuild * g = CGuildManager::instance().TouchGuild(p->dwGuild);

    g->SetLadderPoint(p->lLadderPoint);
    g->SetWarData(p->lWin, p->lDraw, p->lLoss);
}

void CInputDB::ItemLoad(LPDESC d, const char * c_pData)
{
    LPCHARACTER ch;

    if (!d || !(ch = d->GetCharacter()))
        return;

    if (ch->IsItemLoaded())
        return;

    DWORD dwCount = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    sys_log(0, "ITEM_LOAD: COUNT %s %u", ch->GetName(), dwCount);

    std::vector<LPITEM> v;

    TPlayerItem * p = (TPlayerItem *) c_pData;

    for (DWORD i = 0; i < dwCount; ++i, ++p)
    {
        LPITEM item = ITEM_MANAGER::instance().CreateItem(p->vnum, p->count, p->id);

        if (!item)
        {
            sys_err("cannot create item by vnum %u (name %s id %u)", p->vnum, ch->GetName(), p->id);
            continue;
        }

        item->SetSkipSave(true);
        item->SetSockets(p->alSockets);
        item->SetAttributes(p->aAttr);

        if ((p->window == INVENTORY && ch->GetInventoryItem(p->pos)) ||
                (p->window == EQUIPMENT && ch->GetWear(p->pos)))
        {
            sys_log(0, "ITEM_RESTORE: %s %s", ch->GetName(), item->GetName());
            v.push_back(item);
        }
        else
        {
            switch (p->window)
            {
                case INVENTORY:
                case DRAGON_SOUL_INVENTORY:
                #ifdef ENABLE_SPLIT_INVENTORY_SYSTEM
                case SKILL_BOOK_INVENTORY:
                case UPGRADE_ITEMS_INVENTORY:
                case STONE_INVENTORY:
                case BOX_INVENTORY:
                case EFSUN_INVENTORY:
                case CICEK_INVENTORY:
                #endif
                    item->AddToCharacter(ch, TItemPos(p->window, p->pos));
                    break;

                case EQUIPMENT:
                    if (item->CheckItemUseLevel(ch->GetLevel()) == true )
                    {
                        if (item->EquipTo(ch, p->pos) == false )
                        {
                            v.push_back(item);
                        }
                    }
                    else
                    {
                        v.push_back(item);
                    }
                    break;
            }
        }

        if (false == item->OnAfterCreatedItem())
            sys_err("Failed to call ITEM::OnAfterCreatedItem (vnum: %d, id: %d)", item->GetVnum(), item->GetID());

        item->SetSkipSave(false);
    }

    itertype(v) it = v.begin();

    while (it != v.end())
    {
        LPITEM item = *(it++);

        int pos = ch->GetEmptyInventory(item->GetSize());

        if (pos < 0)
        {
            PIXEL_POSITION coord;
            coord.x = ch->GetX();
            coord.y = ch->GetY();

            item->AddToGround(ch->GetMapIndex(), coord);
            item->SetOwnership(ch, 180);
            item->StartDestroyEvent();
        }
        else
            item->AddToCharacter(ch, TItemPos(INVENTORY, pos));
    }

    ch->CheckMaximumPoints();
    ch->PointsPacket();

    ch->SetItemLoaded();
}

void CInputDB::AffectLoad(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    if (!d->GetCharacter())
        return;

    LPCHARACTER ch = d->GetCharacter();

    DWORD dwPID = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    DWORD dwCount = decode_4bytes(c_pData);
    c_pData += sizeof(DWORD);

    if (ch->GetPlayerID() != dwPID)
        return;

    ch->LoadAffect(dwCount, (TPacketAffectElement *) c_pData);
 
}
 


void CInputDB::PartyCreate(const char* c_pData)
{
    TPacketPartyCreate* p = (TPacketPartyCreate*) c_pData;
    CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);
}

void CInputDB::PartyDelete(const char* c_pData)
{
    TPacketPartyDelete* p = (TPacketPartyDelete*) c_pData;
    CPartyManager::instance().P2PDeleteParty(p->dwLeaderPID);
}

void CInputDB::PartyAdd(const char* c_pData)
{
    TPacketPartyAdd* p = (TPacketPartyAdd*) c_pData;
    CPartyManager::instance().P2PJoinParty(p->dwLeaderPID, p->dwPID, p->bState);
}

void CInputDB::PartyRemove(const char* c_pData)
{
    TPacketPartyRemove* p = (TPacketPartyRemove*) c_pData;
    CPartyManager::instance().P2PQuitParty(p->dwPID);
}

void CInputDB::PartyStateChange(const char* c_pData)
{
    TPacketPartyStateChange * p = (TPacketPartyStateChange *) c_pData;
    LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);

    if (!pParty)
        return;

    pParty->SetRole(p->dwPID, p->bRole, p->bFlag);
}

void CInputDB::PartySetMemberLevel(const char* c_pData)
{
    TPacketPartySetMemberLevel* p = (TPacketPartySetMemberLevel*) c_pData;
    LPPARTY pParty = CPartyManager::instance().P2PCreateParty(p->dwLeaderPID);

    if (!pParty)
        return;

    pParty->P2PSetMemberLevel(p->dwPID, p->bLevel);
}

void CInputDB::Time(const char * c_pData)
{
    set_global_time(*(time_t *) c_pData);
}

void CInputDB::ReloadProto(const char * c_pData)
{
    WORD wSize;

    /*
     * Skill
     */
    wSize = decode_2bytes(c_pData);
    c_pData += sizeof(WORD);
    if (wSize) CSkillManager::instance().Initialize((TSkillTable *) c_pData, wSize);
    c_pData += sizeof(TSkillTable) * wSize;

    /*
     * Banwords
     */

    wSize = decode_2bytes(c_pData);
    c_pData += sizeof(WORD);
    CBanwordManager::instance().Initialize((TBanwordTable *) c_pData, wSize);
    c_pData += sizeof(TBanwordTable) * wSize;

    /*
     * ITEM
     */
    wSize = decode_2bytes(c_pData);
    c_pData += 2;
    sys_log(0, "RELOAD: ITEM: %d", wSize);

    if (wSize)
    {
        ITEM_MANAGER::instance().Initialize((TItemTable *) c_pData, wSize);
        c_pData += wSize * sizeof(TItemTable);
    }

    /*
     * MONSTER
     */
    wSize = decode_2bytes(c_pData);
    c_pData += 2;
    sys_log(0, "RELOAD: MOB: %d", wSize);

    if (wSize)
    {
        CMobManager::instance().Initialize((TMobTable *) c_pData, wSize);
        c_pData += wSize * sizeof(TMobTable);
    }

    CMotionManager::instance().Build();

    CHARACTER_MANAGER::instance().for_each_pc(std::mem_fun(&CHARACTER::ComputePoints));
}

void CInputDB::GuildSkillUsableChange(const char* c_pData)
{
    TPacketGuildSkillUsableChange* p = (TPacketGuildSkillUsableChange*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);

    g->SkillUsableChange(p->dwSkillVnum, p->bUsable?true:false);
}

void CInputDB::AuthLogin(LPDESC d, const char * c_pData)
{
    if (!d)
        return;

    BYTE bResult = *(BYTE *) c_pData;

    TPacketGCAuthSuccess ptoc;

    ptoc.bHeader = HEADER_GC_AUTH_SUCCESS;

    if (bResult)
    {
        // Panama 암호화 팩에 필요한 키 보내기
        SendPanamaList(d);
        ptoc.dwLoginKey = d->GetLoginKey();

        //NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_-
        //Send Client Package CryptKey
        {
            DESC_MANAGER::instance().SendClientPackageCryptKey(d);
            DESC_MANAGER::instance().SendClientPackageSDBToLoadMap(d, MAPNAME_DEFAULT);
        }
    }
    else
    {
        ptoc.dwLoginKey = 0;
    }

    ptoc.bResult = bResult;

    d->Packet(&ptoc, sizeof(TPacketGCAuthSuccess));
    sys_log(0, "AuthLogin result %u key %u", bResult, d->GetLoginKey());
}


void CInputDB::ChangeEmpirePriv(const char* c_pData)
{
    TPacketDGChangeEmpirePriv* p = (TPacketDGChangeEmpirePriv*) c_pData;

    // ADD_EMPIRE_PRIV_TIME
    CPrivManager::instance().GiveEmpirePriv(p->empire, p->type, p->value, p->bLog, p->end_time_sec);
    // END_OF_ADD_EMPIRE_PRIV_TIME
}

/**
 * @version 05/06/08    Bang2ni - 지속시간 추가
 */
void CInputDB::ChangeGuildPriv(const char* c_pData)
{
    TPacketDGChangeGuildPriv* p = (TPacketDGChangeGuildPriv*) c_pData;

    // ADD_GUILD_PRIV_TIME
    CPrivManager::instance().GiveGuildPriv(p->guild_id, p->type, p->value, p->bLog, p->end_time_sec);
    // END_OF_ADD_GUILD_PRIV_TIME
}

void CInputDB::ChangeCharacterPriv(const char* c_pData)
{
    TPacketDGChangeCharacterPriv* p = (TPacketDGChangeCharacterPriv*) c_pData;
    CPrivManager::instance().GiveCharacterPriv(p->pid, p->type, p->value, p->bLog);
}

void CInputDB::MoneyLog(const char* c_pData)
{
    TPacketMoneyLog * p = (TPacketMoneyLog *) c_pData;

    if (p->type == 4) // QUEST_MONEY_LOG_SKIP
        return;

    if (g_bAuthServer ==true )
        return;

    LogManager::instance().MoneyLog(p->type, p->vnum, p->gold);
}

void CInputDB::GuildMoneyChange(const char* c_pData)
{
    TPacketDGGuildMoneyChange* p = (TPacketDGGuildMoneyChange*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
    if (g)
    {
        g->RecvMoneyChange(p->iTotalGold);
    }
}

void CInputDB::GuildWithdrawMoney(const char* c_pData)
{
    TPacketDGGuildMoneyWithdraw* p = (TPacketDGGuildMoneyWithdraw*) c_pData;

    CGuild* g = CGuildManager::instance().TouchGuild(p->dwGuild);
    if (g)
    {
        g->RecvWithdrawMoneyGive(p->iChangeGold);
    }
}

void CInputDB::SetEventFlag(const char* c_pData)
{
    TPacketSetEventFlag* p = (TPacketSetEventFlag*) c_pData;
    quest::CQuestManager::instance().SetEventFlag(p->szFlagName, p->lValue);
}

void CInputDB::CreateObject(const char * c_pData)
{
    using namespace building;
    CManager::instance().LoadObject((TObject *) c_pData);
}

void CInputDB::DeleteObject(const char * c_pData)
{
    using namespace building;
    CManager::instance().DeleteObject(*(DWORD *) c_pData);
}

void CInputDB::UpdateLand(const char * c_pData)
{
    using namespace building;
    CManager::instance().UpdateLand((TLand *) c_pData);
}

void CInputDB::Notice(const char * c_pData)
{
    extern void SendNotice(const char * c_pszBuf);

    char szBuf[256+1];
    strlcpy(szBuf, c_pData, sizeof(szBuf));

    sys_log(0, "InputDB:: Notice: %s", szBuf);

    //SendNotice(LC_TEXT(szBuf));
    SendNotice(szBuf);
}

void CInputDB::GuildWarReserveAdd(TGuildWarReserve * p)
{
    CGuildManager::instance().ReserveWarAdd(p);
}

void CInputDB::GuildWarReserveDelete(DWORD dwID)
{
    CGuildManager::instance().ReserveWarDelete(dwID);
}

void CInputDB::GuildWarBet(TPacketGDGuildWarBet * p)
{
    CGuildManager::instance().ReserveWarBet(p);
}

void CInputDB::MarriageAdd(TPacketMarriageAdd * p)
{
    sys_log(0, "MarriageAdd %u %u %u %s %s", p->dwPID1, p->dwPID2, (DWORD)p->tMarryTime, p->szName1, p->szName2);
    marriage::CManager::instance().Add(p->dwPID1, p->dwPID2, p->tMarryTime, p->szName1, p->szName2);
}

void CInputDB::MarriageUpdate(TPacketMarriageUpdate * p)
{
    sys_log(0, "MarriageUpdate %u %u %d %d", p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
    marriage::CManager::instance().Update(p->dwPID1, p->dwPID2, p->iLovePoint, p->byMarried);
}

void CInputDB::MarriageRemove(TPacketMarriageRemove * p)
{
    sys_log(0, "MarriageRemove %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().Remove(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingRequest(TPacketWeddingRequest* p)
{
    marriage::WeddingManager::instance().Request(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingReady(TPacketWeddingReady* p)
{
    sys_log(0, "WeddingReady %u %u %u", p->dwPID1, p->dwPID2, p->dwMapIndex);
    marriage::CManager::instance().WeddingReady(p->dwPID1, p->dwPID2, p->dwMapIndex);
}

void CInputDB::WeddingStart(TPacketWeddingStart* p)
{
    sys_log(0, "WeddingStart %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().WeddingStart(p->dwPID1, p->dwPID2);
}

void CInputDB::WeddingEnd(TPacketWeddingEnd* p)
{
    sys_log(0, "WeddingEnd %u %u", p->dwPID1, p->dwPID2);
    marriage::CManager::instance().WeddingEnd(p->dwPID1, p->dwPID2);
}

// MYSHOP_PRICE_LIST
void CInputDB::MyshopPricelistRes(LPDESC d, const TPacketMyshopPricelistHeader* p )
{
    LPCHARACTER ch;

    if (!d || !(ch = d->GetCharacter()) )
        return;

    sys_log(0, "RecvMyshopPricelistRes name[%s]", ch->GetName());
    ch->UseSilkBotaryReal(p );

}
// END_OF_MYSHOP_PRICE_LIST


//RELOAD_ADMIN
void CInputDB::ReloadAdmin(const char * c_pData )
{
    gm_new_clear();
    int ChunkSize = decode_2bytes(c_pData );
    c_pData += 2;
    int HostSize = decode_2bytes(c_pData );
    c_pData += 2;
 
    for (int n = 0; n < HostSize; ++n )
    {
        gm_new_host_inert(c_pData );
        c_pData += ChunkSize;
    }
 
 
    c_pData += 2;
    int size =     decode_2bytes(c_pData );
    c_pData += 2;
 
    for (int n = 0; n < size; ++n )
    {
        tAdminInfo& rAdminInfo = *(tAdminInfo*)c_pData;

        gm_new_insert(rAdminInfo );

        c_pData += sizeof (tAdminInfo );
 
        LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindPC(rAdminInfo.m_szName );
        if (pChar )
        {
            pChar->SetGMLevel();
        }
    }
 
}
//END_RELOAD_ADMIN

////////////////////////////////////////////////////////////////////
// Analyze
// @version    05/06/10 Bang2ni - 아이템 가격정보 리스트 패킷(HEADER_DG_MYSHOP_PRICELIST_RES) 처리루틴 추가.
////////////////////////////////////////////////////////////////////
int CInputDB::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
{
    switch (bHeader)
    {
    case HEADER_DG_BOOT:
        Boot(c_pData);
        break;

    case HEADER_DG_LOGIN_SUCCESS:
        LoginSuccess(m_dwHandle, c_pData);
        break;

    case HEADER_DG_LOGIN_NOT_EXIST:
        LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "NOID");
        break;

    case HEADER_DG_LOGIN_WRONG_PASSWD:
        LoginFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), "WRONGPWD");
        break;

    case HEADER_DG_LOGIN_ALREADY:
        LoginAlready(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_LOAD_SUCCESS:
        PlayerLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_CREATE_SUCCESS:
        PlayerCreateSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_CREATE_FAILED:
        PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 0);
        break;

    case HEADER_DG_PLAYER_CREATE_ALREADY:
        PlayerCreateFailure(DESC_MANAGER::instance().FindByHandle(m_dwHandle), 1);
        break;

    case HEADER_DG_PLAYER_DELETE_SUCCESS:
        PlayerDeleteSuccess(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_PLAYER_LOAD_FAILED:
        //sys_log(0, "PLAYER_LOAD_FAILED");
        break;

    case HEADER_DG_PLAYER_DELETE_FAILED:
        //sys_log(0, "PLAYER_DELETE_FAILED");
        PlayerDeleteFail(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
        break;

    case HEADER_DG_ITEM_LOAD:
        ItemLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_QUEST_LOAD:
        QuestLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_AFFECT_LOAD:
        AffectLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_LOAD:
        SafeboxLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_CHANGE_SIZE:
        SafeboxChangeSize(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_SAFEBOX_WRONG_PASSWORD:
        SafeboxWrongPassword(DESC_MANAGER::instance().FindByHandle(m_dwHandle));
        break;

    case HEADER_DG_SAFEBOX_CHANGE_PASSWORD_ANSWER:
        SafeboxChangePasswordAnswer(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_MALL_LOAD:
        MallLoad(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_EMPIRE_SELECT:
        EmpireSelect(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_MAP_LOCATIONS:
        MapLocations(c_pData);
        break;

    case HEADER_DG_P2P:
        P2P(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_UPDATE:
        GuildSkillUpdate(c_pData);
        break;

    case HEADER_DG_GUILD_LOAD:
        GuildLoad(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_RECHARGE:
        GuildSkillRecharge();
        break;

    case HEADER_DG_GUILD_EXP_UPDATE:
        GuildExpUpdate(c_pData);
        break;

    case HEADER_DG_PARTY_CREATE:
        PartyCreate(c_pData);
        break;

    case HEADER_DG_PARTY_DELETE:
        PartyDelete(c_pData);
        break;

    case HEADER_DG_PARTY_ADD:
        PartyAdd(c_pData);
        break;

    case HEADER_DG_PARTY_REMOVE:
        PartyRemove(c_pData);
        break;

    case HEADER_DG_PARTY_STATE_CHANGE:
        PartyStateChange(c_pData);
        break;

    case HEADER_DG_PARTY_SET_MEMBER_LEVEL:
        PartySetMemberLevel(c_pData);
        break;

    case HEADER_DG_TIME:
        Time(c_pData);
        break;

    case HEADER_DG_GUILD_ADD_MEMBER:
        GuildAddMember(c_pData);
        break;

    case HEADER_DG_GUILD_REMOVE_MEMBER:
        GuildRemoveMember(c_pData);
        break;

    case HEADER_DG_GUILD_CHANGE_GRADE:
        GuildChangeGrade(c_pData);
        break;

    case HEADER_DG_GUILD_CHANGE_MEMBER_DATA:
        GuildChangeMemberData(c_pData);
        break;

    case HEADER_DG_GUILD_DISBAND:
        GuildDisband(c_pData);
        break;

    case HEADER_DG_RELOAD_PROTO:
        ReloadProto(c_pData);
        break;

    case HEADER_DG_GUILD_WAR:
        GuildWar(c_pData);
        break;

    case HEADER_DG_GUILD_WAR_SCORE:
        GuildWarScore(c_pData);
        break;

    case HEADER_DG_GUILD_LADDER:
        GuildLadder(c_pData);
        break;

    case HEADER_DG_GUILD_SKILL_USABLE_CHANGE:
        GuildSkillUsableChange(c_pData);
        break;

    case HEADER_DG_CHANGE_NAME:
        ChangeName(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_AUTH_LOGIN:
        AuthLogin(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;

    case HEADER_DG_CHANGE_EMPIRE_PRIV:
        ChangeEmpirePriv(c_pData);
        break;

    case HEADER_DG_CHANGE_GUILD_PRIV:
        ChangeGuildPriv(c_pData);
        break;

    case HEADER_DG_CHANGE_CHARACTER_PRIV:
        ChangeCharacterPriv(c_pData);
        break;

    case HEADER_DG_MONEY_LOG:
        MoneyLog(c_pData);
        break;

    case HEADER_DG_GUILD_WITHDRAW_MONEY_GIVE:
        GuildWithdrawMoney(c_pData);
        break;

    case HEADER_DG_GUILD_MONEY_CHANGE:
        GuildMoneyChange(c_pData);
        break;

    case HEADER_DG_SET_EVENT_FLAG:
        SetEventFlag(c_pData);
        break;

    case HEADER_DG_CREATE_OBJECT:
        CreateObject(c_pData);
        break;

    case HEADER_DG_DELETE_OBJECT:
        DeleteObject(c_pData);
        break;

    case HEADER_DG_UPDATE_LAND:
        UpdateLand(c_pData);
        break;

    case HEADER_DG_NOTICE:
        Notice(c_pData);
        break;

    case HEADER_DG_GUILD_WAR_RESERVE_ADD:
        GuildWarReserveAdd((TGuildWarReserve *) c_pData);
        break;

    case HEADER_DG_GUILD_WAR_RESERVE_DEL:
        GuildWarReserveDelete(*(DWORD *) c_pData);
        break;

    case HEADER_DG_GUILD_WAR_BET:
        GuildWarBet((TPacketGDGuildWarBet *) c_pData);
        break;

    case HEADER_DG_MARRIAGE_ADD:
        MarriageAdd((TPacketMarriageAdd*) c_pData);
        break;

    case HEADER_DG_MARRIAGE_UPDATE:
        MarriageUpdate((TPacketMarriageUpdate*) c_pData);
        break;

    case HEADER_DG_MARRIAGE_REMOVE:
        MarriageRemove((TPacketMarriageRemove*) c_pData);
        break;

    case HEADER_DG_WEDDING_REQUEST:
        WeddingRequest((TPacketWeddingRequest*) c_pData);
        break;

    case HEADER_DG_WEDDING_READY:
        WeddingReady((TPacketWeddingReady*) c_pData);
        break;

    case HEADER_DG_WEDDING_START:
        WeddingStart((TPacketWeddingStart*) c_pData);
        break;

    case HEADER_DG_WEDDING_END:
        WeddingEnd((TPacketWeddingEnd*) c_pData);
        break;

        // MYSHOP_PRICE_LIST
    case HEADER_DG_MYSHOP_PRICELIST_RES:
        MyshopPricelistRes(DESC_MANAGER::instance().FindByHandle(m_dwHandle), (TPacketMyshopPricelistHeader*) c_pData );
        break;
        // END_OF_MYSHOP_PRICE_LIST
        //
    // RELOAD_ADMIN
    case HEADER_DG_RELOAD_ADMIN:
        ReloadAdmin(c_pData );   
        break;
    //END_RELOAD_ADMIN


    case HEADER_DG_ACK_CHANGE_GUILD_MASTER :
        this->GuildChangeMaster((TPacketChangeGuildMaster*) c_pData);
        break;
    case HEADER_DG_ACK_SPARE_ITEM_ID_RANGE :
        ITEM_MANAGER::instance().SetMaxSpareItemID(*((TItemIDRangeTable*)c_pData) );
        break;

    case HEADER_DG_UPDATE_HORSE_NAME :
    case HEADER_DG_ACK_HORSE_NAME :
        CHorseNameManager::instance().UpdateHorseName(
                ((TPacketUpdateHorseName*)c_pData)->dwPlayerID,
                ((TPacketUpdateHorseName*)c_pData)->szHorseName);
        break;

    case HEADER_DG_NEED_LOGIN_LOG:
        DetailLog( (TPacketNeedLoginLogInfo*) c_pData );
        break;
    // 독일 선물 기능 테스트
    case HEADER_DG_ITEMAWARD_INFORMER:
        ItemAwardInformer((TPacketItemAwardInfromer*) c_pData);
        break;
    case HEADER_DG_RESPOND_CHANNELSTATUS:
        RespondChannelStatus(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;
#ifdef WJ_PREMIUM_PRIVATE_SHOP
    case HEADER_DG_PRIVATE_SHOP:
        PrivateShop(DESC_MANAGER::instance().FindByHandle(m_dwHandle), c_pData);
        break;
#endif
    default:
        return (-1);
    }

    return 0;
}

bool CInputDB::Process(LPDESC d, const void * orig, int bytes, int & r_iBytesProceed)
{
    const char *    c_pData = (const char *) orig;
    BYTE        bHeader, bLastHeader = 0;
    int            iSize;
    int            iLastPacketLen = 0;

    for (m_iBufferLeft = bytes; m_iBufferLeft > 0;)
    {
        if (m_iBufferLeft < 9)
            return true;

        bHeader        = *((BYTE *) (c_pData));    // 1
        m_dwHandle    = *((DWORD *) (c_pData + 1));    // 4
        iSize        = *((DWORD *) (c_pData + 5));    // 4

        sys_log(1, "DBCLIENT: header %d handle %d size %d bytes %d", bHeader, m_dwHandle, iSize, bytes);

        if (m_iBufferLeft - 9 < iSize)
            return true;

        const char * pRealData = (c_pData + 9);

        if (Analyze(d, bHeader, pRealData) < 0)
        {
            sys_err("in InputDB: UNKNOWN HEADER: %d, LAST HEADER: %d(%d), REMAIN BYTES: %d, DESC: %d",
                    bHeader, bLastHeader, iLastPacketLen, m_iBufferLeft, d->GetSocket());

            //printdata((BYTE*) orig, bytes);
            //d->SetPhase(PHASE_CLOSE);
        }

        c_pData        += 9 + iSize;
        m_iBufferLeft    -= 9 + iSize;
        r_iBytesProceed    += 9 + iSize;

        iLastPacketLen    = 9 + iSize;
        bLastHeader    = bHeader;
    }

    return true;
}

void CInputDB::GuildChangeMaster(TPacketChangeGuildMaster* p)
{
    CGuildManager::instance().ChangeMaster(p->dwGuildID);
}

void CInputDB::DetailLog(const TPacketNeedLoginLogInfo* info)
{
    if (true == LC_IsEurope() || true == LC_IsYMIR() || true == LC_IsKorea() )
    {
        LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID( info->dwPlayerID );

        if (NULL != pChar)
        {
            LogManager::instance().DetailLoginLog(true, pChar);
        }
    }
}

void CInputDB::ItemAwardInformer(TPacketItemAwardInfromer *data)
{
    LPDESC d = DESC_MANAGER::instance().FindByLoginName(data->login);    //login정보
 
    if(d == NULL)
        return;
    else
    {
        if (d->GetCharacter())
        {
            LPCHARACTER ch = d->GetCharacter();
            ch->SetItemAward_vnum(data->vnum);    // ch 에 임시 저장해놨다가 QuestLoad 함수에서 처리
            ch->SetItemAward_cmd(data->command);   

            if(d->IsPhase(PHASE_GAME))            //게임페이즈일때
            {
                quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum());    //questmanager 호출
            }
        }
    }
}

void CInputDB::RespondChannelStatus(LPDESC desc, const char* pcData)
{
    if (!desc) {
        return;
    }
    const int nSize = decode_4bytes(pcData);
    pcData += sizeof(nSize);

    BYTE bHeader = HEADER_GC_RESPOND_CHANNELSTATUS;
    desc->BufferedPacket(&bHeader, sizeof(BYTE));
    desc->BufferedPacket(&nSize, sizeof(nSize));
    if (0 < nSize) {
        desc->BufferedPacket(pcData, sizeof(TChannelStatus)*nSize);
    }
    BYTE bSuccess = 1;
    desc->Packet(&bSuccess, sizeof(bSuccess));
    desc->SetChannelStatusRequested(false);
}
#ifdef WJ_PREMIUM_PRIVATE_SHOP
void CInputDB::PrivateShop(LPDESC d, const char* c_pData)
{
    const BYTE bSubHeader = *reinterpret_cast<const BYTE*>(c_pData);
    c_pData += sizeof(BYTE);

    switch (bSubHeader)
    {
        case PRIVATE_SHOP_DG_SUBHEADER_CREATE_RESULT:
        {
            TPacketDGPrivateShopCreateResult* p = (TPacketDGPrivateShopCreateResult*)c_pData;

            CPrivateShopManager::Instance().BuildPrivateShopResult(p->privateShopTable.dwOwner, &p->privateShopTable, p->bSuccess);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NO_SHOP:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You do not have an open personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CLOSE_RESULT_BALANCE_AVAILABLE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You must withdraw your earnings before you can close your personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_DESTROY:
        {
            if (d && d->GetCharacter())
                CPrivateShopManager::Instance().ClosePrivateShop(d->GetCharacter());
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SPAWN:
        {
            TPrivateShop* pPrivateShopTable = (TPrivateShop*)c_pData;
            c_pData += sizeof(TPrivateShop);

            const WORD wCount = *reinterpret_cast<const WORD*>(c_pData);
            c_pData += sizeof(WORD);

            TPlayerPrivateShopItem* pShopItem = (TPlayerPrivateShopItem*)c_pData;

            std::vector<TPlayerPrivateShopItem> vec_shopItem;
            for (int i = 0; i < wCount; ++i, ++pShopItem)
                vec_shopItem.push_back(*pShopItem);

            CPrivateShopManager::Instance().SpawnPrivateShop(pPrivateShopTable, vec_shopItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_DESPAWN:
        {
            const DWORD dwPID = *reinterpret_cast<const DWORD*>(c_pData);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwPID);
            if (!pPrivateShop)
                return;

            LogManager::Instance().CharLog(dwPID, 0, 0, 0, "PRIVATE SHOP DESPAWN", "", "");
            CPrivateShopManager::Instance().DeletePrivateShop(dwPID);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_LOAD:
        {
            if (!d || !d->GetCharacter())
                return;

            TPrivateShop* pPrivateShopTable = (TPrivateShop*)c_pData;
            d->GetCharacter()->SetPrivateShopTable(*pPrivateShopTable);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_LOAD:
        {
            if (!d || !d->GetCharacter())
                return;

            const WORD wCount = *reinterpret_cast<const WORD*>(c_pData);
            c_pData += sizeof(WORD);

            TPlayerPrivateShopItem* pShopItem = (TPlayerPrivateShopItem*)c_pData;

            for (int i = 0; i < wCount; ++i, ++pShopItem)
            {
                d->GetCharacter()->SetPrivateShopItem(*pShopItem);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_FALSE_ITEM:
        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKIN_FALSE_ITEM:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("This item is currently unavailable."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_FALSE_PRICE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Refresh your search result to sync price of the item."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_MODIFY_STATE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot buy an item while a personal shop is in a modifying state."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_NO_GOLD:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Yang."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_RESULT_NO_CHEQUE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You don't have enough Won."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_BUY_REQUEST:
        {
            TPacketDGPrivateShopBuyRequest* p = (TPacketDGPrivateShopBuyRequest*)c_pData;

            if (d && d->GetCharacter())
                CPrivateShopManager::Instance().ItemTransaction(d->GetCharacter(), &p->TRequestedItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_REMOVE_ITEM:
        {
            const DWORD dwShopID = *reinterpret_cast<const DWORD*>(c_pData);
            c_pData += sizeof(DWORD);

            const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwShopID);
            if (!pPrivateShop)
                return;

            pPrivateShop->RemoveItem(wPos);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ADD_ITEM:
        {
            const DWORD dwShopID = *reinterpret_cast<const DWORD*>(c_pData);
            c_pData += sizeof(DWORD);

            const TPlayerPrivateShopItem TPrivateShopItem = *(TPlayerPrivateShopItem*)c_pData;

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(dwShopID);
            if (!pPrivateShop)
                return;

            sys_err("Adding item to private shop!");
            pPrivateShop->ItemCheckin(TPrivateShopItem);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_WITHDRAW_RESULT_NO_BALANCE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("There is no money to collect."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NOT_MODIFY_STATE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot manage personal shop's content while it is not in a modifying state."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_WITHDRAW:
        {
            const TPacketDGPrivateShopWithdraw* p = (TPacketDGPrivateShopWithdraw*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->WithdrawPrivateShop(p->llGold, p->dwCheque);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_PRICE_CHANGE:
        {
            const TPacketPrivateShopItemPriceChange* p = (TPacketPrivateShopItemPriceChange*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopItemPrice(p->wPos, p->TPrice.llGold, p->TPrice.dwCheque);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwShopID);
            if (pPrivateShop)
                pPrivateShop->ChangeItemPrice(p->wPos, p->TPrice.llGold, p->TPrice.dwCheque);
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_MOVE:
        {
            const TPacketPrivateShopItemMove* p = (TPacketPrivateShopItemMove*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopItemPos(p->wPos, p->wChangePos);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwShopID);
            if (pPrivateShop)
                pPrivateShop->MoveItem(p->wPos, p->wChangePos);
        };
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CANNOT_MOVE_ITEM:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot move the item to that position."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKIN_REQ:
        {
            const TPacketDGPrivateShopItemCheckin* p = (TPacketDGPrivateShopItemCheckin*)c_pData;

            if (d && d->GetCharacter())
            {
                CPrivateShopManager::Instance().ItemCheckin(d->GetCharacter(), &p->TItem);
            }

        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_CHECKOUT_REQ:
        {
            const TPacketDGPrivateShopItemCheckout* p = (TPacketDGPrivateShopItemCheckout*)c_pData;

            if (d && d->GetCharacter())
            {
                CPrivateShopManager::Instance().ItemCheckout(d->GetCharacter(), p->wSrcPos, p->TDstPos);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_ITEM_EXPIRE:
        {
            const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);

            if (d && d->GetCharacter())
            {
                // Notify the player and remove the private shop item
                d->GetCharacter()->ItemExpireUpdate(wPos);
            }
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SHOP_NOT_AVAILABLE:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Your personal shop is currently unavailable."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_TITLE_CHANGE:
        {
            const TPacketPrivateShopTitleChange* p = (TPacketPrivateShopTitleChange*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->ChangePrivateShopTitle(p->szTitle);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->ChangeTitle(p->szTitle);

        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_CLOSE:
        {
            if (d && d->GetCharacter())
                d->GetCharacter()->ClosePrivateShop();
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_NO_AVAILABLE_SPACE:
        {
            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot place any more items in your personal shop."));
        }
        break;

        case PRIVATE_SHOP_DG_SUBHEADER_SALE_UPDATE:
        {
            const TPacketDGPrivateShopSaleUpdate* p = (TPacketDGPrivateShopSaleUpdate*)c_pData;

            if (!d || !d->GetCharacter())
                return;

            d->GetCharacter()->SaleUpdate(p->TItem, p->szCustomerName);
        }
        break;
    }
}
#endif
input_db.cppde
input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

Burayı Şu şekilde değiştirir denermisin.

input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
            {
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

                if (p->bState == STATE_CLOSED)
                {
                    sys_err("PRIVATE SHOP STATE_CLOSED PID %u", p->dwPID);
                    d->GetCharacter()->ClosePrivateShop();
                }
            }

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);

            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;
Yaptığımız işlem, d->GetCharacter()->ClosePrivateShop(); pazarın kapandığını söylemek yani STATE_CLOSED paketini alınca karakter üzerindeki pazar verilerini temizliyoruz.
 
input_db.cppde
input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);
            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;

Burayı Şu şekilde değiştirir denermisin.

input_db.cpp:
Genişlet Daralt Kopyala
        case PRIVATE_SHOP_DG_SUBHEADER_STATE_UPDATE:
        {
            const TPacketDGPrivateShopStateUpdate* p = (TPacketDGPrivateShopStateUpdate*)c_pData;

            if (d && d->GetCharacter())
            {
                d->GetCharacter()->SetPrivateShopState(p->bState, true);

                if (p->bState == STATE_CLOSED)
                {
                    sys_err("PRIVATE SHOP STATE_CLOSED PID %u", p->dwPID);
                    d->GetCharacter()->ClosePrivateShop();
                }
            }

            LPPRIVATE_SHOP pPrivateShop = CPrivateShopManager::Instance().GetPrivateShop(p->dwPID);

            if (pPrivateShop)
                pPrivateShop->SetState(p->bState);
        }
        break;
Yaptığımız işlem, d->GetCharacter()->ClosePrivateShop(); pazarın kapandığını söylemek yani STATE_CLOSED paketini alınca karakter üzerindeki pazar verilerini temizliyoruz.
Evet, bu ekleme pazarın kapanmasını sağlıyor ama pazarda satın alınan itemin biriken parası yok oluyor. Pazar panel ui pakete tıklanınca açılıyor ama yeni bir item listeleme denendiğinde private_shop_manager.cpp içerisinde " You cannot build a personal shop at this moment. " hatasını basıyor.

private_shop_manager.cpp:
Genişlet Daralt Kopyala
void CPrivateShopManager::BuildPrivateShopResult(DWORD dwPID, TPrivateShop* pPrivateShopTable, bool bSuccess)
{
    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }

    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (!pOwner)
    {
        sys_err("Cannot find private shop owner with id %u", dwPID);
        return;
    }

    pOwner->ClosePrivateShopPanel(true);

    const auto& map_privateShopItem = pPrivateShop->GetItemContainer();
    for (const auto& kv : map_privateShopItem)
    {
        WORD wPos = kv.first;
        LPITEM pItem = kv.second;

        if (bSuccess)
        {
            pItem->SetSkipSave(true);

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop

            pItem->RemoveFromCharacter();
            pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, pItem->GetCell(), 255);

            pItem->SetCell(nullptr, wPos);
            pItem->BindPrivateShop(pPrivateShop);

            TPlayerPrivateShopItem t{};
            CopyItemData(pItem, t);

            pOwner->SetPrivateShopItem(t);

            char szHint[128 + 1]{};
            snprintf(szHint, sizeof(szHint), "%s x%u pos %u gold %lld", pItem->GetName(), pItem->GetCount(), t.wPos, t.TPrice.llGold);
            LogManager::Instance().ItemLog(pOwner, pItem, "PRIVATE SHOP BUILD CHECKIN", szHint);
        }
        else
        {
            pItem->BindPrivateShop(nullptr);
            pItem->SetCheckinTime(0);
            pItem->SetGoldPrice(0);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
            pItem->SetChequePrice(0);
#endif

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop
        }
    }

    if (!bSuccess)
    {
        DeletePrivateShop(dwPID);
        pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot build a personal shop at this moment. "));

        sys_err("Private shop building process stopped for player %u", dwPID);
        return;
    }

    pPrivateShop->Show(pPrivateShopTable->lX, pPrivateShopTable->lY, 0, pPrivateShopTable->lMapIndex);
    pOwner->SetPrivateShopTable(*pPrivateShopTable);

    LogManager::Instance().CharLog(pOwner, 0, "PRIVATE SHOP BUILT", "");

    sys_log(0, "%s PRIVATE_SHOP: SUCCESS Shop entity created", pPrivateShopTable->szOwnerName);
}
syslog:
Genişlet Daralt Kopyala
Jun  5 15:12:55 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:12:55 :: Re-creating private shop for owner 1
Jun  5 15:12:55 :: PRIVATE_SHOP: Added item 10000303 pos 22 vnum 30190 to private shop 1
Jun  5 15:12:55 :: PRIVATE_SHOP: Private shop 1 successfully created
Jun  5 15:12:55 :: PRIVATE_SHOP: Private shop 1 successfully built
Jun  5 15:12:58 :: [    19600] return 0/0/0 async 0/0/0
Jun  5 15:13:03 :: [    19650] return 0/0/0 async 0/0/0
Jun  5 15:13:03 :: PRIVATE_SHOP: Buy request forwarded to game for private shop 1 customer 3 item pos 22 item 30190 yang 100000 won 0
Jun  5 15:13:04 :: PRIVATE_SHOP: Item bought from private shop 1 pos 22 gold 100000 won 0 by pid 3
Jun  5 15:13:04 :: PRIVATE_SHOP: Despawning item empty private shop 1 by item sale
Jun  5 15:13:04 :: PRIVATE_SHOP: Sending despawn update to owner 1
Jun  5 15:13:08 :: [    19700] return 0/0/0 async 0/0/0
Jun  5 15:13:13 :: [    19750] return 0/0/0 async 0/0/0
Jun  5 15:13:18 :: [    19800] return 0/0/0 async 0/0/0
Jun  5 15:13:23 :: [    19850] return 0/0/0 async 0/0/0
Jun  5 15:13:28 :: [    19900] return 0/0/0 async 0/0/0
Jun  5 15:13:33 :: [    19950] return 0/0/0 async 0/0/0
Jun  5 15:13:38 :: [    20000] return 0/0/0 async 0/0/0
Jun  5 15:13:43 :: [    20050] return 0/0/0 async 0/0/0
Jun  5 15:13:48 :: [    20100] return 0/0/0 async 0/0/0
Jun  5 15:13:53 :: [    20150] return 0/0/0 async 0/0/0
Jun  5 15:13:58 :: [    20200] return 0/0/0 async 0/0/0
Jun  5 15:14:03 :: [    20250] return 0/0/0 async 0/0/0
Jun  5 15:14:08 :: [    20300] return 0/0/0 async 0/0/0
Jun  5 15:14:13 :: [    20350] return 0/0/0 async 0/0/0
Jun  5 15:14:18 :: [    20400] return 0/0/0 async 0/0/0
Jun  5 15:14:19 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:14:19 :: PRIVATE_SHOP: Private shop 1 already created
Jun  5 15:14:23 :: [    20450] return 0/0/0 async 0/0/0
Jun  5 15:14:28 :: [    20500] return 0/0/0 async 0/0/0
Jun  5 15:14:33 :: [    20550] return 0/0/0 async 0/0/0
Jun  5 15:14:38 :: [    20600] return 0/0/0 async 0/0/0
Jun  5 15:14:43 :: [    20650] return 0/0/0 async 0/0/0
Jun  5 15:14:48 :: [    20700] return 0/0/0 async 0/0/0
Jun  5 15:14:53 :: [    20750] return 0/0/0 async 0/0/0
Jun  5 15:14:58 :: [    20800] return 0/0/0 async 0/0/0
Jun  5 15:15:03 :: [    20850] return 0/0/0 async 0/0/0
Jun  5 15:15:08 :: [    20900] return 0/0/0 async 0/0/0
Jun  5 15:15:13 :: [    20950] return 0/0/0 async 0/0/0
Jun  5 15:15:18 :: [    21000] return 0/0/0 async 0/0/0
Jun  5 15:15:23 :: [    21050] return 0/0/0 async 0/0/0
Jun  5 15:15:28 :: [    21100] return 0/0/0 async 0/0/0
Jun  5 15:15:30 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:15:30 :: PRIVATE_SHOP: Private shop 1 already created
Jun  5 15:15:33 :: [    21150] return 0/0/0 async 0/0/0

Açıkçası buraya kadar gelebilmek bile iyi bir ilerleme oldu. Değerli vaktiniz için @Erto @YunusEmreOfficial teşekkür ederim. Mysql kaynaklı veri gecikme bilgisi bile yeterince verimliydi benim için. Farklı bir çözüm bulmam gerekecek ama sizi de daha fazla yormak istemiyorum.
 
Evet, bu ekleme pazarın kapanmasını sağlıyor ama pazarda satın alınan itemin biriken parası yok oluyor. Pazar panel ui pakete tıklanınca açılıyor ama yeni bir item listeleme denendiğinde private_shop_manager.cpp içerisinde " You cannot build a personal shop at this moment. " hatasını basıyor.

private_shop_manager.cpp:
Genişlet Daralt Kopyala
void CPrivateShopManager::BuildPrivateShopResult(DWORD dwPID, TPrivateShop* pPrivateShopTable, bool bSuccess)
{
    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }

    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (!pOwner)
    {
        sys_err("Cannot find private shop owner with id %u", dwPID);
        return;
    }

    pOwner->ClosePrivateShopPanel(true);

    const auto& map_privateShopItem = pPrivateShop->GetItemContainer();
    for (const auto& kv : map_privateShopItem)
    {
        WORD wPos = kv.first;
        LPITEM pItem = kv.second;

        if (bSuccess)
        {
            pItem->SetSkipSave(true);

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop

            pItem->RemoveFromCharacter();
            pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, pItem->GetCell(), 255);

            pItem->SetCell(nullptr, wPos);
            pItem->BindPrivateShop(pPrivateShop);

            TPlayerPrivateShopItem t{};
            CopyItemData(pItem, t);

            pOwner->SetPrivateShopItem(t);

            char szHint[128 + 1]{};
            snprintf(szHint, sizeof(szHint), "%s x%u pos %u gold %lld", pItem->GetName(), pItem->GetCount(), t.wPos, t.TPrice.llGold);
            LogManager::Instance().ItemLog(pOwner, pItem, "PRIVATE SHOP BUILD CHECKIN", szHint);
        }
        else
        {
            pItem->BindPrivateShop(nullptr);
            pItem->SetCheckinTime(0);
            pItem->SetGoldPrice(0);
#ifdef WJ_PRIVATE_SHOP_CHEQUE
            pItem->SetChequePrice(0);
#endif

            pItem->Lock(false);//Darklovers_Fix_Offline_Shop
        }
    }

    if (!bSuccess)
    {
        DeletePrivateShop(dwPID);
        pOwner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You cannot build a personal shop at this moment. "));

        sys_err("Private shop building process stopped for player %u", dwPID);
        return;
    }

    pPrivateShop->Show(pPrivateShopTable->lX, pPrivateShopTable->lY, 0, pPrivateShopTable->lMapIndex);
    pOwner->SetPrivateShopTable(*pPrivateShopTable);

    LogManager::Instance().CharLog(pOwner, 0, "PRIVATE SHOP BUILT", "");

    sys_log(0, "%s PRIVATE_SHOP: SUCCESS Shop entity created", pPrivateShopTable->szOwnerName);
}
syslog:
Genişlet Daralt Kopyala
Jun  5 15:12:55 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:12:55 :: Re-creating private shop for owner 1
Jun  5 15:12:55 :: PRIVATE_SHOP: Added item 10000303 pos 22 vnum 30190 to private shop 1
Jun  5 15:12:55 :: PRIVATE_SHOP: Private shop 1 successfully created
Jun  5 15:12:55 :: PRIVATE_SHOP: Private shop 1 successfully built
Jun  5 15:12:58 :: [    19600] return 0/0/0 async 0/0/0
Jun  5 15:13:03 :: [    19650] return 0/0/0 async 0/0/0
Jun  5 15:13:03 :: PRIVATE_SHOP: Buy request forwarded to game for private shop 1 customer 3 item pos 22 item 30190 yang 100000 won 0
Jun  5 15:13:04 :: PRIVATE_SHOP: Item bought from private shop 1 pos 22 gold 100000 won 0 by pid 3
Jun  5 15:13:04 :: PRIVATE_SHOP: Despawning item empty private shop 1 by item sale
Jun  5 15:13:04 :: PRIVATE_SHOP: Sending despawn update to owner 1
Jun  5 15:13:08 :: [    19700] return 0/0/0 async 0/0/0
Jun  5 15:13:13 :: [    19750] return 0/0/0 async 0/0/0
Jun  5 15:13:18 :: [    19800] return 0/0/0 async 0/0/0
Jun  5 15:13:23 :: [    19850] return 0/0/0 async 0/0/0
Jun  5 15:13:28 :: [    19900] return 0/0/0 async 0/0/0
Jun  5 15:13:33 :: [    19950] return 0/0/0 async 0/0/0
Jun  5 15:13:38 :: [    20000] return 0/0/0 async 0/0/0
Jun  5 15:13:43 :: [    20050] return 0/0/0 async 0/0/0
Jun  5 15:13:48 :: [    20100] return 0/0/0 async 0/0/0
Jun  5 15:13:53 :: [    20150] return 0/0/0 async 0/0/0
Jun  5 15:13:58 :: [    20200] return 0/0/0 async 0/0/0
Jun  5 15:14:03 :: [    20250] return 0/0/0 async 0/0/0
Jun  5 15:14:08 :: [    20300] return 0/0/0 async 0/0/0
Jun  5 15:14:13 :: [    20350] return 0/0/0 async 0/0/0
Jun  5 15:14:18 :: [    20400] return 0/0/0 async 0/0/0
Jun  5 15:14:19 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:14:19 :: PRIVATE_SHOP: Private shop 1 already created
Jun  5 15:14:23 :: [    20450] return 0/0/0 async 0/0/0
Jun  5 15:14:28 :: [    20500] return 0/0/0 async 0/0/0
Jun  5 15:14:33 :: [    20550] return 0/0/0 async 0/0/0
Jun  5 15:14:38 :: [    20600] return 0/0/0 async 0/0/0
Jun  5 15:14:43 :: [    20650] return 0/0/0 async 0/0/0
Jun  5 15:14:48 :: [    20700] return 0/0/0 async 0/0/0
Jun  5 15:14:53 :: [    20750] return 0/0/0 async 0/0/0
Jun  5 15:14:58 :: [    20800] return 0/0/0 async 0/0/0
Jun  5 15:15:03 :: [    20850] return 0/0/0 async 0/0/0
Jun  5 15:15:08 :: [    20900] return 0/0/0 async 0/0/0
Jun  5 15:15:13 :: [    20950] return 0/0/0 async 0/0/0
Jun  5 15:15:18 :: [    21000] return 0/0/0 async 0/0/0
Jun  5 15:15:23 :: [    21050] return 0/0/0 async 0/0/0
Jun  5 15:15:28 :: [    21100] return 0/0/0 async 0/0/0
Jun  5 15:15:30 :: PRIVATE_SHOP: Building private shop 1
Jun  5 15:15:30 :: PRIVATE_SHOP: Private shop 1 already created
Jun  5 15:15:33 :: [    21150] return 0/0/0 async 0/0/0

Açıkçası buraya kadar gelebilmek bile iyi bir ilerleme oldu. Değerli vaktiniz için @Erto @YunusEmreOfficial teşekkür ederim. Mysql kaynaklı veri gecikme bilgisi bile yeterince verimliydi benim için. Farklı bir çözüm bulmam gerekecek ama sizi de daha fazla yormak istemiyorum.
Rica ederim, Çalışan bir files bulursan baştan sona baksan iyi olacak. Sanırım eksiği çok. Ancak loglara baktığımda konuda belirtilen hatanın giderildiğini görüyorum.
15:13:04 PRIVATE_SHOP: Despawning item empty private shop 1 by item sale
15:13:04 PRIVATE_SHOP: Sending despawn update to owner 1
Buda demek oluyorki para gözükmemesinin sebebi, dbde veya game tarafında hala GetPrivateShop(1) dönüyor olması.
private_shop_manager.cpp: 'de
C++:
Genişlet Daralt Kopyala
void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID)
Fonksiyonunu şu şekilde değiştirsene;
C++:
Genişlet Daralt Kopyala
void CPrivateShopManager::DespawnPrivateShop(DWORD dwPID)
{
    DWORD dwOwner = dwPID;

    LPPRIVATE_SHOP pPrivateShop = GetPrivateShop(dwPID);
    if (!pPrivateShop)
    {
        sys_err("Cannot find private shop with id %u", dwPID);
        return;
    }

    pPrivateShop->ChangeState(STATE_CLOSED);
    pPrivateShop->CleanShopViewers();

    LPCHARACTER pOwner = CHARACTER_MANAGER::Instance().FindByPID(dwPID);
    if (pOwner)
    {
        pOwner->SetPrivateShopTable(TPrivateShop{});
        pOwner->ClosePrivateShopPanel(true);
    }

    BYTE bSubHeader = PRIVATE_SHOP_GD_SUBHEADER_DESPAWN;

    db_clientdesc->DBPacketHeader(HEADER_GD_PRIVATE_SHOP, 0, sizeof(BYTE) + sizeof(DWORD));
    db_clientdesc->Packet(&bSubHeader, sizeof(BYTE));
    db_clientdesc->Packet(&dwOwner, sizeof(DWORD));

    sys_log(0, "%s PRIVATE_SHOP: Shop entity despawned", pPrivateShop->GetOwnerName().c_str());
    DeletePrivateShop(dwPID);
}

Bu seferki yaptığımız işlem,

1. STATE CLOSED (satış bitti)​

  • UI kapanır
  • owner state update

2. DESPAWN (entity kaldır)​

  • shop map’ten kalkar
  • viewer temizlenir

3. DELETE (RAM cleanup)​

  • en son yapılır
 
Sonitexin bile sorunlarını kabullendiği yüksek onlineda kullanmayın dediği bir offshopun peşinde niye koşarsınız be hocam.
Hocam valla pek bilgi sahibi değilim o konularda, forumda bakınırken en güncel bu takılmıştı gözüme fikir almak için bir konu daha açmıştım bir öneri gelmedi, denemekten zarar gelmez diyerekten başladım ben de. Sorunlu olduğu şüphesiz.
 
Hocam valla pek bilgi sahibi değilim o konularda, forumda bakınırken en güncel bu takılmıştı gözüme fikir almak için bir konu daha açmıştım bir öneri gelmedi, denemekten zarar gelmez diyerekten başladım ben de. Sorunlu olduğu şüphesiz.
Zamanında marty alt yapıya eklenmiş premium versiyonu kullan derim. Aktif olarak 2,5 senedir kullanıyorum dediğin hiçbir sıkıntıyı çekmedim.





pw; metin2.network@@@@Best
 
Son düzenleme:
Geri
Üst