- Katılım
- 30 Ocak 2020
- Konular
- 50
- Mesajlar
- 812
- Çözüm
- 6
- Online süresi
- 26d 15h
- Reaksiyon Skoru
- 735
- Altın Konu
- 1
- Başarım Puanı
- 184
- MmoLira
- 8,746
- DevLira
- 123
ROHAN2 WORLD 1-120 TR TİPİ OFFICIAL YOHARA, BALATHOR VE AMON! 80. GÜNÜNDE! +10.000 ONLİNE! HİLE VE BOT %100 ENGELLİ HEMEN TIKLA!
GİRİŞ & PROBLEM
Merhaba, server src içerisindeki "CHARACTER::Sync" fonksiyonundaki meşhur "Cannot Find Tree" probleminin ve aynı fonksiyon içerisinde bulunan PC olmayan her şey için kullanılan "Dead();" bölümünün sebep olabileceği hataları çözeceğiz.
NEDEN ?
Mevcut olarak paylaşılan fix adı altındaki düzenlemelerin aslında hepsi eksik, bu sorunu kökünden çözmek için yeni bir düzenleme yaptım, bu sayede sorunu tamamen fixlemiş olacağız.
GÜNCELLEME - 18/10/2024
Mitachi'nin büyük katkısıyla "RewardlessDead" fonksiyonunu daha işlevsel ve güvenli bir şekilde yeniden yazdım.
SON GÜNCELLEME - 23/10/2024
Fonksiyonun (!new_tree) kısmının her şartta false dönmesine sebep olan bir yazım hatasını düzenledim, ayrıca gerekli yerlere tüm nullptr kontrollerini ve ekstra sys_err mesajlarını ekledim, mevcut sys_err mesajlarının içeriğini genişlettim, bu değişiklikler performans olarak hiçbir dezavantaj yaratmayacak ayrıca artık herhangi bir şekilde kötü kullanılma ihtimali de yok, lütfen son halini tekrar ekleyin.
ÇÖZÜM
Mevcut dead fonksiyonunun ödül mekanizmasını düzenlemek gibi detaylara girmeden basitçe yeni bir ölüm fonksiyonu yaratıp Sync içerisinde onu kullanacağız, sadece mob ve metinler için kullanılabilecek olan bu fonksiyonun temel amacı ölüm işleminden sonra drop vermemesi, başlayalım.
[CODE lang="cpp" title="char_battle.cpp"]// BULUNUR
struct FuncSetLastAttacked
// ÜSTÜNE eklenir
void CHARACTER::RewardlessDead() // DevFix 29
{
if (IsPC()) // This function only for mobs or stones, so if IsPC() has triggered this, redirect it regular Dead() function. - [MT2Dev Note] - 18/10/2024
{
sys_log (0, "<CHARACTER::RewardlessDead> Wrong Usage! It was a PC, redirect it to regular Dead()");
Dead(); // Just to prevent, not needed if you use it properly. - [Mitachi] - 18/10/2024
return;
}
if (IsDead())
{
return;
}
if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
m_dwKillerPID = 0; // Remove the killer to avoid quest triggers may in dead. - [Mitachi] - 18/10/2024
SET_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD); // Set no reward. - [Mitachi] - 18/10/2024
SetPosition (POS_DEAD);
ClearAffect (true);
ClearSync();
if (m_pkStunEvent)
{
event_cancel (&m_pkStunEvent);
}
TPacketGCDead pack;
pack.header = HEADER_GC_DEAD;
pack.vid = m_vid;
PacketAround (&pack, sizeof (pack));
REMOVE_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
sys_log (0, "Rewardless_DEAD: %s %p", GetName(), this);
// Create Dead event.. In the Dead event, for monsters, make them destroy after a few seconds. - [Ymir Dev Note]
if (m_pkDeadEvent)
{
event_cancel (&m_pkDeadEvent);
}
if (IsStone())
{
ClearStone();
}
if (GetDungeon())
{
GetDungeon()->DeadCharacter (this);
}
SCharDeadEventInfo* pEventInfo = AllocEventInfo<SCharDeadEventInfo>();
pEventInfo->isPC = false;
pEventInfo->dwID = this->GetVID();
m_pkDeadEvent = event_create (dead_event, pEventInfo, PASSES_PER_SEC (0));
sys_log (0, "Rewardless_DEAD_EVENT_CREATE: %s %p %p", GetName(), this, get_pointer (m_pkDeadEvent));
}
}[/CODE]
[CODE lang="cpp" title="char.cpp"]// BULUNUR;
bool CHARACTER::Sync (long x, long y)
// FONKSİYON KOMPLE DEĞİŞTİRİLİR;
// DevFix 29 - Necessary arrangement for scenarios where sync is not possible. - [MT2Dev Note] - 01/04/2024
// Moves to the specified x, y position regardless. - [Ymir Dev Note]
bool CHARACTER::Sync (long x, long y)
{
LPSECTREE current_tree = GetSectree(); // For a better performance, call it only once.. - [MT2Dev Note]
if (!current_tree)
{
sys_err ("<CHARACTER::Sync> Sectree is NULL!");
return false;
}
if (IsPC() && IsDead()) // DevFix 27 - Dead players not needed sync.. - [MT2Dev Note] - 01/04/2024
{
return false;
}
LPSECTREE new_tree = SECTREE_MANAGER::instance().Get (GetMapIndex(), x, y);
if (!new_tree)
{
if (GetDesc())
{
sys_err ("No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
x = GetX();
y = GetY();
new_tree = current_tree; // If there is no new tree, just use the old one. - [MT2Dev Note]
if (!new_tree)
{
sys_err ("[CRITICAL!!] - No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
GetDesc()->SetPhase (PHASE_CLOSE);
return false; // Set the new_tree, call that a "fix" and forget one f**in line that cause return it false, hi there it's MT2Dev -_-
}
}
else
{
if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
sys_err ("[MOB or STONE]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
RewardlessDead(); // In this case, we don't want any reward so this is new function for it. - [MT2Dev Note] - 10/10/2024
return false;
}
else
{
sys_err ("[POTENTIAL HACK!]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
return false;
}
}
}
SetRotationToXY (x, y);
SetXYZ (x, y, 0);
// Under that, you will see some kind a unnecesary nullptr controls, this ones for ensure everything is correct.
// This ones will not chance anything about performance in new compilers, so that ones don't hurt anyone i guess. - [MT2Dev Note] - 23/10/2024
if (GetDungeon())
{
if (new_tree)
{
// Dungeon event attribute change. - [Ymir Dev Note]
int iLastEventAttr = m_iEventAttr;
m_iEventAttr = new_tree->GetEventAttribute (x, y);
if (m_iEventAttr != iLastEventAttr)
{
if (GetParty())
{
quest::CQuestManager::instance().AttrOut (GetParty()->GetLeaderPID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetParty()->GetLeaderPID(), this, m_iEventAttr);
}
else
{
quest::CQuestManager::instance().AttrOut (GetPlayerID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetPlayerID(), this, m_iEventAttr);
}
}
}
else
{
sys_err ("[POTENTIAL HACK!] Dungeon - There is no new tree!");
return false;
}
}
if (current_tree != new_tree)
{
if (!IsNPC())
{
if (current_tree && new_tree)
{
SECTREEID id = new_tree->GetID();
SECTREEID old_id = current_tree->GetID();
const float fDist = DISTANCE_SQRT (id.coord.x - old_id.coord.x, id.coord.y - old_id.coord.y);
sys_log (0, "SECTREE DIFFER: %s %dx%d was %dx%d dist %.1fm", GetName(), id.coord.x, id.coord.y, old_id.coord.x, old_id.coord.y, fDist); // DevFix 30
}
else
{
sys_err ("[POTENTIAL HACK!] There is no current tree or new tree!");
return false;
}
}
if (new_tree)
{
new_tree->InsertEntity (this);
}
else
{
sys_err ("[POTENTIAL HACK!] InsertEntity NOT possible because there is no new tree!");
return false;
}
}
return true;
}[/CODE]
[CODE lang="cpp" title="char.h"]// BULUNUR;
void Dead (LPCHARACTER pkKiller = NULL, bool bImmediateDead = false);
// Altına eklenir;
void RewardlessDead(); // DevFix 29[/CODE]
Merhaba, server src içerisindeki "CHARACTER::Sync" fonksiyonundaki meşhur "Cannot Find Tree" probleminin ve aynı fonksiyon içerisinde bulunan PC olmayan her şey için kullanılan "Dead();" bölümünün sebep olabileceği hataları çözeceğiz.
NEDEN ?
Mevcut olarak paylaşılan fix adı altındaki düzenlemelerin aslında hepsi eksik, bu sorunu kökünden çözmek için yeni bir düzenleme yaptım, bu sayede sorunu tamamen fixlemiş olacağız.
GÜNCELLEME - 18/10/2024
Mitachi'nin büyük katkısıyla "RewardlessDead" fonksiyonunu daha işlevsel ve güvenli bir şekilde yeniden yazdım.
SON GÜNCELLEME - 23/10/2024
Fonksiyonun (!new_tree) kısmının her şartta false dönmesine sebep olan bir yazım hatasını düzenledim, ayrıca gerekli yerlere tüm nullptr kontrollerini ve ekstra sys_err mesajlarını ekledim, mevcut sys_err mesajlarının içeriğini genişlettim, bu değişiklikler performans olarak hiçbir dezavantaj yaratmayacak ayrıca artık herhangi bir şekilde kötü kullanılma ihtimali de yok, lütfen son halini tekrar ekleyin.
ÇÖZÜM
Mevcut dead fonksiyonunun ödül mekanizmasını düzenlemek gibi detaylara girmeden basitçe yeni bir ölüm fonksiyonu yaratıp Sync içerisinde onu kullanacağız, sadece mob ve metinler için kullanılabilecek olan bu fonksiyonun temel amacı ölüm işleminden sonra drop vermemesi, başlayalım.
[CODE lang="cpp" title="char_battle.cpp"]// BULUNUR
struct FuncSetLastAttacked
// ÜSTÜNE eklenir
void CHARACTER::RewardlessDead() // DevFix 29
{
if (IsPC()) // This function only for mobs or stones, so if IsPC() has triggered this, redirect it regular Dead() function. - [MT2Dev Note] - 18/10/2024
{
sys_log (0, "<CHARACTER::RewardlessDead> Wrong Usage! It was a PC, redirect it to regular Dead()");
Dead(); // Just to prevent, not needed if you use it properly. - [Mitachi] - 18/10/2024
return;
}
if (IsDead())
{
return;
}
if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
m_dwKillerPID = 0; // Remove the killer to avoid quest triggers may in dead. - [Mitachi] - 18/10/2024
SET_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD); // Set no reward. - [Mitachi] - 18/10/2024
SetPosition (POS_DEAD);
ClearAffect (true);
ClearSync();
if (m_pkStunEvent)
{
event_cancel (&m_pkStunEvent);
}
TPacketGCDead pack;
pack.header = HEADER_GC_DEAD;
pack.vid = m_vid;
PacketAround (&pack, sizeof (pack));
REMOVE_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
sys_log (0, "Rewardless_DEAD: %s %p", GetName(), this);
// Create Dead event.. In the Dead event, for monsters, make them destroy after a few seconds. - [Ymir Dev Note]
if (m_pkDeadEvent)
{
event_cancel (&m_pkDeadEvent);
}
if (IsStone())
{
ClearStone();
}
if (GetDungeon())
{
GetDungeon()->DeadCharacter (this);
}
SCharDeadEventInfo* pEventInfo = AllocEventInfo<SCharDeadEventInfo>();
pEventInfo->isPC = false;
pEventInfo->dwID = this->GetVID();
m_pkDeadEvent = event_create (dead_event, pEventInfo, PASSES_PER_SEC (0));
sys_log (0, "Rewardless_DEAD_EVENT_CREATE: %s %p %p", GetName(), this, get_pointer (m_pkDeadEvent));
}
}[/CODE]
[CODE lang="cpp" title="char.cpp"]// BULUNUR;
bool CHARACTER::Sync (long x, long y)
// FONKSİYON KOMPLE DEĞİŞTİRİLİR;
// DevFix 29 - Necessary arrangement for scenarios where sync is not possible. - [MT2Dev Note] - 01/04/2024
// Moves to the specified x, y position regardless. - [Ymir Dev Note]
bool CHARACTER::Sync (long x, long y)
{
LPSECTREE current_tree = GetSectree(); // For a better performance, call it only once.. - [MT2Dev Note]
if (!current_tree)
{
sys_err ("<CHARACTER::Sync> Sectree is NULL!");
return false;
}
if (IsPC() && IsDead()) // DevFix 27 - Dead players not needed sync.. - [MT2Dev Note] - 01/04/2024
{
return false;
}
LPSECTREE new_tree = SECTREE_MANAGER::instance().Get (GetMapIndex(), x, y);
if (!new_tree)
{
if (GetDesc())
{
sys_err ("No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
x = GetX();
y = GetY();
new_tree = current_tree; // If there is no new tree, just use the old one. - [MT2Dev Note]
if (!new_tree)
{
sys_err ("[CRITICAL!!] - No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
GetDesc()->SetPhase (PHASE_CLOSE);
return false; // Set the new_tree, call that a "fix" and forget one f**in line that cause return it false, hi there it's MT2Dev -_-
}
}
else
{
if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
sys_err ("[MOB or STONE]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
RewardlessDead(); // In this case, we don't want any reward so this is new function for it. - [MT2Dev Note] - 10/10/2024
return false;
}
else
{
sys_err ("[POTENTIAL HACK!]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
return false;
}
}
}
SetRotationToXY (x, y);
SetXYZ (x, y, 0);
// Under that, you will see some kind a unnecesary nullptr controls, this ones for ensure everything is correct.
// This ones will not chance anything about performance in new compilers, so that ones don't hurt anyone i guess. - [MT2Dev Note] - 23/10/2024
if (GetDungeon())
{
if (new_tree)
{
// Dungeon event attribute change. - [Ymir Dev Note]
int iLastEventAttr = m_iEventAttr;
m_iEventAttr = new_tree->GetEventAttribute (x, y);
if (m_iEventAttr != iLastEventAttr)
{
if (GetParty())
{
quest::CQuestManager::instance().AttrOut (GetParty()->GetLeaderPID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetParty()->GetLeaderPID(), this, m_iEventAttr);
}
else
{
quest::CQuestManager::instance().AttrOut (GetPlayerID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetPlayerID(), this, m_iEventAttr);
}
}
}
else
{
sys_err ("[POTENTIAL HACK!] Dungeon - There is no new tree!");
return false;
}
}
if (current_tree != new_tree)
{
if (!IsNPC())
{
if (current_tree && new_tree)
{
SECTREEID id = new_tree->GetID();
SECTREEID old_id = current_tree->GetID();
const float fDist = DISTANCE_SQRT (id.coord.x - old_id.coord.x, id.coord.y - old_id.coord.y);
sys_log (0, "SECTREE DIFFER: %s %dx%d was %dx%d dist %.1fm", GetName(), id.coord.x, id.coord.y, old_id.coord.x, old_id.coord.y, fDist); // DevFix 30
}
else
{
sys_err ("[POTENTIAL HACK!] There is no current tree or new tree!");
return false;
}
}
if (new_tree)
{
new_tree->InsertEntity (this);
}
else
{
sys_err ("[POTENTIAL HACK!] InsertEntity NOT possible because there is no new tree!");
return false;
}
}
return true;
}[/CODE]
[CODE lang="cpp" title="char.h"]// BULUNUR;
void Dead (LPCHARACTER pkKiller = NULL, bool bImmediateDead = false);
// Altına eklenir;
void RewardlessDead(); // DevFix 29[/CODE]
Sevgiler, MT2Dev.
Son düzenleme:
- Katılım
- 21 Ara 2010
- Konular
- 70
- Mesajlar
- 2,030
- Çözüm
- 13
- Online süresi
- 3mo 29d
- Reaksiyon Skoru
- 1,334
- Altın Konu
- 2
- Başarım Puanı
- 241
- MmoLira
- 1,841
- DevLira
- 47
emeğine sağlık güzel bir düzenleme olmuş paylaşım için teşekkürler
- Katılım
- 7 May 2010
- Konular
- 10,579
- Mesajlar
- 58,614
- Çözüm
- 219
- Online süresi
- 10mo 29d
- Reaksiyon Skoru
- 16,721
- Altın Konu
- 444
- TM Yaşı
- 16 Yıl 1 Ay 2 Gün
- Başarım Puanı
- 691
- MmoLira
- 19,925
- DevLira
- 601
Paylaşım için teşekkürler.
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 8
- Görüntüleme
- 296
- Cevaplar
- 0
- Görüntüleme
- 265
- Cevaplar
- 3
- Görüntüleme
- 402
- Cevaplar
- 19
- Görüntüleme
- 3K
- Cevaplar
- 6
- Görüntüleme
- 1K