Expire-Time Mantığıyla Action Limit Kontrolü

  • Konuyu açan Konuyu açan Toranaga
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 6
  • Gösterim Gösterim 128

Toranaga

Co-Admin
Co-Admin
Geliştirici
Yardımsever Üye
Usta Üye
Mesaj
920
Çözümler
46
Beğeni
1.125
Puan
1.159
Ticaret Puanı
0
Başlık biraz havalı dursa da sistem basit oyuncu aksiyonlarını (zırh giyme, binek vb.) spamlamayı önlemek için kullandığım, expire-time (süre dolma) mantığına dayalı bir Action Limit sistemini paylaşıyorum. Yok quest flag ile fln uğraşmak istemeyenler için.

char.h:
Genişlet Daralt Kopyala
// Altına ekle #include "mining.h"
#include <array>

// Üstlere bir yerlere ekle Örnek: enum EBlockAction Altına
enum EActionLimit
{
    ACTION_LIMIT_WEAR_ARMOR = 0,
    ACTION_LIMIT_RIDE,
    ACTION_LIMIT_CAMP_FIRE,
    ACTION_LIMIT_MAX
};

// CHARACTER sınıfının en altına ekle
public:
        void    SetActionLimit(EActionLimit action, int second);
        bool    CheckActionLimit(EActionLimit action);
        bool    CheckAndSetActionLimit(EActionLimit action, int second);
        int        GetActionLimitLeft(EActionLimit action) const;
    private:
        std::array<uint32_t, ACTION_LIMIT_MAX> m_actionLimitExpire;

char.cpp:
Genişlet Daralt Kopyala
// CHARACTER::Initialize() içine m_iSyncHackCount = 0; altına ekle
m_actionLimitExpire.fill(0);

// En alta ekle
void CHARACTER::SetActionLimit(EActionLimit action, int second)
{
    if (action < 0 || action >= ACTION_LIMIT_MAX)
        return;

    m_actionLimitExpire[action] = get_global_time() + second;

}

bool CHARACTER::CheckActionLimit(EActionLimit action)
{
    if (action < 0 || action >= ACTION_LIMIT_MAX)
        return false;

    auto now = get_global_time();

    if (m_actionLimitExpire[action] > now)
        return false;

    return true;
}

bool CHARACTER::CheckAndSetActionLimit(EActionLimit action, int second)
{
    if (action < 0 || action >= ACTION_LIMIT_MAX)
        return false;

    auto now = get_global_time();

    if (m_actionLimitExpire[action] > now)
        return false;

    m_actionLimitExpire[action] = now + second;
    return true;
}

int CHARACTER::GetActionLimitLeft(EActionLimit action) const
{
    if (action < 0 || action >= ACTION_LIMIT_MAX)
        return 0;

    auto now = get_global_time();

    if (m_actionLimitExpire[action] > now)
        return m_actionLimitExpire[action] - now;

    return 0;
}

char_horse.cpp:
Genişlet Daralt Kopyala
// içinde bool CHARACTER::StartRiding()
// DWORD dwMountVnum = m_chHorse ? m_chHorse->GetRaceNum() : GetMyHorseVnum();
// Üstüne ekle
if (!CheckAndSetActionLimit(ACTION_LIMIT_RIDE, 2))
{
    ChatPacket(CHAT_TYPE_INFO, "[LSE;3;%d]", GetActionLimitLeft(ACTION_LIMIT_RIDE));
    return false;
}
// bool CHARACTER::StopRiding() içine en üste ekle
if (!CheckAndSetActionLimit(ACTION_LIMIT_RIDE, 2))
    return false;

char_item.cpp:
Genişlet Daralt Kopyala
// İçinde bool CHARACTER::UseItemEx (LPITEM item, TItemPos DestCell)
// Arat
LPCHARACTER campfire = CHARACTER_MANAGER::instance().SpawnMob (fishing::CAMPFIRE_MOB, GetMapIndex(), (long) (GetX()+fx), (long) (GetY()+fy), 0, false, number (0, 359));
// Üstüne Ekle
if (!CheckAndSetActionLimit(ACTION_LIMIT_CAMP_FIRE, 40))
{
    ChatPacket(CHAT_TYPE_INFO, "[LSE;5;%d]", GetActionLimitLeft(ACTION_LIMIT_CAMP_FIRE));
    return false;
}
// içinde bool CHARACTER::EquipItem (LPITEM item, int iCandidateCell)
// Arat
if (item->IsDragonSoul())
// Üstüne Ekle
if (iWearCell == WEAR_BODY || iWearCell == WEAR_COSTUME_BODY)
{
    if (!CheckAndSetActionLimit(ACTION_LIMIT_WEAR_ARMOR, 2))
    {
        ChatPacket(CHAT_TYPE_INFO, "[LSE;4;%d]", GetActionLimitLeft(ACTION_LIMIT_WEAR_ARMOR));
        return false;
    }
}
 
Son düzenleme:
Lag mı yaptırtıyolar hocam in bin yaparak kötü niyetli loncalar?

55 120 de bi tek binekten inip kaykaya bindiriyoruz :d sonra 24 saat oto avdalar. Bilmediğimden soruyorum.
 
Lag mı yaptırtıyolar hocam in bin yaparak kötü niyetli loncalar?

55 120 de bi tek binekten inip kaykaya bindiriyoruz :d sonra 24 saat oto avdalar. Bilmediğimden soruyorum.
Şu an geliştirdiğim files ta bu şekilde bug yapılabiliyor onun önüne geçmek için. Eskiden at üzerinde zırh değiştirerek bug yapıyordu oyuncular.
 
C++:
Genişlet Daralt Kopyala
CheckActionLimit(ACTION_LIMIT_MAX); // crash
CheckActionLimit(3); // veya 3den buyuk bir sayi, crash
CheckAndSetActionLimit(ACTION_LIMIT_MAX); // crash
CheckAndSetActionLimit(3); // veya 3den buyuk bir sayi, crash


klasik out of bound (hatta eğer derleyici optimizasyonu açıksa UB, optimizasyonun kapalı olduğunu düşünerek crash diyorum)
enum yerine enum class kullanmanızı tavsiye edebilirim, tabii MAX değerini yine de kontrol etmelisiniz, enum class implicit conversionun önüne geçer(mesela argüman olarak 3, 4 gibi integer değer geçmenizi önler)
 
C++:
Genişlet Daralt Kopyala
CheckActionLimit(ACTION_LIMIT_MAX); // crash
CheckActionLimit(3); // veya 3den buyuk bir sayi, crash
CheckAndSetActionLimit(ACTION_LIMIT_MAX); // crash
CheckAndSetActionLimit(3); // veya 3den buyuk bir sayi, crash


klasik out of bound (hatta eğer derleyici optimizasyonu açıksa UB, optimizasyonun kapalı olduğunu düşünerek crash diyorum)
enum yerine enum class kullanmanızı tavsiye edebilirim, tabii MAX değerini yine de kontrol etmelisiniz, enum class implicit conversionun önüne geçer(mesela argüman olarak 3, 4 gibi integer değer geçmenizi önler)
Teşekkür ederim. SetActionLimit ve GetActionLimitLeft içinde kontrol sağladım ama diğerlerinde unutmuşum. Enum class kullanmamamın sebebi ise her yerde EActionLimit:: bu şekilde kullanmaya üşendiğim için. Kodu güncellerim.
 
Teşekkür ederim. SetActionLimit ve GetActionLimitLeft içinde kontrol sağladım ama diğerlerinde unutmuşum. Enum class kullanmamamın sebebi ise her yerde EActionLimit:: bu şekilde kullanmaya üşendiğim için. Kodu güncellerim.
rica ederim gözüme çarptı söylemek istedim, c++20 kullanıyorsanız "using enum" kullanabilirsiniz syntaxı kısaltmak amacıyla, ama dediğim gibi en büyük sorun zaten "implicit conversion"(type safety, scoped enumeration vs. cabası), üşenmekten ziyade doğru yolu tercih etmeniz daha iyi olabilir diye düşünüyorum, saygılar
 
rica ederim gözüme çarptı söylemek istedim, c++20 kullanıyorsanız "using enum" kullanabilirsiniz syntaxı kısaltmak amacıyla, ama dediğim gibi en büyük sorun zaten "implicit conversion", üşenmekten ziyade doğru yolu tercih etmeniz daha iyi olabilir diye düşünüyorum, saygılar
syntax error yiğidin kamçısıdır
 
Geri
Üst