C++] DB + NoTXT! İtem Proto Sorununa Son

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

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
Merhaba filezilla db item proto sorununu anlatıcam bugün yani artık navicattan ekliceksiniz herşeyi :) metin2 devden alıntıdır. yapamayanlar konu altına yazsın

geliyor...

1.) db/src/Main.cpp Açılır

bool'un altına şunu ekleyin

Kod:
// NOTXT_STARTUP_BEGINBOOL g_noTXT = false;[/FONT] // NOTXT_STARTUP_END
son hali

bM7uA.png


ve sonra int iDisableHotBackup arayın

altına ekleyin

Kod:
// NOTXT_STARTUP_BEGINint iNoTXT;if (CConfig::instance().GetValue("NO_TXT", &iNoTXT)){    if (iNoTXT)    {        sys_log(0, "CONFIG: NO_TXT");        g_noTXT = true;    }} // NOTXT_STARTUP_END
son hali

bM7BK.png



kaydedip çıkın.

db/src/ClientManager.h açılır

Kod:
1 bool        InitializeMobTable();2 bool        InitializeItemTable(); 1 // NOTXT_STARTUP_BEGIN2 bool        InitializeMobTableTXT();3 bool        InitializeItemTableTXT();4 bool        InitializeMobTableSQL();5 bool        InitializeItemTableSQL(); 6 // NOTXT_STARTUP_END
son hali

bM7GT.png


böyle değiştirilir

kaydedip çıkın


db/src/ClientManagerBoot.cpp açın

extern altına şunu ekleyin

Kod:
// NOTXT_STARTUP_BEGINextern int g_noTXT; // NOTXT_STARTUP_END
son hali

bM7Jt.png


şunu arayın

Kod:
1 bool CClientManager::InitializeMobTable() 1 bool CClientManager::InitializeMobTableTXT()
son hali

bMbDB.png


bMbFn.png


değiştirin.

Ve Tekrar

bool CClientManager::InitializeTables() arayın

Kod:
if (!InitializeMobTable()){    sys_err("InitializeMobTable FAILED");    return false;}if (!MirrorMobTableIntoDB()){    sys_err("MirrorMobTableIntoDB FAILED");    return false; } if (!InitializeItemTable()){    sys_err("InitializeItemTable FAILED");    return false; } if (!MirrorItemTableIntoDB()){    sys_err("MirrorItemTableIntoDB FAILED");    return false; } // NOTXT_STARTUP_BEGINif (g_noTXT) // item and mob proto{    if (!InitializeMobTableSQL())    {        sys_err("InitializeMobTableSQL FAILED");        return false;    }    if (!InitializeItemTableSQL())    {        sys_err("InitializeItemTableSQL FAILED");        return false;    }}else{    if (!InitializeMobTableTXT())    {        sys_err("InitializeMobTableTXT FAILED");        return false;    }     if (!MirrorMobTableIntoDB())    {        sys_err("MirrorMobTableIntoDB FAILED");        return false;    }     if (!InitializeItemTableTXT())    {        sys_err("InitializeItemTableTXT FAILED");        return false;    }     if (!MirrorItemTableIntoDB())    {        sys_err("MirrorItemTableIntoDB FAILED");        return false;    }} // NOTXT_STARTUP_END

değiştirilir

Ve ClientManagerBoot.cpp'nin en altına

şunu ekleyin

Kod:
// NOTXT_STARTUP_BEGINbool CClientManager::InitializeMobTableSQL(){    char query[4096];    snprintf(query, sizeof(query),        "SELECT vnum, name, %s, type, rank, battle_type, level, "        "size+0, ai_flag+0, setRaceFlag+0, setImmuneFlag+0, "        "on_click, empire, drop_item, resurrection_vnum, folder, "        "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, "        "gold_min, gold_max, def, attack_speed, move_speed, "        "aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, "        "enchant_curse, enchant_slow, enchant_poison, enchant_stun, enchant_critical, enchant_penetrate, "        "resist_sword, resist_twohand, resist_dagger, resist_bell, resist_fan, resist_bow, "        "resist_fire, resist_elect, resist_magic, resist_wind, resist_poison, "        "dam_multiply, summon, drain_sp, "        "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2,"        "skill_vnum3, skill_level3, skill_vnum4, skill_level4 , sp_berserk, sp_stoneskin, "        "sp_godspeed, sp_deathblow, sp_revive "        "FROM mob_proto%s ORDER BY vnum",        g_stLocaleNameColumn.c_str(), GetTablePostfix());     std::auto_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));    SQLResult * pRes = pkMsg->Get();     if (!pRes->uiNumRows)    {        sys_err("Could not load mob_proto. No results!");        return false;    }     sys_log(0, "MOB_PROTO loading...");     if (!m_vec_mobTable.empty())    {        sys_log(0, "RELOAD: mob_proto");        m_vec_mobTable.clear();    }     m_vec_mobTable.resize(pRes->uiNumRows);    memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size());    TMobTable * mob_table = &m_vec_mobTable[0];     MYSQL_ROW data;    int col;    while ((data = mysql_fetch_row(pRes->pSQLResult)))    {        col = 0;        str_to_number(mob_table->dwVnum, data[col++]);        strlcpy(mob_table->szName, data[col++], sizeof(mob_table->szName));        strlcpy(mob_table->szLocaleName, data[col++], sizeof(mob_table->szLocaleName));        str_to_number(mob_table->bType, data[col++]);        str_to_number(mob_table->bRank, data[col++]);        str_to_number(mob_table->bBattleType, data[col++]);        str_to_number(mob_table->bLevel, data[col++]);        str_to_number(mob_table->bSize, data[col++]);        str_to_number(mob_table->dwAIFlag, data[col++]);        str_to_number(mob_table->dwRaceFlag, data[col++]);        str_to_number(mob_table->dwImmuneFlag, data[col++]);        str_to_number(mob_table->bOnClickType, data[col++]);        str_to_number(mob_table->bEmpire, data[col++]);        str_to_number(mob_table->dwDropItemVnum, data[col++]);        str_to_number(mob_table->dwResurrectionVnum, data[col++]);        strlcpy(mob_table->szFolder, data[col++], sizeof(mob_table->szFolder));        str_to_number(mob_table->bStr, data[col++]);        str_to_number(mob_table->bDex, data[col++]);        str_to_number(mob_table->bCon, data[col++]);        str_to_number(mob_table->bInt, data[col++]);        str_to_number(mob_table->dwDamageRange[0], data[col++]);        str_to_number(mob_table->dwDamageRange[1], data[col++]);        str_to_number(mob_table->dwMaxHP, data[col++]);        str_to_number(mob_table->bRegenCycle, data[col++]);        str_to_number(mob_table->bRegenPercent, data[col++]);        str_to_number(mob_table->dwExp, data[col++]);        str_to_number(mob_table->dwGoldMin, data[col++]);        str_to_number(mob_table->dwGoldMax, data[col++]);        str_to_number(mob_table->wDef, data[col++]);        str_to_number(mob_table->sAttackSpeed, data[col++]);        str_to_number(mob_table->sMovingSpeed, data[col++]);        str_to_number(mob_table->bAggresiveHPPct, data[col++]);        str_to_number(mob_table->wAggressiveSight, data[col++]);        str_to_number(mob_table->wAttackRange, data[col++]);        str_to_number(mob_table->dwPolymorphItemVnum, data[col++]);         int i;        for (i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i)            str_to_number(mob_table->cEnchants[i], data[col++]);         for (i = 0; i < MOB_RESISTS_MAX_NUM; ++i)            str_to_number(mob_table->cResists[i], data[col++]);         str_to_number(mob_table->fDamMultiply, data[col++]);        str_to_number(mob_table->dwSummonVnum, data[col++]);        str_to_number(mob_table->dwDrainSP, data[col++]);         for (i = 0; i < MOB_SKILL_MAX_NUM; ++i)        {            str_to_number(mob_table->Skills[i].dwVnum, data[col++]);            str_to_number(mob_table->Skills[i].bLevel, data[col++]);        }         str_to_number(mob_table->bBerserkPoint, data[col++]);        str_to_number(mob_table->bStoneSkinPoint, data[col++]);        str_to_number(mob_table->bGodSpeedPoint, data[col++]);        str_to_number(mob_table->bDeathBlowPoint, data[col++]);        str_to_number(mob_table->bRevivePoint, data[col++]);         sys_log(1, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire);        ++mob_table;    }     sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum());    sys_log(0, "CClientManager::InitializeMobTable:: %d mobs loaded.\n", m_vec_mobTable.size());    return true;} bool CClientManager::InitializeItemTableSQL(){    char query[4096];    snprintf(query, sizeof(query),        "SELECT vnum, vnum_range, name, %s, type, subtype, gold, shop_buy_price, weight, size, flag, wearflag, "        "antiflag, immuneflag+0, refined_vnum, refine_set, magic_pct, socket_pct, addon_type, "        "limittype0, limitvalue0, limittype1, limitvalue1, "        "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, "        "value0, value1, value2, value3, value4, value5 "        "FROM item_proto%s ORDER BY vnum",        g_stLocaleNameColumn.c_str(), GetTablePostfix());     std::auto_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));    SQLResult * pRes = pkMsg->Get();     if (!pRes->uiNumRows)    {        sys_err("Could not load item_proto. No results!");        return false;    }     sys_log(0, "ITEM_PROTO loading...");     if (!m_vec_itemTable.empty())    {        sys_log(0, "RELOAD: item_proto");        m_vec_itemTable.clear();        m_map_itemTableByVnum.clear();    }     m_vec_itemTable.resize(pRes->uiNumRows);    memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size());    TItemTable * item_table = &m_vec_itemTable[0];     MYSQL_ROW data;    int col;     while ((data = mysql_fetch_row(pRes->pSQLResult)))    {        col = 0;         str_to_number(item_table->dwVnum, data[col++]);        str_to_number(item_table->dwVnumRange, data[col++]);        strlcpy(item_table->szName, data[col++], sizeof(item_table->szName));        strlcpy(item_table->szLocaleName, data[col++], sizeof(item_table->szLocaleName));        str_to_number(item_table->bType, data[col++]);        str_to_number(item_table->bSubType, data[col++]);        str_to_number(item_table->dwGold, data[col++]);        str_to_number(item_table->dwShopBuyPrice, data[col++]);        str_to_number(item_table->bWeight, data[col++]);        str_to_number(item_table->bSize, data[col++]);        str_to_number(item_table->dwFlags, data[col++]);        str_to_number(item_table->dwWearFlags, data[col++]);        str_to_number(item_table->dwAntiFlags, data[col++]);        str_to_number(item_table->dwImmuneFlag, data[col++]);        str_to_number(item_table->dwRefinedVnum, data[col++]);        str_to_number(item_table->wRefineSet, data[col++]);        str_to_number(item_table->bAlterToMagicItemPct, data[col++]);        str_to_number(item_table->bGainSocketPct, data[col++]);        str_to_number(item_table->sAddonType, data[col++]);         item_table->cLimitRealTimeFirstUseIndex = -1;        item_table->cLimitTimerBasedOnWearIndex = -1;         int i;        for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)        {            str_to_number(item_table->aLimits[i].bType, data[col++]);            str_to_number(item_table->aLimits[i].lValue, data[col++]);             if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits[i].bType)                item_table->cLimitRealTimeFirstUseIndex = (char)i;             if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits[i].bType)                item_table->cLimitTimerBasedOnWearIndex = (char)i;        }         for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i)        {            str_to_number(item_table->aApplies[i].bType, data[col++]);            str_to_number(item_table->aApplies[i].lValue, data[col++]);        }         for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i)            str_to_number(item_table->alValues[i], data[col++]);         sys_log(1, "ITEM: #%-5lu %-24s %-24s VAL: %ld %ld %ld %ld %ld %ld WEAR %lu ANTI %lu IMMUNE %lu REFINE %lu REFINE_SET %u MAGIC_PCT %u",                item_table->dwVnum,item_table->szName,item_table->szLocaleName,                item_table->alValues[0],item_table->alValues[1],item_table->alValues[2],                item_table->alValues[3],item_table->alValues[4],item_table->alValues[5],                item_table->dwWearFlags,item_table->dwAntiFlags,item_table->dwImmuneFlag,                item_table->dwRefinedVnum,item_table->wRefineSet,item_table->bAlterToMagicItemPct);         m_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::value_type(item_table->dwVnum, item_table));        ++item_table;    }     sort(m_vec_itemTable.begin(), m_vec_itemTable.end(), FCompareVnum());    sys_log(0, "CClientManager::InitializeMobTable:: %d items loaded.\n", m_vec_itemTable.size());    return true;}// NOTXT_STARTUP_END


Yeni İtem_Proto.sql

Kod:
DROP TABLE IF EXISTS `item_proto`;CREATE TABLE `item_proto` (  `vnum` int(11) unsigned NOT NULL DEFAULT '0',  `vnum_range` int(11) unsigned NOT NULL DEFAULT '0',  `name` varbinary(200) NOT NULL DEFAULT 'Noname                  ',  `locale_name` varbinary(24) NOT NULL DEFAULT 'Noname                  ',  `type` tinyint(2) NOT NULL DEFAULT '0',  `subtype` tinyint(2) NOT NULL DEFAULT '0',  `weight` tinyint(3) DEFAULT '0',  `size` tinyint(3) DEFAULT '0',  `antiflag` int(11) DEFAULT '0',  `flag` int(11) DEFAULT '0',  `wearflag` int(11) DEFAULT '0',  `immuneflag` set('PARA','CURSE','STUN','SLEEP','SLOW','POISON','TERROR') CHARACTER SET big5 NOT NULL DEFAULT '',  `gold` int(11) DEFAULT '0',  `shop_buy_price` int(10) unsigned NOT NULL DEFAULT '0',  `refined_vnum` int(10) unsigned NOT NULL DEFAULT '0',  `refine_set` smallint(11) unsigned NOT NULL DEFAULT '0',  `refine_set2` smallint(5) unsigned NOT NULL DEFAULT '0',  `magic_pct` tinyint(4) NOT NULL DEFAULT '0',  `limittype0` tinyint(4) DEFAULT '0',  `limitvalue0` int(11) DEFAULT '0',  `limittype1` tinyint(4) DEFAULT '0',  `limitvalue1` int(11) DEFAULT '0',  `applytype0` tinyint(4) DEFAULT '0',  `applyvalue0` int(11) DEFAULT '0',  `applytype1` tinyint(4) DEFAULT '0',  `applyvalue1` int(11) DEFAULT '0',  `applytype2` tinyint(4) DEFAULT '0',  `applyvalue2` int(11) DEFAULT '0',  `value0` int(11) DEFAULT '0',  `value1` int(11) DEFAULT '0',  `value2` int(11) DEFAULT '0',  `value3` int(11) DEFAULT '0',  `value4` int(11) DEFAULT '0',  `value5` int(11) DEFAULT '0',  `socket0` tinyint(4) DEFAULT '-1',  `socket1` tinyint(4) DEFAULT '-1',  `socket2` tinyint(4) DEFAULT '-1',  `socket3` tinyint(4) DEFAULT '-1',  `socket4` tinyint(4) DEFAULT '-1',  `socket5` tinyint(4) DEFAULT '-1',  `specular` tinyint(4) NOT NULL DEFAULT '0',  `socket_pct` tinyint(4) NOT NULL DEFAULT '0',  `addon_type` smallint(6) NOT NULL DEFAULT '0',  PRIMARY KEY (`vnum`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin;



Kodlar Karıştı Bekleyin
C++ ile Metin2 DB + NoTXT Item Proto Sorununa Kesin ve Etkili Çözüm

Metin2 özel sunucularında DB ve NoTXT item proto sistemlerinde yaşanan sorunlar, özellikle C++ tabanlı sistemlerde geliştirme yapan geliştiriciler için zaman zaman büyük baş ağrısına dönüşebilir. Bu yazıda, Metin2 lobby ortamında karşılaşılan bu problemi kökten çözecek bir yaklaşımı ele alacağız.

Problemin Temeli

Metin2 özel sunucu geliştirme süreçlerinde, eşyaların (item) veritabanı (DB) üzerinden yönetilmesi ve NoTXT sistemler ile dosya tabanlı olarak aktarılması arasında bir uyumsuzluk yaşanabilir. Bu durum genellikle, item_proto tablosundaki verilerin doğru şekilde okunmaması ya da item_proto.txt dosyasındaki tanımların DB ile senkronize edilememesiyle oluşur. Özellikle C++ tabanlı kaynak kod üzerinde yapılan değişikliklerde, DB ile TXT dosyaları arasında bir fark olursa, oyun içi itemlerin eksik ya da yanlış yüklenmesi gibi sorunlar meydana gelir.

Ortaya Çıkan Sorunlar

- Item Proto tablosunda tanımlı eşyaların oyun içine düşmemesi
- Oyuncuların item kullanamaması veya itemin görünmemesi
- Client ve server senkronizasyonunda kopmalar
- Item ID'lerde çakışmalar

C++ ile DB ve NoTXT Uyumlu Sistem Nasıl Kurulur?

Bu sorunu çözmek için öncelikle item_proto verilerinin hem DB'de hem de NoTXT yapısında aynı yapıya sahip olması gerekir. Bunun için şu adımları izleyebilirsiniz:

1. Item Proto Formatını Belirleme:
Her item için DB ve TXT dosyasında aynı alanların tanımlı olduğundan emin olun. Örneğin: item_vnum, name, type, size, gold, shop_buy_price gibi alanlar.

2. Game Sunucusunu Güncelle:
C++ kaynak kodda, item_proto.txt dosyasının okunması sırasında DB'deki karşılıklarıyla senkronize edilecek şekilde bir kontrol mekanizması kurun. Bu işlem sırasında MySQL bağlantısı ile veritabanı sorguları yapılmaktadır.

3. Load_ItemProto Fonksiyonunu Revize Etme:
Game sunucu başlatılırken çalışan Load_ItemProto() fonksiyonu, artık hem TXT dosyasını hem de DB'deki verileri kontrol etmelidir. Eğer DB'de item varsa, TXT dosyasındaki verilerle çakışmaması için bir filtreleme yapılmalıdır.

Python ve C++ Entegrasyonu

Metin2 özel sunucularında bazı geliştiriciler, Python kullanarak UIscript ve py root dosyaları aracılığıyla item verilerini daha kolay yönetebilirler. Ancak bu, DB ile TXT senkronizasyonunu doğrudan etkilemez; sadece istemci tarafında item bilgilerinin doğru gösterilmesini sağlar. Yine de bu yapı, C++ backend ile uyumlu çalışacak şekilde tasarlanmalıdır.

Martysama ve Metin2 Development Araçları

Bazı geliştiriciler, Martysama gibi gelişmiş araçlar sayesinde item_proto verilerini daha hızlı ve hatasız yönetebilirler. Bu tür araçlar, hem DB hem de TXT dosyalarını aynı anda güncelleyebilen otomatik sistemler sunar. Bu da NoTXT ve DB uyumu için büyük bir avantajdır.

Sonuç

Metin2 özel sunucularında DB ile NoTXT sistemleri arasındaki uyumsuzluklar, C++ seviyesinde dikkatli planlama ile çözülebilir. Doğru yapılandırmalar ve senkronizasyon işlemleri, oyun içinde itemlerin eksiksiz ve doğru şekilde yüklenmesini sağlar. Metin2 Lobby ortamında bu konuda yapılan çalışmalar, sunucu kalitesini ciddi anlamda artırmaktadır.


Definitive and Effective Solution to DB + NoTXT Item Proto Issues with C++

Issues arising from DB and NoTXT item proto systems in Metin2 private servers can sometimes turn into major headaches for developers working on C++-based systems. In this article, we will address an approach that tackles this problem at its root within the Metin2 lobby environment.

Root of the Problem

During the development process of Metin2 private servers, mismatches may occur between managing items (items) via database (DB) and transferring them via file-based NoTXT systems. This issue typically arises when the data in the item_proto table is not read correctly or the definitions in the item_proto.txt file cannot be synchronized with the DB. Particularly in C++-based source code modifications, if there is a discrepancy between DB and TXT files, issues such as items not loading properly into the game may occur.

Issues That Arise

- Items defined in the item_proto table not appearing in-game
- Players unable to use items or items not showing up
- Disconnections in client-server synchronization
- Conflicts in item IDs

How to Set Up a DB and NoTXT Compatible System with C++

To solve this problem, first ensure that the item_proto data has the same structure in both the DB and NoTXT system. You can follow these steps:

1. Define Item Proto Format:
Ensure that the same fields are defined in both the DB and TXT files for each item. For example: item_vnum, name, type, size, gold, shop_buy_price, etc.

2. Update the Game Server:
In the C++ source code, a control mechanism should be set up so that while reading the item_proto.txt file, it is synchronized with the corresponding entries in the DB. During this process, database queries are performed using MySQL.

3. Revise the Load_ItemProto Function:
The Load_ItemProto() function, which runs when the game server starts, should now check both the TXT file and the data in the DB. If an item exists in the DB, filtering must be done to avoid conflicts with the data in the TXT file.

Python and C++ Integration

Some developers in Metin2 private servers can manage item data more easily using Python through UIscript and py root files. However, this does not directly affect DB and TXT synchronization; it only ensures correct display of item information on the client side. Still, this structure must be designed to work seamlessly with the C++ backend.

Martysama and Metin2 Development Tools

Some developers manage item_proto data faster and more accurately using advanced tools like Martysama. These tools offer automatic systems that update both DB and TXT files simultaneously, providing a significant advantage for NoTXT and DB compatibility.

Conclusion

Incompatibilities between DB and NoTXT systems in Metin2 private servers can be resolved with careful planning at the C++ level. Proper configurations and synchronization processes ensure that items load completely and correctly in-game. Work done on this subject within the Metin2 Lobby environment significantly enhances server quality.
 

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

Benzer konular

Geri
Üst Alt