BK Envanteri Cube Fix - Metin2Hizmet Farkı İle

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

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
Uzatmadan fixe geçelim. Altta vereceğim işlemleri yaptığınız taktirde cube sorunu tamamen kalkacaktır.

Gerekli dosyalar: cmd_general.cpp - cube.cpp - cube.h
Not: Kodlar karışık geldiyse int olarak geçen tüm satırları uint olarak değiştireceksiniz cube.cpp ve cube.h içindeki!
Kod:
ACMD(do_cube)[/CENTER] {     if (!ch->CanDoCube())         return;     dev_log(LOG_DEB0, "CUBE COMMAND <%s>: %s", ch->GetName(), argument);     //www.metin2hizmet.com Cube Fixed     UINT cube_index = 0, inven_index = 0;     //www.metin2hizmet.com Cube Fixed     const char *line;     char arg1[256], arg2[256], arg3[256];     line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));     one_argument(line, arg3, sizeof(arg3));     if (0 == arg1[0])     {         // print usage         ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube close");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube add <inveltory_index>");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube delete <cube_index>");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube list");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube cancel");         ch->ChatPacket(CHAT_TYPE_INFO, "       cube make [all]");         return;     }     const std::string& strArg1 = std::string(arg1);          if (strArg1 == "r_info")     {         if (0 == arg2[0])             Cube_request_result_list(ch);         else         {             if (isdigit(*arg2))             {                 //www.metin2hizmet.com Cube Fixed                 UINT listIndex = 0, requestCount = 1;                 //www.metin2hizmet.com Cube Fixed                 str_to_number(listIndex, arg2);                 if (0 != arg3[0] && isdigit(*arg3))                     str_to_number(requestCount, arg3);                 Cube_request_material_info(ch, listIndex, requestCount);             }         }         return;     }     switch (LOWER(arg1[0]))     {         case 'o':    // open             Cube_open(ch);             break;         case 'c':    // close             Cube_close(ch);             break;         case 'l':    // list             Cube_show_list(ch);             break;         case 'a':    // add cue_index inven_index             {                 if (0 == arg2[0] || !isdigit(*arg2) ||                     0 == arg3[0] || !isdigit(*arg3))                     return;                 str_to_number(cube_index, arg2);                 str_to_number(inven_index, arg3);                 Cube_add_item (ch, cube_index, inven_index);             }             break;         case 'd':    // delete             {                 if (0 == arg2[0] || !isdigit(*arg2))                     return;                 str_to_number(cube_index, arg2);                 Cube_delete_item (ch, cube_index);             }             break;         case 'm':    // make             if (0 != arg2[0])             {                 while (true == Cube_make(ch))                     dev_log (LOG_DEB0, "cube make success");             }             else                 Cube_make(ch);             break;         default:             return;     } }
Kod:
Bulunacak satırlar; void Cube_add_item (LPCHARACTER ch, int cube_index, int inven_index); void Cube_delete_item(LPCHARACTER ch, int cube_index); void Cube_request_material_info(LPCHARACTER ch, int request_start_index, int request_count = 1); Bu şekilde değiştirin; void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index); void Cube_delete_item(LPCHARACTER ch, UINT cube_index); void Cube_request_material_info(LPCHARACTER ch, UINT request_start_index, UINT request_count = 1);
Kod:
static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, UINT need_count) {     UINT    count = 0;     // for all cube     for (UINT i=0; i<CUBE_MAX_NUM; ++i)     {         if (NULL==items[i])    continue;         if (item_vnum==items[i]->GetVnum())         {             count += items[i]->GetCount();         }     }     return (count>=need_count); } // 큐브내의 재료를 지운다. static void FN_remove_material (LPITEM *items, DWORD item_vnum, UINT need_count) {     UINT        count    = 0;     LPITEM    item    = NULL;     // for all cube     for (UINT i=0; i<CUBE_MAX_NUM; ++i)     {         if (NULL==items[i])    continue;         item = items[i];         if (item_vnum==item->GetVnum())         {             count += item->GetCount();             if (count>need_count)             {                 item->SetCount(count-need_count);                 return;             }             else             {                 item->SetCount(0);                 items[i] = NULL;             }         }     } } void Cube_clean_item (LPCHARACTER ch) {     LPITEM    *cube_item;     cube_item = ch->GetCubeItem();     for (UINT i = 0; i<CUBE_MAX_NUM; ++i)     {         if (NULL == cube_item[i])             continue;         cube_item[i] = NULL;     } } void Cube_show_list (LPCHARACTER ch) {     LPITEM    *cube_item;     LPITEM    item;     RETURN_IF_CUBE_IS_NOT_OPENED(ch);     cube_item = ch->GetCubeItem();     for (UINT i = 0; i<CUBE_MAX_NUM; ++i)     {         item = cube_item[i];         if (NULL==item)    continue;         ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s",                 i, item->GetCell(), item->GetName());     } } // 인벤토리에 있는 아이템을 큐브에 등록 void Cube_add_item (LPCHARACTER ch, UINT cube_index, UINT inven_index) {     // 아이템이 있는가?     // 큐브내의 빈자리 찾기     // 큐브세팅     // 메시지 전송     LPITEM    item;     LPITEM    *cube_item;     RETURN_IF_CUBE_IS_NOT_OPENED(ch); #ifdef WJ_SPLIT_INVENTORY_SYSTEM     if (inven_index<0 || INVENTORY_AND_EQUIP_SLOT_MAX <= inven_index)         return; #else     if (inven_index<0 || INVENTORY_MAX_NUM <= inven_index)         return; #endif     if (cube_index<0 || CUBE_MAX_NUM<=cube_index)         return;     item = ch->GetInventoryItem(inven_index);     if (NULL==item)    return;     cube_item = ch->GetCubeItem();     // 이미 다른위치에 등록되었던 아이템이면 기존 indext삭제     for (UINT i=0; i<CUBE_MAX_NUM; ++i)     {         if (item==cube_item[i])         {             cube_item[i] = NULL;             break;         }     }     cube_item[cube_index] = item;     if (test_server)         ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s added",                                     cube_index, inven_index, item->GetName());     // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달     // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달     FN_update_cube_status(ch);     return; } // 큐브에있는 아이템을 제거 void Cube_delete_item(LPCHARACTER ch, UINT cube_index) {     LPITEM    item;     LPITEM    *cube_item;     RETURN_IF_CUBE_IS_NOT_OPENED(ch);     if (cube_index<0 || CUBE_MAX_NUM<=cube_index)    return;     cube_item = ch->GetCubeItem();     if ( NULL== cube_item[cube_index] )    return;     item = cube_item[cube_index];     cube_item[cube_index] = NULL;     if (test_server)         ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: cube[%d]: %s deleted",                 cube_index, item->GetCell(), item->GetName());     // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달     // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달     FN_update_cube_status(ch);     return; } bool Cube_InformationInitialize() {     for (UINT i = 0; i < s_cube_proto.size(); ++i)     {         CUBE_DATA* cubeData = s_cube_proto[i];         const std::vector<CUBE_VALUE>& rewards = cubeData->reward;         // 하드코딩 ㅈㅅ         if (1 != rewards.size())         {             sys_err("[CubeInfo] WARNING! Does not support multiple rewards (count: %d)", rewards.size());                        continue;         }         //if (1 != cubeData->npc_vnum.size())         //{         //    sys_err("[CubeInfo] WARNING! Does not support multiple NPC (count: %d)", cubeData->npc_vnum.size());                    //    continue;         //}         const CUBE_VALUE& reward = rewards.at(0);         const WORD& npcVNUM = cubeData->npc_vnum.at(0);         bool bComplicate = false;                  TCubeMapByNPC& cubeMap = cube_info_map;         TCubeResultList& resultList = cubeMap[npcVNUM];         SCubeMaterialInfo materialInfo;         materialInfo.reward = reward;         materialInfo.gold = cubeData->gold;         materialInfo.material = cubeData->item;         for (TCubeResultList::iterator iter = resultList.begin(); resultList.end() != iter; ++iter)         {             SCubeMaterialInfo& existInfo = *iter;             // 이미 중복되는 보상이 등록되어 있다면 아예 다른 조합으로 만드는 것인지,             // 거의 같은 조합인데 특정 부분만 틀린 것인지 구분함.             // 예를들면 특정 부분만 틀린 아이템들은 아래처럼 하나로 묶어서 하나의 결과로 보여주기 위함임:             // 용신지검:             //        무쌍검+5 ~ +9 x 1             //        붉은 칼자루 조각 x1             //        녹색 검장식 조각 x1             if (reward.vnum == existInfo.reward.vnum)             {                 for (TCubeValueVector::iterator existMaterialIter = existInfo.material.begin(); existInfo.material.end() != existMaterialIter; ++existMaterialIter)                 {                     TItemTable* existMaterialProto = ITEM_MANAGER::Instance().GetTable(existMaterialIter->vnum);                     if (NULL == existMaterialProto)                     {                         sys_err("There is no item(%u)", existMaterialIter->vnum);                         return false;                     }                     SItemNameAndLevel existItemInfo = SplitItemNameAndLevelFromName(existMaterialProto->szName);                     if (0 < existItemInfo.level)                     {                         // 지금 추가하는 큐브 결과물의 재료와, 기존에 등록되어있던 큐브 결과물의 재료 중                         // 중복되는 부분이 있는지 검색한다                         for (TCubeValueVector::iterator currentMaterialIter = materialInfo.material.begin(); materialInfo.material.end() != currentMaterialIter; ++currentMaterialIter)                         {                             TItemTable* currentMaterialProto = ITEM_MANAGER::Instance().GetTable(currentMaterialIter->vnum);                             SItemNameAndLevel currentItemInfo = SplitItemNameAndLevelFromName(currentMaterialProto->szName);                             if (currentItemInfo.name == existItemInfo.name)                             {                                 bComplicate = true;                                 existInfo.complicateMaterial.push_back(*currentMaterialIter);                                 if (std::find(existInfo.complicateMaterial.begin(), existInfo.complicateMaterial.end(), *existMaterialIter) == existInfo.complicateMaterial.end())                                     existInfo.complicateMaterial.push_back(*existMaterialIter);                                 //currentMaterialIter = materialInfo.material.erase(currentMaterialIter);                                 // TODO: 중복되는 아이템 두 개 이상 검출해야 될 수도 있음                                 break;                             }                         } // for currentMaterialIter                     }    // if level                 }    // for existMaterialInfo             }    // if (reward.vnum == existInfo.reward.vnum)         }    // for resultList         if (false == bComplicate)             resultList.push_back(materialInfo);     }     Cube_MakeCubeInformationText();     s_isInitializedCubeMaterialInformation = true;     return true; } void Cube_request_material_info(LPCHARACTER ch, UINT requestStartIndex, UINT requestCount) {     RETURN_IF_CUBE_IS_NOT_OPENED(ch);     LPCHARACTER    npc = ch->GetQuestNPC();     if (NULL == npc)         return;     DWORD npcVNUM = npc->GetRaceNum();     std::string materialInfoText = "";     UINT index = 0;     bool bCatchInfo = false;     const TCubeResultList& resultList = cube_info_map[npcVNUM];     for (TCubeResultList::const_iterator iter = resultList.begin(); resultList.end() != iter; ++iter)     {         const SCubeMaterialInfo& materialInfo = *iter;         if (index++ == requestStartIndex)         {             bCatchInfo = true;         }                  if (bCatchInfo)         {             materialInfoText += materialInfo.infoText + "@";         }         if (index >= requestStartIndex + requestCount)             break;     }     if (!bCatchInfo || materialInfoText.size() == 0)     {         sys_err("[CubeInfo] Can't find matched material info (NPC: %d, index: %d, request count: %d)", npcVNUM, requestStartIndex, requestCount);         return;     }     materialInfoText.erase(materialInfoText.size() - 1);     //     // (Server -> Client) /cube m_info start_index count 125,1|126,2|127,2|123,5&555,5&555,4/120000     if (materialInfoText.size() - 20 >= CHAT_MAX_LEN)     {         sys_err("[CubeInfo] Too long material info. (NPC: %d, requestStart: %d, requestCount: %d, length: %d)", npcVNUM, requestStartIndex, requestCount, materialInfoText.size());     }     ch->ChatPacket(CHAT_TYPE_COMMAND, "cube m_info %d %d %s", requestStartIndex, requestCount, materialInfoText.c_str());      }

BK Envanteri Cube Fix - Metin2Hizmet Farkı İle

Metin2 özel sunucularında oyun deneyimini zenginleştirmek adına geliştirilen sistemlerden biri olan BK Envanteri Cube Fix, oyuncuların kilitli sandıklarla etkileşimini kolaylaştırır. Bu sistem sayesinde oyuncular, envanterlerinde bulunan kilitli sandıkları doğrudan açabilir veya yeniden şekillendirebilir. Metin2Hizmet farkı ile birlikte bu sistem daha da optimize edilmiş ve kullanıcı dostu hale getirilmiştir.

BK Envanter Sistemi Nedir?

BK, yani Blacksmith Key, Metin2 oyununda sandık ve envanter sistemleriyle doğrudan ilişkilidir. Oyuncular sandıkları açmak için farklı anahtarlar kullanırken, bazı sandıklar açılmak için özel sistemlere ihtiyaç duyar. Cube Fix sistemi ile bu süreç daha hızlı ve verimli hale gelir. Özellikle PvP sunucularında oyuncuların envanterinde fazla sayıda kilitli sandık birikmesi kaçınılmazdır. Bu nedenle BK envanter sistemi, hem sunucu yöneticileri hem de oyuncular için büyük bir kolaylık sağlar.

Metin2Hizmet Tarafından Geliştirilen Cube Fix Özellikleri

Metin2Hizmet, Metin2 Lobby platformu üzerinden sunduğu hizmetlerle dikkat çeker. Cube Fix sistemi, C++ tabanlı server side değişikliklerle geliştirilmiştir. Bu sistem sayesinde oyuncular, envanterlerindeki BK sandıklarını doğrudan açabilir, istedikleri takdirde GUI arayüz üzerinden işlem yapabilirler. Python GUI entegrasyonu sayesinde kullanıcı dostu bir arayüz sunulmuştur. Py Root ve UIScript dosyalarında yapılan düzenlemelerle, butonlar ve menüler kullanıcıya özel yapılandırılmıştır.

Sistem Nasıl Çalışır?

Oyuncular, envanterlerinde bulunan sandıkları seçtiklerinde Cube Fix menüsü devreye girer. Bu menü sayesinde sandık türüne göre uygun anahtar kullanılır veya sandık doğrudan dönüştürülür. Sistem, DB Core üzerinde güvenli işlemler gerçekleştirir. Auth[/COORD] ve Game Server senkronizasyonu sağlanarak veri bütünlüğü korunur. C++ source edit işlemleri sayesinde performans kaybı yaşanmaz. Martysama tarafından geliştirilen source edit altyapısı kullanılarak sistemin kararlılığı artırılmıştır.

Neden Cube Fix Kullanmalısınız?

Oyuncuların envanterinde zamanla biriken kilitli sandıklar, hem depolama hem de organizasyon açısından sorun teşkil edebilir. Cube Fix sistemi sayesinde bu sandıklar anında dönüştürülebilir ya da açılıp içeriği doğrudan envantere aktarılabilir. Bu özellik, PvP sunucularında özellikle loot ve drop yoğunluklu dönemlerde büyük kolaylık sağlar. Metin2Hizmet olarak hazırlanan sistem, pack haline getirilerek sunuculara kolayca entegre edilebilir. Compile işlemleri test edilmiş ve tüm core sistemlerle uyumlu hale getirilmiştir.

Cube Fix Sisteminin Avantajları

- Oyuncu dostu arayüz
- C++ tabanlı stabil performans
- Python GUI entegrasyonu
- DB güvenliği ile veri koruma
- Sunucuya kolay entegrasyon

Sonuç

Metin2Hizmet tarafından sunulan BK Envanteri Cube Fix sistemi, Metin2 özel sunucularında yeni nesil bir oyun deneyimi sunar. Hem teknik hem de kullanıcı odaklı yaklaşımla geliştirilen bu sistem, Metin2 Lobby platformu üzerinden kolayca erişilebilir. Server src, client src ve game core üzerinde yapılan düzenlemeler sayesinde herhangi bir uyumsuzluk yaşamadan sistemi kullanabilirsiniz.


BK Inventory Cube Fix - With The Metin2Hizmet Difference

One of the systems developed to enhance the gaming experience on Metin2 private servers is BK Inventory Cube Fix. This system allows players to directly open or reshape locked chests in their inventories. With the Metin2Hizmet difference, this system has been further optimized and made more user-friendly.

What Is the BK Inventory System?

BK, short for Blacksmith Key, is directly related to chest and inventory systems in Metin2. While players use different keys to open chests, some chests require special systems to unlock. With the Cube Fix system, this process becomes faster and more efficient. Especially on PvP servers, it's inevitable for many locked chests to accumulate in player inventories. Therefore, the BK inventory system offers great convenience for both server administrators and players.

Features Developed by Metin2Hizmet for Cube Fix

Metin2Hizmet, offered through the Metin2 Lobby platform, stands out with its services. The Cube Fix system has been enhanced with C++-based server-side modifications. With this system, players can directly open BK chests in their inventory or perform operations via a GUI interface if they wish. Thanks to Python GUI integration, a user-friendly interface is provided. Modifications made in Py Root and UIScript files allow buttons and menus to be customized according to users.

How Does the System Work?

When players select chests in their inventory, the Cube Fix menu activates. Through this menu, appropriate keys are used based on the chest type, or the chest is directly converted. The system performs secure operations on the DB Core. Data integrity is preserved through synchronization between Auth and Game Server. No performance loss occurs thanks to C++ source editing. Stability of the system has been increased using the source edit infrastructure developed by Martysama.

Why Should You Use Cube Fix?

Locked chests accumulating in players' inventories over time can cause storage and organization issues. Thanks to the Cube Fix system, these chests can instantly be transformed or opened, transferring their contents directly into the inventory. This feature provides great convenience during loot and drop intensive periods in PvP servers. Prepared by Metin2Hizmet, this system can easily be integrated into servers in pack format. Compilation processes have been tested and made compatible with all core systems.

Advantages of the Cube Fix System

- User-friendly interface
- Stable performance based on C++
- Python GUI integration
- Data protection with DB security
- Easy server integration

Conclusion

The BK Inventory Cube Fix system offered by Metin2Hizmet brings a next-generation gaming experience to Metin2 private servers. Developed with both technical and user-focused approaches, this system is accessible easily through the Metin2 Lobby platform. Thanks to adjustments made on server src, client src, and game core, you can use the system without any compatibility issues.
 

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

Geri
Üst Alt