Konu: Çözülemedi - Transmutation ve Private Shop Search sistemleri ile ilgili ufak bug
Problemin kaynağı:
Bug sunucu tarafında, CShop::BroadcastUpdateItem (source/server/game/src/shop.cpp) içerisinde yer alıyor:
TPacketGCShopUpdateItem pack2; // <- sıfırlanmıyor!
Özel dükkandan (ticaret aynası dahil) bir eşya satın alındığında, sunucu önce r_item.pkItem = NULL atamasını yapar ve ardından BroadcastUpdateItem(pos) fonksiyonunu çağırır. Bu fonksiyonun ilk koşul bloğu şu şekildedir:
if (m_pkPC && !m_itemVector[pos].pkItem)
pack2.item.vnum = 0; // sadece vnum sıfırlanıyor
Stack üzerindeki pack2 yapısı sıfırlanmadığı için dwTransmutationVnum dâhil olmak üzere diğer alanlarda çöp (garbage) bellek değerleri kalır. İstemci bu paketi SetItemData ile kopyalar ve uishop.py dosyasında shop.GetItemChangeLookVnum(idx) != 0 şartı sağlandığında ingame_convert_Mark.tga simgesini ekrana çizer. Pencereyi kapatıp açtığınızda ise SHOP_SUBHEADER_GC_START paketi doğru değerle (0) gönderilir ve simge kaybolur — bu da tam olarak yaşanan davranışı açıklar.
Çözümü:
shop.cpp dosyası içerisinde pack2 yapısını sıfırlayın:
Aynı dosyadaki Start() fonksiyonu da halihazırda bu yaklaşımı kullanmaktadır. Bu işlem, satılan eşya slotundaki dwTransmutationVnum ve diğer tüm başlatılmamış alanları temizler. Hem normal dükkan hem de ticaret aynası üzerinden yapılan satın alımlar bu fonksiyon üzerinden geçtiği için her iki durum da çözüme kavuşur. İşlemi tamamlamak için game projesini yeniden derlemeniz yeterlidir.
Örnek:
Problemin kaynağı:
Bug sunucu tarafında, CShop::BroadcastUpdateItem (source/server/game/src/shop.cpp) içerisinde yer alıyor:
TPacketGCShopUpdateItem pack2; // <- sıfırlanmıyor!
Özel dükkandan (ticaret aynası dahil) bir eşya satın alındığında, sunucu önce r_item.pkItem = NULL atamasını yapar ve ardından BroadcastUpdateItem(pos) fonksiyonunu çağırır. Bu fonksiyonun ilk koşul bloğu şu şekildedir:
if (m_pkPC && !m_itemVector[pos].pkItem)
pack2.item.vnum = 0; // sadece vnum sıfırlanıyor
Stack üzerindeki pack2 yapısı sıfırlanmadığı için dwTransmutationVnum dâhil olmak üzere diğer alanlarda çöp (garbage) bellek değerleri kalır. İstemci bu paketi SetItemData ile kopyalar ve uishop.py dosyasında shop.GetItemChangeLookVnum(idx) != 0 şartı sağlandığında ingame_convert_Mark.tga simgesini ekrana çizer. Pencereyi kapatıp açtığınızda ise SHOP_SUBHEADER_GC_START paketi doğru değerle (0) gönderilir ve simge kaybolur — bu da tam olarak yaşanan davranışı açıklar.
Çözümü:
shop.cpp dosyası içerisinde pack2 yapısını sıfırlayın:
C++:
TPacketGCShopUpdateItem pack2;
memset(&pack2, 0, sizeof(pack2));
Aynı dosyadaki Start() fonksiyonu da halihazırda bu yaklaşımı kullanmaktadır. Bu işlem, satılan eşya slotundaki dwTransmutationVnum ve diğer tüm başlatılmamış alanları temizler. Hem normal dükkan hem de ticaret aynası üzerinden yapılan satın alımlar bu fonksiyon üzerinden geçtiği için her iki durum da çözüme kavuşur. İşlemi tamamlamak için game projesini yeniden derlemeniz yeterlidir.
Örnek:
C++:
void CShop::BroadcastUpdateItem(BYTE pos)
{
TPacketGCShop pack;
TPacketGCShopUpdateItem pack2;
#if defined(ENABLE_TRANSMUTATION)
memset(&pack2, 0, sizeof(pack2));
#endif
TEMP_BUFFER buf;
pack.header = HEADER_GC_SHOP;
pack.subheader = SHOP_SUBHEADER_GC_UPDATE_ITEM;
pack.size = sizeof(pack) + sizeof(pack2);
pack2.pos = pos;
if (m_pkPC && !m_itemVector[pos].pkItem)
pack2.item.vnum = 0;
else
{
pack2.item.vnum = m_itemVector[pos].vnum;
if (m_itemVector[pos].pkItem)
{
thecore_memcpy(pack2.item.alSockets, m_itemVector[pos].pkItem->GetSockets(), sizeof(pack2.item.alSockets));
thecore_memcpy(pack2.item.aAttr, m_itemVector[pos].pkItem->GetAttributes(), sizeof(pack2.item.aAttr));
#if defined(ENABLE_TRANSMUTATION)
pack2.item.dwTransmutationVnum = m_itemVector[pos].pkItem->GetTransmutationVnum();
#endif
}
else
{
memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
#if defined(ENABLE_TRANSMUTATION)
pack2.item.dwTransmutationVnum = 0;
#endif
}
}
pack2.item.price = m_itemVector[pos].price;
#ifdef ENABLE_CHEQUE_SYSTEM
pack2.item.cheque = m_itemVector[pos].cheque;
#endif
pack2.item.count = m_itemVector[pos].count;
buf.write(&pack, sizeof(pack));
buf.write(&pack2, sizeof(pack2));
Broadcast(buf.read_peek(), buf.size());
}