Great OfflineShoplarda Artık Edit Modunu Kapatmayın

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

Admin

Metin2Lobby
Yönetici
Founder
Katılım
6 Mayıs 2022
Mesajlar
52,647
Ticaret : 1 / 0 / 0
çünkü fixini paylaşıyorum.
Kod:
ACMD(do_shop_update_item) {     if (ch->IsObserverMode() || ch->GetExchange() || ch->IsOpenSafebox() || ch->GetShopOwner() || ch->IsCubeOpen() || ch->GetMyShop())         return;     extern ACMD(do_shop_refresh_items);     char arg1[256];     one_argument(argument, arg1, sizeof(arg1));     if (!*arg1)         return;     std::vector<std::string> args;     boost::split(args, arg1, boost::is_any_of("|")); #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE     if (args.size() == 4) #else     if (args.size() == 3) #endif     {         return;     }     DWORD shop_id;     str_to_number(shop_id, args[1].c_str());     bool myShop=false;     {         CharacterVectorInteractor i;         if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))         {             CharacterVectorInteractor::iterator it = i.begin();             while (it != i.end()) {                 LPCHARACTER pc = *it++;                 if (pc)                     if (pc->GetRaceNum() == 30000 && pc->GetPrivShop() == shop_id) {                         myShop=true;                         break;                     }             }         }     }     if(!myShop)     {         SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id from player_shop WHERE id = %d and player_id=%d", shop_id, ch->GetPlayerID()));         SQLResult * pRes = pkMsg->Get();         myShop=pRes->uiNumRows>0;     }     if (myShop)     {         {             TPacketShopUpdateItem packet;             packet.shop_id = shop_id;             packet.shop_locked = true;             db_clientdesc->DBPacket(HEADER_GD_SHOP_UPDATE_ITEM, 0, &packet, sizeof(packet));         }         /*         /update_shop_item price|%d|%d|%d)         /update_shop_item remove|%d|%d         /update_shop_item add|%d|%d|%d|%d|%s         */         if (args.size() == 4)         {             DWORD item_id;             str_to_number(item_id, args[2].c_str());             long long price;             str_to_number(price, args[3].c_str()); #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE             DWORD cheque;             str_to_number(cheque, args[4].c_str()); #endif             if (price <= 0 || item_id <= 0)                 return;             {                 SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT id from player_shop_items WHERE id = %d and shop_id=%d", item_id, shop_id));                 SQLResult * pRes = pkMsg->Get();                 if (pRes->uiNumRows > 0)                     DBManager::instance().DirectQuery("UPDATE player_shop_items SET price=%lld WHERE id = %d and shop_id=%d", price, item_id, shop_id); #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE                 if (pRes->uiNumRows > 0)                     DBManager::instance().DirectQuery("UPDATE player_shop_items SET cheque=%d WHERE id = %d and shop_id=%d", cheque, item_id, shop_id); #endif             }             }         else if (args.size() == 3)         {             DWORD item_id;             str_to_number(item_id, args[2].c_str());             if (item_id <= 0)                 return;             {                 std::string shop_name(LC_TEXT( "SHOP_NAME"));                 boost::replace_all(shop_name, "#PLAYER_NAME#", ch->GetName());                 boost::replace_all(shop_name, "#ID#", "");                 char szSockets[1024] = { '\0' };                 char *tempSockets = szSockets;                 for (int i = 0; i < ITEM_SOCKET_MAX_NUM; i++)                 {                     tempSockets += sprintf(tempSockets, "socket%d", i);                     if (i<ITEM_SOCKET_MAX_NUM - 1)                         tempSockets += sprintf(tempSockets, ",");                 }                 char szAttrs[1024] = { '\0' };                 char *tempAttrs = szAttrs;                 for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++)                 {                     if (i < 7)                         tempAttrs += sprintf(tempAttrs, "attrtype%d,attrvalue%d", i, i);                     else                         tempAttrs += sprintf(tempAttrs, "applytype%d,applyvalue%d", i - 7, i - 7);                     if (i<ITEM_ATTRIBUTE_MAX_NUM - 1)                         tempAttrs += sprintf(tempAttrs, ",");                 }                 SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT vnum,count,%s,%s from player_shop_items where shop_id='%d' and id=%d", szSockets,szAttrs,shop_id, item_id));                 SQLResult * pRes = pkMsg->Get();                 if (pRes->uiNumRows>0)                 {                     MYSQL_ROW row;                     while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)                     {                         int col = 0;                         char query[8192];                         sprintf(query, "INSERT INTO player_gift SET owner_id=%d,reason='%s',`from`=replace(\"%s\",' ','_'),status='WAIT',date_add=NOW()", ch->GetPlayerID(), LC_TEXT( "SHOP_ITEM_REASON"), shop_name.c_str());                         sprintf(query, "%s, vnum='%s'", query, row[col++]);                         sprintf(query, "%s, count='%s'", query, row[col++]);                         for (int s = 0; s < ITEM_SOCKET_MAX_NUM; s++)                             sprintf(query, "%s, socket%d='%s'", query, s, row[col++]);                                         for (int ia = 0; ia < ITEM_ATTRIBUTE_MAX_NUM; ia++)                         {                             if (ia < 7)                             {                                 sprintf(query, "%s, attrtype%d='%s'", query, ia, row[col++]);                                 sprintf(query, "%s, attrvalue%d='%s'", query, ia, row[col++]);                             }                             else                             {                                 sprintf(query, "%s, applytype%d='%s'", query, ia-7,row[col++]);                                 sprintf(query, "%s, applyvalue%d='%s'", query, ia-7,row[col++]);                             }                         }                         SQLMsg * pkMsg(DBManager::instance().DirectQuery(query));                         SQLResult * pRes = pkMsg->Get();                         DWORD gift_id = pRes->uiInsertID;                         if (gift_id > 0)                             GetGift(ch, gift_id);                                                                       DBManager::instance().DirectQuery("delete from player_shop_items where id='%d'", item_id);                         DBManager::instance().DirectQuery("UPDATE player_shop SET item_count=item_count-1 WHERE id = %d", shop_id);                     }                 }             }         } #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE         else if (args.size() == 7) #else         else if (args.size() == 6) #endif         {             BYTE display_pos;             str_to_number(display_pos, args[2].c_str());             if (display_pos < 0)                 return;             WORD pos;             str_to_number(pos, args[3].c_str());             if (pos < 0)                 return;             BYTE window_type;             str_to_number(window_type, args[4].c_str());             if (window_type < 0)                 return;             #ifdef ACCE_LENNT_FIX             if(ch->IsAcceOpen())                 Acce_close(ch);             #endif             long long price;             str_to_number(price, args[5].c_str());             if (price <= 0)                 return; #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE             DWORD cheque;             str_to_number(cheque, args[6].c_str());             if (cheque < 0)                 return; #endif         #ifdef FULL_YANG             {                 long long nTotalMoney=price;                 SQLMsg * pkMsg(DBManager::instance().DirectQuery("SELECT price from player_shop_items where shop_id='%d'", szSockets,szAttrs,shop_id));                 SQLResult * pRes = pkMsg->Get();                 if (pRes->uiNumRows>0)                 {                     MYSQL_ROW row;                     while ((row = mysql_fetch_row(pRes->pSQLResult)) != NULL)                     {                         long long temp;                         str_to_number(temp,row[0]);                         nTotalMoney+=temp;                     }                 }                 if (GOLD_MAX <= nTotalMoney)                 {                     sys_err("[OVERFLOW_GOLD] Overflow (GOLD_MAX) id %u name %s", GetPlayerID(), GetName());                     ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20?? ©©E?¡í ??¡ÆuC??¨Ï ¡íoA¢§?¡í ?¡©?o¡Æ¢§ ??¢©?¢¥?¢¥?"));                     return;                 }             }         #endif             LPITEM item = ch->GetItem(TItemPos(window_type, pos));             if (item)             {                 const TItemTable * item_table = item->GetProto();                 if (item_table && (IS_SET(item_table->dwAntiFlags, ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MYSHOP)))                 {                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "??¡¤a?¡© ???????? ¡Æ©©?I¡íoA¢§?¢§?¡© ?C¢¬?C? ?o ??¢©?¢¥?¢¥?."));                     return;                 }                 if (item->IsEquipped())                 {                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "????A©¬?I ???????? ¡Æ©©?I¡íoA¢§?¢§?¡© ?C¢¬?C? ?o ??¢©?¢¥?¢¥?."));                     return;                 }                 if (item->isLocked())                 {                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "¡íc?eA©¬?I ???????? ¡Æ©©?I¡íoA¢§?¢§?¡© ?C¢¬?C? ?o ??¢©?¢¥?¢¥?."));                     return;                 }                 if (item->GetOwner() != ch)                 {                     return;                 } #ifdef SOULBIND_SYSTEM                 if (item->IsSoulBind())                 {                     ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT( "You can't sell in private shop item with soul bind."));                     return;                 } #endif                 char query[1024];                 sprintf(query, "INSERT INTO player_shop_items SET");                 sprintf(query, "%s player_id='%d'", query, ch->GetPlayerID());                 sprintf(query, "%s, shop_id='%d'", query, shop_id);                 sprintf(query, "%s, vnum='%d'", query, item->GetVnum());                 sprintf(query, "%s, count='%d'", query, item->GetCount());                 sprintf(query, "%s, price='%lld'", query, price); #ifdef ENABLE_OFFLINE_SHOP_USE_CHEQUE                 sprintf(query, "%s, cheque='%d'", query, cheque); #endif                 sprintf(query, "%s, display_pos='%u'", query, display_pos);                 for (int s = 0; s < ITEM_SOCKET_MAX_NUM; s++)                 {                     sprintf(query, "%s, socket%d='%ld'", query, s, item->GetSocket(s));                 }                 for (int ia = 0; ia < ITEM_ATTRIBUTE_MAX_NUM; ia++)                 {                     const TPlayerItemAttribute& attr = item->GetAttribute(ia);                     if (ia < 7)                     {                         sprintf(query, "%s, attrtype%d='%u'", query, ia, attr.bType);                         sprintf(query, "%s, attrvalue%d='%d'", query, ia, attr.sValue);                     }                     else                     {                         sprintf(query, "%s, applytype%d='%u'", query, ia-7, attr.bType);                         sprintf(query, "%s, applyvalue%d='%d'", query, ia-7, attr.sValue);                     }                 }                 DBManager::instance().DirectQuery(query);                 ITEM_MANAGER::Instance().RemoveItem(item, "Priv shop");                 DBManager::instance().DirectQuery("UPDATE player_shop SET item_count=item_count +1 WHERE id = %d", shop_id);             }             else                 return;         }         else             return;         ch->LoadPrivShops();         char buf[32];         sprintf(buf, "refresh_shop_items %d", shop_id);         interpret_command(ch, buf, strlen(buf));         CharacterVectorInteractor i;         if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(30000, i))         {             CharacterVectorInteractor::iterator it = i.begin();             while (it != i.end()) {                 LPCHARACTER pc = *it++;                 if (pc)                     if (pc->GetRaceNum() == 30000 && pc->GetPrivShop() == shop_id) {                         pc->UpdateShopItems();                         return;                     }             }         }         TPacketShopUpdateItem packet;         packet.shop_id = shop_id;         packet.shop_locked = false;         db_clientdesc->DBPacket(HEADER_GD_SHOP_UPDATE_ITEM, 0, &packet, sizeof(packet));         }     }

güle güle kullanın

kanıt



for vermeyi unutmuşum for
Great OfflineShoplarda Artık Edit Modunu Kapatmayın

Metin2 özel sunucularında OfflineShop sistemleri, oyuncuların oyun dışıyken bile eşya ve para kazanabilmesi için oldukça popülerdir. Bu sistemler sayesinde oyuncular, karakterlerini oynatmadan dahi gelişim sağlayabilir. Ancak bazı sunucu geliştiricileri, Edit Mode özelliğini kapatmayı tercih eder; çünkü bu modun yanlış kullanım potansiyeli barındırdığını düşünürler. Fakat Great OfflineShop gibi gelişmiş sistemlerde, Edit Mode'un açık kalmasının birçok avantajı vardır. Bu yazıda, neden artık edit modunu kapatmamamız gerektiğini detaylıca ele alacağız.

Edit Mode Nedir?

Edit Mode, Metin2 özel sunucularında geliştiricilerin belirli ayarları kolayca değiştirmesine olanak tanıyan bir özelliktir. Özellikle OfflineShop sistemleri gibi karmaşık yapılarla çalışırken, bu mod sayesinde eşya listeleri, fiyatlar, süreler gibi parametreler doğrudan oyun içinden kolayca düzenlenebilir. Bu da geliştirme ve test süreçlerini hızlandırır.

Great OfflineShop ve Edit Mode

Great OfflineShop, Metin2 özel sunucularında kullanılmak üzere geliştirilmiş, güçlü ve esnek bir sistemdir. Bu sistemde, Edit Mode açıldığında geliştiriciler, C++ veya Python seviyesinde kod yazmadan da değişiklik yapabilirler. Örneğin, bir eşya satış fiyatı veya otomatik işlem süresi gibi parametreler, kullanıcı dostu bir arayüz üzerinden hızlıca güncellenebilir.

Neden Edit Mode'u Kapatmamalıyız?

1. Hızlı Geliştirme ve Test: Edit Mode, sistem üzerinde hızlı testler yapmanızı sağlar. Yeni özellikler eklediğinizde veya mevcut sistemleri optimize ettiğinizde, değişikliklerinizi anında görebilirsiniz. Bu, server src üzerinde tekrar derleme yapma zorunluluğunu ortadan kaldırır.

2. Oyuncu Deneyimi İçin Esneklik: Sunucunuzdaki OfflineShop sistemini, oyuncu geri bildirimlerine göre anında güncellemek isterseniz, Edit Mode olmadan bu mümkün değildir. Sistem üzerinde dinamik değişiklikler yapabilmek, oyuncu memnuniyetini artırır.

3. Yetkili Kullanıcılar Arasında Güven: Edit Mode sadece güvenilir geliştiriciler veya adminler tarafından kullanılmalıdır. Bu yetkilendirme, sunucu sahipleri tarafından kontrollü bir şekilde sağlanabilir. Böylece güvenlik riski en aza indirgenirken, sistem yönetimi daha esnek hale gelir.

Güvenlik İçin Öneriler

Edit Mode açıkken dikkat edilmesi gereken bazı güvenlik önlemleri vardır:

- Sadece güvenilir geliştiricilerin bu moda erişimine izin verin.
- Yetki kontrol mekanizmalarını C++ veya Python seviyesinde ekleyerek sistemi koruyun.
- Gerekirse, sunucu loglarında yapılan değişiklikleri takip edin.

Sonuç

Edit Mode özelliği, Metin2 özel sunucularında Great OfflineShop gibi gelişmiş sistemlerle çalışırken büyük kolaylıklar sağlar. Bu modu kapatmak yerine, güvenli bir şekilde yönetmek, sunucu performansını ve geliştirme süreçlerini olumlu yönde etkiler. Metin2 özel sunucu dünyasında rekabet arttıkça, esneklik ve hızlı adaptasyon yetenekleri önem kazanmaktadır. Bu nedenle, Edit Mode artık kapatılmamalıdır.


Don't Close Edit Mode in Great OfflineShops Anymore

Metin2 private servers often use OfflineShop systems, which allow players to earn items and gold even while offline. These systems enable characters to progress without active gameplay. However, some server developers choose to disable Edit Mode, believing that it can be misused. Yet, in advanced systems like Great OfflineShop, keeping Edit Mode enabled offers several advantages. In this article, we will explore why edit mode should no longer be disabled.

What Is Edit Mode?

Edit Mode is a feature that allows developers on Metin2 private servers to easily adjust certain settings. Especially when working with complex systems like OfflineShops, this mode allows developers to quickly modify item lists, prices, durations, and other parameters directly from within the game. This significantly speeds up development and testing processes.

Great OfflineShop and Edit Mode

Great OfflineShop is a powerful and flexible system developed for Metin2 private servers. When Edit Mode is enabled in this system, developers can make adjustments without writing code at C++ or Python level. For example, parameters such as item sale prices or automatic operation times can be updated quickly via a user-friendly interface.

Why Shouldn't We Close Edit Mode?

1. Fast Development and Testing: Edit Mode allows you to perform quick tests on your system. When adding new features or optimizing existing ones, you can see changes instantly. This eliminates the need to recompile the server src.

2. Flexibility for Player Experience: If you want to update your OfflineShop system based on player feedback, this is not possible without Edit Mode. Making dynamic changes to the system increases player satisfaction.

3. Trust Among Authorized Users: Edit Mode should only be accessible to trusted developers or admins. This authorization can be controlled by server owners. Thus, security risks are minimized while system management becomes more flexible.

Security Recommendations

There are some security measures to consider when Edit Mode is enabled:

- Only allow trusted developers access to this mode.
- Add permission controls at the C++ or Python level to secure the system.
- Log changes made during sessions if necessary.

Conclusion

The Edit Mode feature provides great convenience when working with advanced systems like Great OfflineShop on Metin2 private servers. Instead of disabling this mode, managing it securely enhances both server performance and development processes. As competition in the Metin2 private server world increases, flexibility and rapid adaptation skills become more important. Therefore, Edit Mode should no longer be turned off.​
 

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

Benzer konular

Geri
Üst Alt