[C++] Offline Shop Item Kaybolması Fixi

  • Konbuyu başlatan Konbuyu başlatan Admin
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 0
  • Görüntüleme Görüntüleme 52

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
konudaki pazar sistemindeki:

Pazarı kurduk ve oyunu kapattık. Pazarın süresi oyun kapalı iken dolarsa ,mesela 6 saatlik pazar kurup oyunu 7 saat sonra açarsak o pazardaki itemler offline_shop window'da kalır. Oyuncu tarafından geri alınamaz. Yeni kurduğu pazardaki itemlerin pos'ları bu arada kalan itemler ile çakışır ise tekrar itemleri kaybolur oyuncuların.(Posları çakışan itemlar).

Neyse daha fazla uzatmadan çözüme geçelim;



game/shop.cpp açılır

//Aratılır


Kod:
if (dwNowTimestamp > dwExpireDate){         sys_err("Create Offlineshop fail %s:%u cannot created. shop's time expired", table->szName, table->dwPID);         return false;     }

//Değiştirilir

Kod:
if (dwNowTimestamp > dwExpireDate){      sys_err("[%d] id'li [%s] isimli arkadasin pazarinin suresi doldu.",table->dwPID,table->szName);         sys_err("ve bu yuzden ->RemoveExpiredShop calistirildi.");         RemoveExpiredShop(table->dwAID,table->dwPID);         //return false;     }

İsterseniz bu kadar uzatmayıp

Kod:
RemoveExpiredShop(table->dwAID,table->dwPID);


yerine

Kod:
Remove();

yazarakta çözümleyebilirsiniz. Bu offline_shop'un normal kapatma fonksiyonu ama derseniz ki ben farklı işler yapacam pazar ordan kapanırken bilmemne diye bunları da uygulayın;

game/shop.h açılır

//Aratılır
Kod:
void    Remove();

//Altına eklenir
Kod:
void    RemoveExpiredShop(DWORD hID,DWORD oID);

game/shop.cpp açılır

//Aratılır

Kod:
void CShop::Remove()

Üstüne eklenir;

Kod:
void CShop::RemoveExpiredShop(DWORD hID,DWORD oID){     sys_err("[%d] numarali ID'li oyuncunun pazarinin suresi dolmus kapatiliyor.",oID);     m_bIsLocked = true;     TOfflineShopTable p;     memset(&p, 0, sizeof(p));     p.dwAID = hID;     p.dwPID = oID;     p.dwX = m_pkPC->GetX();     p.dwY = m_pkPC->GetY();     p.dwMapIndex = m_pkPC->GetMapIndex();     p.dwChannel = g_bChannel;     p.ullMoney = m_Money;     strlcpy(p.szSign, m_pkPC->GetShopSign().c_str(), sizeof(p.szSign));     //for (int i = 0; i < 80; ++i){     for (int i = 0; i < SHOP_HOST_ITEM_MAX_NUM; ++i){         SHOP_ITEM& item = m_itemVector[i];         if (item.pkItem == NULL){continue;}         p.items2[i] = item.itemid;         p.price[i] = item.price;         p.cheque_price[i]=item.cheque_price;         /**/         item.pkItem->SetWindow(SAFEBOX_OFFLINE_SHOP);         ITEM_MANAGER::instance().SaveSingleItem(item.pkItem);         item.pkItem->SetSkipSave(true);         M2_DESTROY_ITEM(item.pkItem);         memset(&item, 0, sizeof(item));     }     sys_err("[%d] numarali ID'li oyuncunun pazari kapatildi.",oID);     db_clientdesc->DBPacket(HEADER_GD_OFFLINE_SHOP_REMOVE, 0, &p, sizeof(p)); }


Metin2 Offline Shop Sistemi ve C++ ile Item Kaybolması Sorununa Kalıcı Çözüm

Metin2 özel sunucularında en çok tercih edilen sistemlerden birisi olan Offline Shop sistemi, oyuncuların internet bağlantısı olmadan da eşyalarını satışa sunabilmelerini sağlar. Ancak bu sistemde zaman zaman karşılaşılan item kaybolması sorunu, hem oyuncular hem de sunucu sahipleri için büyük bir problem haline gelebilir. Bu yazıda, C++ tabanlı Game Server üzerinde çalışan bir offline shop sisteminde meydana gelen item kaybolması sorununun kökenine inip, kalıcı bir fix çözümü sunacağız.

Offline Shop Sisteminin Genel Yapısı

Metin2 özel sunucularında offline shop sistemi genellikle Python arayüzleri (uiscript) ve C++ backend işlemleri ile entegre çalışır. Oyuncu bir eşyayı mağazasına koyduğunda, bu eşya veritabanında belirli bir tabloya kayıt edilir ve sunucu kapalıyken dahi bu veriler aktif olarak kalır. Ancak bazı durumlarda, sistemde eksiklikler veya hatalı kontrol mekanizmaları sebebiyle eşyalar silinebilir ya da veritabanından yanlışlıkla kaldırılabilir.

Item Kaybolmasının Olası Sebepleri

1. SQL sorgularında eksik WHERE koşulu kullanımı.
2. Item silme fonksiyonunun yanlışlıkla çağrılması.
3. Offline kullanıcı verilerinin senkronizasyonunda meydana gelen hata.
4. Server restart sırasında veri tutarsızlığı.

C++ Kaynak Kodunda Fix Uygulaması

Aşağıda, item kaybolmasını engellemek amacıyla game/src dizinindeki char_item.cpp dosyasında yapılması gereken temel değişiklikler yer almaktadır:

Önceki Hali:
Kod:
void CHARACTER::RemoveFromShop(TPacketGCShopItemSet* p) {[BR][/BR]    // Eşya doğrudan siliniyor[BR][/BR]    ITEM_MANAGER::instance().DestroyItem(p->vnum);[BR][/BR]}

Düzeltilmiş Hali:
Kod:
void CHARACTER::RemoveFromShop(TPacketGCShopItemSet* p) {[BR][/BR]    LPITEM item = ITEM_MANAGER::instance().FindItem(p->vnum);[BR][/BR]    if (!item) return;[BR][/BR][BR][/BR]    if (item->GetOwner() != this && !IsOfflineShop()) {[BR][/BR]        sys_log(0, "Item remove attempt blocked for character %s", GetName());[BR][/BR]        return;[BR][/BR]    }[BR][/BR][BR][/BR]    ITEM_MANAGER::instance().DestroyItem(item->GetID());[BR][/BR]}


Bu kod parçası sayesinde, bir eşyanın sahibi değilse silinmesi engellenir ve loglama yapılarak potansiyel hatalar takip edilebilir.

Ek Güvenlik Kontrolleri

Ayrıca, auth server ile game server arasında veri senkronizasyonu için özel packet tanımları yapılmalıdır. Örneğin, TPacketCGUpdateOfflineShop gibi özel paketlerle eşya sahipliği kontrolü yapılmalı ve sahte işlemler engellenmelidir.

Veritabanı Tarafında Gerekli Önlemler

MySQL tarafında, offline_shop_items tablosunda foreign key tanımlamaları ve trigger kontrolleri ile silinen eşyaların loglanması sağlanabilir. Bu sayede, bir hata durumunda geri izleme yapmak mümkün olur.

Sonuç

Metin2 özel sunucularında offline shop sisteminin güvenli ve stabil çalışması için hem client hem de server tarafında titizlikle hazırlanmış kodlar gereklidir. Özellikle C++ tabanlı source üzerinde yapılan kontroller, item kaybolması gibi ciddi problemleri önleyebilir. Bu fix ile kullanıcılarınızın eşyalarını güvende hissetmesini sağlayabilir ve sunucunuzun itibarını artırabilirsiniz.

Metin2 Lobby olarak, bu tür sistemsel çözümleri siz geliştiricilere sunmaya devam ediyoruz.


Metin2 Offline Shop System and Permanent Fix for Item Disappearance with C++

The Offline Shop system is one of the most preferred features on Metin2 private servers, allowing players to sell items even without an active internet connection. However, occasional item disappearance issues can become a major problem for both players and server owners. In this article, we will investigate the root cause of the item loss issue in an offline shop system running on a C++-based Game Server and provide a permanent fix solution.

General Structure of the Offline Shop System

On Metin2 private servers, the offline shop system typically integrates Python interfaces (uiscript) with C++ backend processes. When a player puts an item in their store, that item is registered in a specific database table and remains active even while the server is offline. However, due to certain deficiencies or incorrect control mechanisms, items may sometimes be deleted or incorrectly removed from the database.

Possible Causes of Item Loss

1. Missing WHERE clause usage in SQL queries.
2. Incorrect invocation of the item deletion function.
3. Errors during synchronization of offline user data.
4. Data inconsistency during server restart.

Applying Fix in C++ Source Code

Below are the essential changes required in the char_item.cpp file located in game/src to prevent item loss:

Previous Version:
Kod:
void CHARACTER::RemoveFromShop(TPacketGCShopItemSet* p) {[BR][/BR]    // Item is deleted directly[BR][/BR]    ITEM_MANAGER::instance().DestroyItem(p->vnum);[BR][/BR]}

Fixed Version:
Kod:
void CHARACTER::RemoveFromShop(TPacketGCShopItemSet* p) {[BR][/BR]    LPITEM item = ITEM_MANAGER::instance().FindItem(p->vnum);[BR][/BR]    if (!item) return;[BR][/BR][BR][/BR]    if (item->GetOwner() != this && !IsOfflineShop()) {[BR][/BR]        sys_log(0, "Item remove attempt blocked for character %s", GetName());[BR][/BR]        return;[BR][/BR]    }[BR][/BR][BR][/BR]    ITEM_MANAGER::instance().DestroyItem(item->GetID());[BR][/BR]}


Thanks to this code snippet, an item will not be deleted if its owner does not match the caller, and logging ensures potential errors can be tracked.

Additional Security Checks

Furthermore, custom packets should be defined between the auth server and game server to synchronize data. For instance, custom packets like TPacketCGUpdateOfflineShop can be used to verify item ownership and prevent fraudulent transactions.

Necessary Measures on Database Side

In MySQL, foreign key constraints and triggers in the offline_shop_items table can ensure logged removals of items. This way, in case of an error, trace-back operations become possible.

Conclusion

For the secure and stable operation of the offline shop system in Metin2 private servers, careful coding on both client and server sides is necessary. Especially checks made on C++-based source can prevent serious issues like item loss. With this fix, you can ensure your users feel safe about their items and increase your server's reputation.

Metin2 Lobby continues to provide such systematic solutions to developers.
 

Şuan Bu Konuyu Görüntüleyen Kullanıcılar (Toplam : 0, Üye : 0, Misafir : 0)

Benzer konular

Geri
Üst Alt