Reklam vermek için [email protected]

Server Paket Optimizasyonu ComputePoint Deneysel

5.00 yıldız(lar) 4 Değerlendirme Değerlendirenler

[C]Martin

Level 4
TM Üye
Üye
Katılım
14 Ocak 2021
Konular
10
Mesajlar
441
Reaksiyon Skoru
336
Altın Konu
0
Başarım Puanı
82
TM Yaşı
1 Yıl 8 Ay 25 Gün
Online Süresi
149d 21h 34m
MmoLira
484
DevLira
9
Takipçiler
6

Sentor2 Baştan Aşağı Yenilenmiş 55-120 Altyapısı ile 7 Ekim Cuma Günü 21:00'da Açılıyor. Detaylı Bilgi Edinmek ve Soru Sormak İçin Discord Sunucumuza Katılabilirsiniz.

Ekleyenler yorumlarını eksik etmezse sevinirim.

Sistemin Faydaları:
1. Tekli statü verirken oyunda lag oluşması düzeldi
2. Bineğe in bin yaparken ata vs computepoint çağrıları olanlar oradaki lag da düzeltildi
3. Grup üyelerine verilen bonuslar sonucunda oluşan lag düzeldi
4. Normal pet sistemi pet kullanım sonucu computepoint çağrıları olanlar oradaki lag düzeldi
5. Statü sıfırlamada bulunan lag düzeldi
6. Reload proto çektiğinizde oluşan lag da iyileşme olmuştur
7. Beceri puanlarını verirken oluşan lag düzeldi
8. Süresi dolan affectler silinirken oluşan lag düzeldi
9. Oyuna giriş çıkışlarda oluşan paket fazlalığı azaldı lag azalması oldu

Bu sadece sıfır altyapılarda olan iyileşmeler sistem dolu bir oyunda kat kat daha fazla bir iyileşme oluşacaktır.

Ufak bir not : Bu optimizasyon herkesin kullandığı beceri renklendirme sisteminde(skill color) 1-120 projelerde updatepacket boyutunu 900 1000 baytlara kadar çıkarıyordu ve bu updatepacket fonksiyonu çok sık kullanılan bir şey bu optimizasyon updatepacket kullanımını azalttığı için onada biraz fayda sağlayabilir beceri renklendirmeyi büyük projeler denediği için 900 1000 bayt civarı olan paketde sorun çıkmıyordu bunda da sorun çıkacağını düşünmüyorum ama aktif bir şekilde test edilmeden sadece deneyseldir test edildiğinide bu optimizasyon tamamen onaylanır.

Skill color sistemini kullanan serverler bu optimizasyonu uygulayınca sunucu network trafiğince ciddi düşüş yaşayabilir ve lag olasılığı azalabilir filesin kodlamasına göre bu iyileşme oranı değişkenlik gösterecektir.


Gözden kaçan paylaşım hatası:
(item.h update) , bool load = false removed

old : void        ModifyPoints(bool bAdd, bool load = false, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

new : void        ModifyPoints(bool bAdd, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

Update Final paket boyutu tamamen düşürüldü maksimum 100 baytın üstüne çıkmıyor artık :

C++:
typedef struct character_point_instant
{
    long            points[POINT_MAX_NUM];
    long            points_computepoint[POINT_MAX_NUM];//Fixed_[C]Martin_001

//--------------------------------------------------------


void CHARACTER::ComputePoints()
{
    compute_point_status = true;//Fixed_[C]Martin_001
    memcpy(m_pointsInstant.points_computepoint, m_pointsInstant.points, sizeof(m_pointsInstant.points));//Fixed_[C]Martin_001

    long comp_hp = GetHP();//Fixed_[C]Martin_001
    long comp_max_hp = GetMaxHP();//Fixed_[C]Martin_001
    long comp_sp = GetSP();//Fixed_[C]Martin_001
    long comp_max_sp = GetMaxSP();//Fixed_[C]Martin_001
    long comp_stamina = GetStamina();//Fixed_[C]Martin_001
    long comp_max_stamina = GetMaxStamina();//Fixed_[C]Martin_001

    long lStat = GetPoint(POINT_STAT);
    long lStatResetCount = GetPoint(POINT_STAT_RESET_COUNT);
    long lSkillActive = GetPoint(POINT_SKILL);
    long lSkillSub = GetPoint(POINT_SUB_SKILL);
    long lSkillHorse = GetPoint(POINT_HORSE_SKILL);
    long lLevelStep = GetPoint(POINT_LEVEL_STEP);

    long lAttackerBonus = GetPoint(POINT_PARTY_ATTACKER_BONUS);
    long lTankerBonus = GetPoint(POINT_PARTY_TANKER_BONUS);
    long lBufferBonus = GetPoint(POINT_PARTY_BUFFER_BONUS);
    long lSkillMasterBonus = GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
    long lHasteBonus = GetPoint(POINT_PARTY_HASTE_BONUS);
    long lDefenderBonus = GetPoint(POINT_PARTY_DEFENDER_BONUS);

    long lHPRecovery = GetPoint(POINT_HP_RECOVERY);
    long lSPRecovery = GetPoint(POINT_SP_RECOVERY);

    memset(m_pointsInstant.points, 0, sizeof(m_pointsInstant.points));
    BuffOnAttr_ClearAll();
    m_SkillDamageBonus.clear();

    SetPoint(POINT_STAT, lStat);
    SetPoint(POINT_SKILL, lSkillActive);
    SetPoint(POINT_SUB_SKILL, lSkillSub);
    SetPoint(POINT_HORSE_SKILL, lSkillHorse);
    SetPoint(POINT_LEVEL_STEP, lLevelStep);
    SetPoint(POINT_STAT_RESET_COUNT, lStatResetCount);

    SetPoint(POINT_ST, GetRealPoint(POINT_ST));
    SetPoint(POINT_HT, GetRealPoint(POINT_HT));
    SetPoint(POINT_DX, GetRealPoint(POINT_DX));
    SetPoint(POINT_IQ, GetRealPoint(POINT_IQ));

    SetPart(PART_MAIN, GetOriginalPart(PART_MAIN));
    SetPart(PART_WEAPON, GetOriginalPart(PART_WEAPON));
    SetPart(PART_HEAD, GetOriginalPart(PART_HEAD));
    SetPart(PART_HAIR, GetOriginalPart(PART_HAIR));

#ifdef ENABLE_ACCE_SYSTEM
    SetPart(PART_ACCE, GetOriginalPart(PART_ACCE));
#endif

    SetPoint(POINT_PARTY_ATTACKER_BONUS, lAttackerBonus);
    SetPoint(POINT_PARTY_TANKER_BONUS, lTankerBonus);
    SetPoint(POINT_PARTY_BUFFER_BONUS, lBufferBonus);
    SetPoint(POINT_PARTY_SKILL_MASTER_BONUS, lSkillMasterBonus);
    SetPoint(POINT_PARTY_HASTE_BONUS, lHasteBonus);
    SetPoint(POINT_PARTY_DEFENDER_BONUS, lDefenderBonus);

    SetPoint(POINT_HP_RECOVERY, lHPRecovery);
    SetPoint(POINT_SP_RECOVERY, lSPRecovery);

    // PC_BANG_ITEM_ADD
    SetPoint(POINT_PC_BANG_EXP_BONUS, 0);
    SetPoint(POINT_PC_BANG_DROP_BONUS, 0);
    // END_PC_BANG_ITEM_ADD

    int iMaxHP, iMaxSP;
    int iMaxStamina;

    if (IsPC())
    {
        iMaxHP = JobInitialPoints[GetJob()].max_hp + m_points.iRandomHP + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].hp_per_ht;
        iMaxSP = JobInitialPoints[GetJob()].max_sp + m_points.iRandomSP + GetPoint(POINT_IQ) * JobInitialPoints[GetJob()].sp_per_iq;
        iMaxStamina = JobInitialPoints[GetJob()].max_stamina + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].stamina_per_con;

        {
            CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_ADD_HP);

            if (NULL != pkSk)
            {
                pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_ADD_HP) / 100.0f);

                iMaxHP += static_cast<int>(pkSk->kPointPoly.Eval());
            }
        }

        SetPoint(POINT_MOV_SPEED,    100);
        SetPoint(POINT_ATT_SPEED,    100);
        PointChange(POINT_ATT_SPEED, GetPoint(POINT_PARTY_HASTE_BONUS), false, false, compute_point_status);//Fixed_[C]Martin_001
        SetPoint(POINT_CASTING_SPEED,    100);
    }
    else
    {
        iMaxHP = m_pkMobData->m_table.dwMaxHP;
        iMaxSP = 0;
        iMaxStamina = 0;

        SetPoint(POINT_ATT_SPEED, m_pkMobData->m_table.sAttackSpeed);
        SetPoint(POINT_MOV_SPEED, m_pkMobData->m_table.sMovingSpeed);
        SetPoint(POINT_CASTING_SPEED, m_pkMobData->m_table.sAttackSpeed);
    }

    if (IsPC())
    {
        if (GetMountVnum())
        {
            if (GetHorseST() > GetPoint(POINT_ST))
                PointChange(POINT_ST, GetHorseST() - GetPoint(POINT_ST), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseDX() > GetPoint(POINT_DX))
                PointChange(POINT_DX, GetHorseDX() - GetPoint(POINT_DX), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseHT() > GetPoint(POINT_HT))
                PointChange(POINT_HT, GetHorseHT() - GetPoint(POINT_HT), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseIQ() > GetPoint(POINT_IQ))
                PointChange(POINT_IQ, GetHorseIQ() - GetPoint(POINT_IQ), false, false, compute_point_status);//Fixed_[C]Martin_001
        }

    }

    ComputeBattlePoints(compute_point_status);//Fixed_[C]Martin_001

    if (iMaxHP != GetMaxHP())
    {
        SetRealPoint(POINT_MAX_HP, iMaxHP);
    }

    PointChange(POINT_MAX_HP, 0, false, false, compute_point_status);//Fixed_[C]Martin_001

    if (iMaxSP != GetMaxSP())
    {
        SetRealPoint(POINT_MAX_SP, iMaxSP);
    }

    PointChange(POINT_MAX_SP, 0, false, false, compute_point_status);//Fixed_[C]Martin_001

    SetMaxStamina(iMaxStamina);
    // @fixme118 part1
    int iCurHP = this->GetHP();
    int iCurSP = this->GetSP();

    m_pointsInstant.dwImmuneFlag = 0;

    for (int i = 0 ; i < WEAR_MAX_NUM; i++)
    {
        LPITEM pItem = GetWear(i);
        if (pItem)
        {
            pItem->ModifyPoints(true, compute_point_status);//Fixed_[C]Martin_001
            SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
        }
    }

    if (DragonSoul_IsDeckActivated())
    {
        for (int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck();
            i < WEAR_MAX_NUM + DS_SLOT_MAX * (DragonSoul_GetActiveDeck() + 1); i++)
        {
            LPITEM pItem = GetWear(i);
            if (pItem)
            {
                if (DSManager::instance().IsTimeLeftDragonSoul(pItem))
                    pItem->ModifyPoints(true,compute_point_status);//Fixed_[C]Martin_001
            }
        }
    }

    if (GetHP() > GetMaxHP())
        PointChange(POINT_HP, GetMaxHP() - GetHP(), false, false, compute_point_status);//Fixed_[C]Martin_001

    if (GetSP() > GetMaxSP())
        PointChange(POINT_SP, GetMaxSP() - GetSP(), false, false, compute_point_status);//Fixed_[C]Martin_001

    ComputeSkillPoints();

    RefreshAffect(compute_point_status);//Fixed_[C]Martin_001

    CPetSystem * pPetSystem = GetPetSystem();
    if (NULL != pPetSystem)
        pPetSystem->RefreshBuff(compute_point_status);//Fixed_[C]Martin_001

    // @fixme118 part2 (after petsystem stuff)
    if (IsPC())
    {
        if (this->GetHP() != iCurHP)
            this->PointChange(POINT_HP, iCurHP-this->GetHP(), false, false, compute_point_status);//Fixed_[C]Martin_001
        if (this->GetSP() != iCurSP)
            this->PointChange(POINT_SP, iCurSP-this->GetSP(), false, false, compute_point_status);//Fixed_[C]Martin_001
    }

    compute_point_status = false;//Fixed_[C]Martin_001

    if (GetDesc())//Fixed_[C]Martin_001
    {
        BYTE send_count = 0;
        auto it = compute_point_list.begin();
        for (; it != compute_point_list.end(); it++)
        {
            if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                continue;

            if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                || it->type == POINT_HP && comp_hp == it->val
                )
            {
                continue;
            }

            if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                || it->type == POINT_SP && comp_sp == it->val
                )
            {
                continue;
            }

            if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                || it->type == POINT_STAMINA && comp_stamina == it->val
                )
            {
                continue;
            }
            send_count++;
        }

        if (send_count == 1)
        {
            auto it = compute_point_list.begin();
            for (; it != compute_point_list.end(); it++)
            {
                if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                    continue;

                if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                    || it->type == POINT_HP && comp_hp == it->val
                    )
                {
                    continue;
                }

                if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                    || it->type == POINT_SP && comp_sp == it->val
                    )
                {
                    continue;
                }

                if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                    || it->type == POINT_STAMINA && comp_stamina == it->val
                    )
                {
                    continue;
                }

                struct packet_point_change pack;

                pack.header = HEADER_GC_CHARACTER_POINT_CHANGE;
                pack.dwVID = m_vid;
                pack.type = it->type;
                pack.value = it->val;

                pack.amount = it->amount;

                GetDesc()->Packet(&pack, sizeof(struct packet_point_change));
            }
        }
        else
        {
            if (send_count > 1)
            {
                TPacketGCPointChangeDynamic pack;

                pack.header = HEADER_GC_CHARACTER_POINT_CHANGE_DYNAMIC;
                pack.dwVID = m_vid;
                pack.count = send_count;

                TEMP_BUFFER buf;
                buf.write(&pack, sizeof(TPacketGCPointChangeDynamic));

                auto it = compute_point_list.begin();
                for (; it != compute_point_list.end(); it++)
                {
                    if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                        continue;

                    if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                        || it->type == POINT_HP && comp_hp == it->val
                        )
                    {
                        continue;
                    }

                    if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                        || it->type == POINT_SP && comp_sp == it->val
                        )
                    {
                        continue;
                    }

                    if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                        || it->type == POINT_STAMINA && comp_stamina == it->val
                        )
                    {
                        continue;
                    }

                    TPacketGCPointChangeDynamicVal pack_val;
                    pack_val.type = it->type;
                    pack_val.value = it->val;

                    pack_val.amount = it->amount;

                    buf.write(&pack_val, sizeof(TPacketGCPointChangeDynamicVal));
                }

                GetDesc()->Packet(buf.read_peek(), buf.size());
            }
        }
    }//Fixed_[C]Martin_001

    compute_point_list.clear();//Fixed_[C]Martin_001
    compute_point_list.shrink_to_fit();//Fixed_[C]Martin_001

    UpdatePacket();

    memset(m_pointsInstant.points_computepoint, 0, sizeof(m_pointsInstant.points_computepoint));//Fixed_[C]Martin_001
}


C++:
UYARI:

Bu bir deneysel optimizasyondur hiç bir aktif sunucu testi yapılmamıştır. localhost da test edilmiştir. bir sorun çıkmamıştır.

Cliente gönderilen değerler toplanıp tek pakette birleştirilmiştir her paket için 20 bayt yerine
bütün computepoint içinde geçen point işlemlerinin numaralarını kayıt edip tek bir dinamik paketle yollanmaktadır bunun sonucu 20*30 toplamı 600 bayt olan bir paketin birleşince 400 bayta düşmesi gözlemlenmiştir ve
bu sayede gereksiz python fonksiyonlarının tetiklenip oyunda kasma donma vb gibi durumlardada iyileşme olmuştur


aklıma takılan tek soru işareti paket büyümesi sonucu oyunculu bir sunucuda nasıl bir tepki vereceğidir
soket programlama konusunda bilgim biraz zayıf üst üste 30*20 bayt paket = 600 bayt yerine bunların birleşimi sonucu 400 500 bayt tek paket de birleşip yollanması [COLOR=rgb(250, 197, 28)]Update(maksimum 100 bayta düşüren güncelleme yayınlandı)[/COLOR]

bunu kullanacaklar computepoint çağrılarınızı gözden geçirmelisiniz olabildiğince en az computepoint kullanımı olmalı herhangi bir olumsuzluk durumuna karşı

yorumlara göre bu tarz optimizasyonların devamı gelecektir

yakında gelecek:
1. affect tablosunun optimizasyonu ve affectlerin cachelenmesi şu an sql sorgu üzerinden çalışıyor. her karakterde skil kullanınca bu tabloya sorgu gidiyor
2. karaktere giriş çıkışta giden gereksiz paketlerin optimizasyonu(tamamlandı. test ediliyor.)



NOT :

//Fixed_[C]Martin#2376_001

bunun bulunduğu yerleri kendinize göre uyarlıyorsunu
.h dosyasına diye yazdıklarımı da h dosyasının içinde uyarlıyorsunuz

ComputeBattlePoints
PointChange
ApplyPoint
ComputeAffect
RefreshAffect

üstteki yazdığım fonksiyonların içinde sizde ekstra olanları
//Fixed_[C]Martin#2376_001
ile geçen yerlerdeki uyarlamasına uygun şekilde uyarlayacaksınız


---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------

--------------------------- Server Source -------------------------

---------------------------------------------------------------------------------------------------------------


---------------------------------------------------------------------------------------------

-- Char.h ye class içinde uygun bir yere ekle

class CHARACTER : public CEntity, public CFSM, public CHorseRider
{

++++++++++++++
    private:
        bool compute_point_status;//Fixed_[C]Martin#2376_001
        typedef struct comput
        {
            BYTE type;
            int amount;
            int val;
        }Tcomput;//Fixed_[C]Martin#2376_001
        std::vector<Tcomput> compute_point_list;//Fixed_[C]Martin#2376_001

---------------------------------------------------------------------------------------------

-- Char.cpp fonksiyon içine uygun bir şekilde ekle

void CHARACTER::Initialize()
{

++++++++++++++++
compute_point_status = false;//Fixed_[C]Martin#2376_001

---------------------------------------------------------------------------------------------

-- Char.cpp //Fixed_[C]Martin#2376_001 bunları bul ve uygun şekilde kendine ekle yada düzenle bunları eklerken kodun uyumlu olduğunu kontrol edin

( char.h dosyasına )void            ComputeBattlePoints(bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CHARACTER::ComputeBattlePoints(bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    if (IsPolymorphed())
    {
        DWORD dwMobVnum = GetPolymorphVnum();
        const CMob * pMob = CMobManager::instance().Get(dwMobVnum);
        int iAtt = 0;
        int iDef = 0;

        if (pMob)
        {
            iAtt = GetLevel() * 2 + GetPolymorphPoint(POINT_ST) * 2;
            iDef = GetLevel() + GetPolymorphPoint(POINT_HT) + pMob->m_table.wDef;
        }

        SetPoint(POINT_ATT_GRADE, iAtt);
        SetPoint(POINT_DEF_GRADE, iDef);
        SetPoint(POINT_MAGIC_ATT_GRADE, GetPoint(POINT_ATT_GRADE));
        SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE));
    }
    else if (IsPC())
    {
        SetPoint(POINT_ATT_GRADE, 0);
        SetPoint(POINT_DEF_GRADE, 0);
        SetPoint(POINT_CLIENT_DEF_GRADE, 0);
        SetPoint(POINT_MAGIC_ATT_GRADE, GetPoint(POINT_ATT_GRADE));
        SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE));

        //
        // ATK = 2lev + 2str
        //
        int iAtk = GetLevel() * 2;
        int iStatAtk = 0;

        switch (GetJob())
        {
            case JOB_WARRIOR:
            case JOB_SURA:
                iStatAtk = (2 * GetPoint(POINT_ST));
                break;

            case JOB_ASSASSIN:
                iStatAtk = (4 * GetPoint(POINT_ST) + 2 * GetPoint(POINT_DX)) / 3;
                break;

            case JOB_SHAMAN:
                iStatAtk = (4 * GetPoint(POINT_ST) + 2 * GetPoint(POINT_IQ)) / 3;
                break;
            default:
                sys_err("invalid job %d", GetJob());
                iStatAtk = (2 * GetPoint(POINT_ST));
                break;
        }

        if (GetMountVnum() && iStatAtk < 2 * GetPoint(POINT_ST))
            iStatAtk = (2 * GetPoint(POINT_ST));

        iAtk += iStatAtk;

        if (GetMountVnum())
        {
            if (GetJob() == JOB_SURA && GetSkillGroup() == 1)
            {
                iAtk += (iAtk * GetHorseLevel()) / 60;
            }
            else
            {
                iAtk += (iAtk * GetHorseLevel()) / 30;
            }
        }

        //
        // ATK Setting
        //
        iAtk += GetPoint(POINT_ATT_GRADE_BONUS);

        PointChange(POINT_ATT_GRADE, iAtk, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

        // DEF = LEV + CON + ARMOR
        int iShowDef = GetLevel() + GetPoint(POINT_HT);
        int iDef = GetLevel() + (int) (GetPoint(POINT_HT) / 1.25); // For Other
        int iArmor = 0;

        LPITEM pkItem;

        for (int i = 0; i < WEAR_MAX_NUM; ++i)
            if ((pkItem = GetWear(i)) && pkItem->GetType() == ITEM_ARMOR)
            {
                if (pkItem->GetSubType() == ARMOR_BODY || pkItem->GetSubType() == ARMOR_HEAD || pkItem->GetSubType() == ARMOR_FOOTS || pkItem->GetSubType() == ARMOR_SHIELD)
                {
                    iArmor += pkItem->GetValue(1);
                    iArmor += (2 * pkItem->GetValue(5));
                }
            }

        if( true == IsHorseRiding() )
        {
            if (iArmor < GetHorseArmor())
                iArmor = GetHorseArmor();

            const char* pHorseName = CHorseNameManager::instance().GetHorseName(GetPlayerID());

            if (pHorseName != NULL && strlen(pHorseName))
            {
                iArmor += 20;
            }
        }

        iArmor += GetPoint(POINT_DEF_GRADE_BONUS);
        iArmor += GetPoint(POINT_PARTY_DEFENDER_BONUS);

        // INTERNATIONAL_VERSION
        PointChange(POINT_DEF_GRADE, iDef + iArmor, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        PointChange(POINT_CLIENT_DEF_GRADE, (iShowDef + iArmor) - GetPoint(POINT_DEF_GRADE), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        // END_OF_INTERNATIONAL_VERSION

        PointChange(POINT_MAGIC_ATT_GRADE, GetLevel() * 2 + GetPoint(POINT_IQ) * 2 + GetPoint(POINT_MAGIC_ATT_GRADE_BONUS), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        PointChange(POINT_MAGIC_DEF_GRADE, GetLevel() + (GetPoint(POINT_IQ) * 3 + GetPoint(POINT_HT)) / 3 + iArmor / 2 + GetPoint(POINT_MAGIC_DEF_GRADE_BONUS), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
    }
    else
    {
        // 2lev + str * 2
        int iAtt = GetLevel() * 2 + GetPoint(POINT_ST) * 2;
        // lev + con
        int iDef = GetLevel() + GetPoint(POINT_HT) + GetMobTable().wDef;

        SetPoint(POINT_ATT_GRADE, iAtt);
        SetPoint(POINT_DEF_GRADE, iDef);
        SetPoint(POINT_MAGIC_ATT_GRADE, GetPoint(POINT_ATT_GRADE));
        SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE));
    }
}

-----

void CHARACTER::ComputePoints()
{
    compute_point_status = true;//Fixed_[C]Martin#2376_001

    long lStat = GetPoint(POINT_STAT);
    long lStatResetCount = GetPoint(POINT_STAT_RESET_COUNT);
    long lSkillActive = GetPoint(POINT_SKILL);
    long lSkillSub = GetPoint(POINT_SUB_SKILL);
    long lSkillHorse = GetPoint(POINT_HORSE_SKILL);
    long lLevelStep = GetPoint(POINT_LEVEL_STEP);

    long lAttackerBonus = GetPoint(POINT_PARTY_ATTACKER_BONUS);
    long lTankerBonus = GetPoint(POINT_PARTY_TANKER_BONUS);
    long lBufferBonus = GetPoint(POINT_PARTY_BUFFER_BONUS);
    long lSkillMasterBonus = GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
    long lHasteBonus = GetPoint(POINT_PARTY_HASTE_BONUS);
    long lDefenderBonus = GetPoint(POINT_PARTY_DEFENDER_BONUS);

    long lHPRecovery = GetPoint(POINT_HP_RECOVERY);
    long lSPRecovery = GetPoint(POINT_SP_RECOVERY);

    memset(m_pointsInstant.points, 0, sizeof(m_pointsInstant.points));
    BuffOnAttr_ClearAll();
    m_SkillDamageBonus.clear();

    SetPoint(POINT_STAT, lStat);
    SetPoint(POINT_SKILL, lSkillActive);
    SetPoint(POINT_SUB_SKILL, lSkillSub);
    SetPoint(POINT_HORSE_SKILL, lSkillHorse);
    SetPoint(POINT_LEVEL_STEP, lLevelStep);
    SetPoint(POINT_STAT_RESET_COUNT, lStatResetCount);

    SetPoint(POINT_ST, GetRealPoint(POINT_ST));
    SetPoint(POINT_HT, GetRealPoint(POINT_HT));
    SetPoint(POINT_DX, GetRealPoint(POINT_DX));
    SetPoint(POINT_IQ, GetRealPoint(POINT_IQ));

    SetPart(PART_MAIN, GetOriginalPart(PART_MAIN));
    SetPart(PART_WEAPON, GetOriginalPart(PART_WEAPON));
    SetPart(PART_HEAD, GetOriginalPart(PART_HEAD));
    SetPart(PART_HAIR, GetOriginalPart(PART_HAIR));

    SetPoint(POINT_PARTY_ATTACKER_BONUS, lAttackerBonus);
    SetPoint(POINT_PARTY_TANKER_BONUS, lTankerBonus);
    SetPoint(POINT_PARTY_BUFFER_BONUS, lBufferBonus);
    SetPoint(POINT_PARTY_SKILL_MASTER_BONUS, lSkillMasterBonus);
    SetPoint(POINT_PARTY_HASTE_BONUS, lHasteBonus);
    SetPoint(POINT_PARTY_DEFENDER_BONUS, lDefenderBonus);

    SetPoint(POINT_HP_RECOVERY, lHPRecovery);
    SetPoint(POINT_SP_RECOVERY, lSPRecovery);

    // PC_BANG_ITEM_ADD
    SetPoint(POINT_PC_BANG_EXP_BONUS, 0);
    SetPoint(POINT_PC_BANG_DROP_BONUS, 0);
    // END_PC_BANG_ITEM_ADD

    int iMaxHP, iMaxSP;
    int iMaxStamina;

    if (IsPC())
    {
        iMaxHP = JobInitialPoints[GetJob()].max_hp + m_points.iRandomHP + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].hp_per_ht;
        iMaxSP = JobInitialPoints[GetJob()].max_sp + m_points.iRandomSP + GetPoint(POINT_IQ) * JobInitialPoints[GetJob()].sp_per_iq;
        iMaxStamina = JobInitialPoints[GetJob()].max_stamina + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].stamina_per_con;

        {
            CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_ADD_HP);

            if (NULL != pkSk)
            {
                pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_ADD_HP) / 100.0f);

                iMaxHP += static_cast<int>(pkSk->kPointPoly.Eval());
            }
        }

        SetPoint(POINT_MOV_SPEED,    100);
        SetPoint(POINT_ATT_SPEED,    100);
        PointChange(POINT_ATT_SPEED, GetPoint(POINT_PARTY_HASTE_BONUS), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        SetPoint(POINT_CASTING_SPEED,    100);
    }
    else
    {
        iMaxHP = m_pkMobData->m_table.dwMaxHP;
        iMaxSP = 0;
        iMaxStamina = 0;

        SetPoint(POINT_ATT_SPEED, m_pkMobData->m_table.sAttackSpeed);
        SetPoint(POINT_MOV_SPEED, m_pkMobData->m_table.sMovingSpeed);
        SetPoint(POINT_CASTING_SPEED, m_pkMobData->m_table.sAttackSpeed);
    }

    if (IsPC())
    {
        if (GetMountVnum())
        {
            if (GetHorseST() > GetPoint(POINT_ST))
                PointChange(POINT_ST, GetHorseST() - GetPoint(POINT_ST), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

            if (GetHorseDX() > GetPoint(POINT_DX))
                PointChange(POINT_DX, GetHorseDX() - GetPoint(POINT_DX), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

            if (GetHorseHT() > GetPoint(POINT_HT))
                PointChange(POINT_HT, GetHorseHT() - GetPoint(POINT_HT), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

            if (GetHorseIQ() > GetPoint(POINT_IQ))
                PointChange(POINT_IQ, GetHorseIQ() - GetPoint(POINT_IQ), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        }

    }

    ComputeBattlePoints(compute_point_status);//Fixed_[C]Martin#2376_001

    if (iMaxHP != GetMaxHP())
    {
        SetRealPoint(POINT_MAX_HP, iMaxHP);
    }

    PointChange(POINT_MAX_HP, 0, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

    if (iMaxSP != GetMaxSP())
    {
        SetRealPoint(POINT_MAX_SP, iMaxSP);
    }

    PointChange(POINT_MAX_SP, 0, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

    SetMaxStamina(iMaxStamina);
    // @fixme118 part1
    int iCurHP = this->GetHP();
    int iCurSP = this->GetSP();

    m_pointsInstant.dwImmuneFlag = 0;

    for (int i = 0 ; i < WEAR_MAX_NUM; i++)
    {
        LPITEM pItem = GetWear(i);
        if (pItem)
        {
            pItem->ModifyPoints(true, compute_point_status);//Fixed_[C]Martin#2376_001
            SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
        }
    }

    if (DragonSoul_IsDeckActivated())
    {
        for (int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck();
            i < WEAR_MAX_NUM + DS_SLOT_MAX * (DragonSoul_GetActiveDeck() + 1); i++)
        {
            LPITEM pItem = GetWear(i);
            if (pItem)
            {
                if (DSManager::instance().IsTimeLeftDragonSoul(pItem))
                    pItem->ModifyPoints(true, compute_point_status);//Fixed_[C]Martin#2376_001
            }
        }
    }

    if (GetHP() > GetMaxHP())
        PointChange(POINT_HP, GetMaxHP() - GetHP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

    if (GetSP() > GetMaxSP())
        PointChange(POINT_SP, GetMaxSP() - GetSP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

    ComputeSkillPoints();

    RefreshAffect(compute_point_status);//Fixed_[C]Martin#2376_001

    CPetSystem * pPetSystem = GetPetSystem();
    if (NULL != pPetSystem)
        pPetSystem->RefreshBuff(compute_point_status);//Fixed_[C]Martin#2376_001

    // @fixme118 part2 (after petsystem stuff)
    if (IsPC())
    {
        if (this->GetHP() != iCurHP)
            this->PointChange(POINT_HP, iCurHP-this->GetHP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
        if (this->GetSP() != iCurSP)
            this->PointChange(POINT_SP, iCurSP-this->GetSP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
    }

    compute_point_status = false;//Fixed_[C]Martin#2376_001

    if (GetDesc())//Fixed_[C]Martin#2376_001
    {
        TPacketGCPointChangeDynamic pack;

        pack.header = HEADER_GC_CHARACTER_POINT_CHANGE_DYNAMIC;
        pack.dwVID = m_vid;
        pack.count = compute_point_list.size();

        TEMP_BUFFER buf;
        buf.write(&pack, sizeof(TPacketGCPointChangeDynamic));

        auto it = compute_point_list.begin();
        for (; it != compute_point_list.end(); it++)
        {
            TPacketGCPointChangeDynamicVal pack_val;
            pack_val.type = it->type;
            pack_val.value = it->val;

            pack_val.amount = it->amount;

            buf.write(&pack_val, sizeof(TPacketGCPointChangeDynamicVal));
        }

        GetDesc()->Packet(buf.read_peek(), buf.size());
    }//Fixed_[C]Martin#2376_001

    compute_point_list.clear();//Fixed_[C]Martin#2376_001
    compute_point_list.shrink_to_fit();//Fixed_[C]Martin#2376_001

    UpdatePacket();
}

----

( char.h dosyasına )void            PointChange(BYTE type, int amount, bool bAmount = false, bool bBroadcast = false, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast, bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    int val = 0;

    //sys_log(0, "PointChange %d %d | %d -> %d cHP %d mHP %d", type, amount, GetPoint(type), GetPoint(type)+amount, GetHP(), GetMaxHP());

    switch (type)
    {
        case POINT_NONE:
            return;

        case POINT_LEVEL:
            if ((GetLevel() + amount) > gPlayerMaxLevel)
                return;

            SetLevel(GetLevel() + amount);
            val = GetLevel();

            sys_log(0, "LEVELUP: %s %d NEXT EXP %d", GetName(), GetLevel(), GetNextExp());

            PointChange(POINT_NEXT_EXP,    GetNextExp(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

            if (amount)
            {
                quest::CQuestManager::instance().LevelUp(GetPlayerID());

                LogManager::instance().LevelLog(this, val, GetRealPoint(POINT_PLAYTIME) + (get_dword_time() - m_dwPlayStartTime) / 60000);

                if (GetGuild())
                {
                    GetGuild()->LevelChange(GetPlayerID(), GetLevel());
                }

                if (GetParty())
                {
                    GetParty()->RequestSetMemberLevel(GetPlayerID(), GetLevel());
                }
            }
            break;

        case POINT_NEXT_EXP:
            val = GetNextExp();
            bAmount = false;
            break;

        case POINT_EXP:
            {
                DWORD exp = GetExp();
                DWORD next_exp = GetNextExp();

                if ((amount < 0) && (exp < (DWORD)(-amount)))
                {
                    sys_log(1, "%s AMOUNT < 0 %d, CUR EXP: %d", GetName(), -amount, exp);
                    amount = -exp;

                    SetExp(exp + amount);
                    val = GetExp();
                }
                else
                {
                    if (gPlayerMaxLevel <= GetLevel())
                        return;

                    if (test_server)
                        ChatPacket(CHAT_TYPE_INFO, "You have gained %d exp.", amount);

                    DWORD iExpBalance = 0;

                    if (exp + amount >= next_exp)
                    {
                        iExpBalance = (exp + amount) - next_exp;
                        amount = next_exp - exp;

                        SetExp(0);
                        exp = next_exp;
                    }
                    else
                    {
                        SetExp(exp + amount);
                        exp = GetExp();
                    }

                    DWORD q = DWORD(next_exp / 4.0f);
                    int iLevStep = GetRealPoint(POINT_LEVEL_STEP);

                    if (iLevStep >= 4)
                    {
                        sys_err("%s LEVEL_STEP bigger than 4! (%d)", GetName(), iLevStep);
                        iLevStep = 4;
                    }

                    if (exp >= next_exp && iLevStep < 4)
                    {
                        for (int i = 0; i < 4 - iLevStep; ++i)
                            PointChange(POINT_LEVEL_STEP, 1, false, true, compute_point_status);//Fixed_[C]Martin#2376_001
                    }
                    else if (exp >= q * 3 && iLevStep < 3)
                    {
                        for (int i = 0; i < 3 - iLevStep; ++i)
                            PointChange(POINT_LEVEL_STEP, 1, false, true, compute_point_status);//Fixed_[C]Martin#2376_001
                    }
                    else if (exp >= q * 2 && iLevStep < 2)
                    {
                        for (int i = 0; i < 2 - iLevStep; ++i)
                            PointChange(POINT_LEVEL_STEP, 1, false, true, compute_point_status);//Fixed_[C]Martin#2376_001
                    }
                    else if (exp >= q && iLevStep < 1)
                        PointChange(POINT_LEVEL_STEP, 1, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

                    if (iExpBalance)
                    {
                        PointChange(POINT_EXP, iExpBalance, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                    }

                    val = GetExp();
                }
            }
            break;

        case POINT_LEVEL_STEP:
            if (amount > 0)
            {
                val = GetPoint(POINT_LEVEL_STEP) + amount;

                switch (val)
                {
                    case 1:
                    case 2:
                    case 3:
                        if ((GetLevel() <= g_iStatusPointGetLevelLimit) &&
                            (GetLevel() <= gPlayerMaxLevel) ) // @fixme104
                            PointChange(POINT_STAT, 1, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                        break;

                    case 4:
                        {
                            int iHP = number(JobInitialPoints[GetJob()].hp_per_lv_begin, JobInitialPoints[GetJob()].hp_per_lv_end);
                            int iSP = number(JobInitialPoints[GetJob()].sp_per_lv_begin, JobInitialPoints[GetJob()].sp_per_lv_end);

                            m_points.iRandomHP += iHP;
                            m_points.iRandomSP += iSP;

                            if (GetSkillGroup())
                            {
                                if (GetLevel() >= 5)
                                    PointChange(POINT_SKILL, 1, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

                                if (GetLevel() >= 9)
                                    PointChange(POINT_SUB_SKILL, 1, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                            }

                            PointChange(POINT_MAX_HP, iHP, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                            PointChange(POINT_MAX_SP, iSP, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                            PointChange(POINT_LEVEL, 1, false, true, compute_point_status);//Fixed_[C]Martin#2376_001

                            val = 0;
                        }
                        break;
                }

                if (GetLevel() <= 10)
                    AutoGiveItem(27001, 2);
                else if (GetLevel() <= 30)
                    AutoGiveItem(27002, 2);
                else
                {
                    AutoGiveItem(27002, 2);
//                    AutoGiveItem(27003, 2);
                }

                PointChange(POINT_HP, GetMaxHP() - GetHP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                PointChange(POINT_SP, GetMaxSP() - GetSP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                PointChange(POINT_STAMINA, GetMaxStamina() - GetStamina(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001

                SetPoint(POINT_LEVEL_STEP, val);
                SetRealPoint(POINT_LEVEL_STEP, val);

                Save();
            }
            else
                val = GetPoint(POINT_LEVEL_STEP);

            break;

        case POINT_HP:
            {
                if (IsDead() || IsStun())
                    return;

                int prev_hp = GetHP();

                amount = MIN(GetMaxHP() - GetHP(), amount);
                SetHP(GetHP() + amount);
                val = GetHP();

                BroadcastTargetPacket();

                if (GetParty() && IsPC() && val != prev_hp)
                    GetParty()->SendPartyInfoOneToAll(this);
            }
            break;

        case POINT_SP:
            {
                if (IsDead() || IsStun())
                    return;

                amount = MIN(GetMaxSP() - GetSP(), amount);
                SetSP(GetSP() + amount);
                val = GetSP();
            }
            break;

        case POINT_STAMINA:
            {
                if (IsDead() || IsStun())
                    return;

                int prev_val = GetStamina();
                amount = MIN(GetMaxStamina() - GetStamina(), amount);
                SetStamina(GetStamina() + amount);
                val = GetStamina();

                if (val == 0)
                {
                    // Stamina
                    SetNowWalking(true);
                }
                else if (prev_val == 0)
                {
                    ResetWalking();
                }

                if (amount < 0 && val != 0)
                    return;
            }
            break;

        case POINT_MAX_HP:
            {
                SetPoint(type, GetPoint(type) + amount);

                //SetMaxHP(GetMaxHP() + amount);
                int hp = GetRealPoint(POINT_MAX_HP);
                int add_hp = MIN(3500, hp * GetPoint(POINT_MAX_HP_PCT) / 100);
                add_hp += GetPoint(POINT_MAX_HP);
                add_hp += GetPoint(POINT_PARTY_TANKER_BONUS);

                SetMaxHP(hp + add_hp);

                val = GetMaxHP();
            }
            break;

        case POINT_MAX_SP:
            {
                SetPoint(type, GetPoint(type) + amount);

                //SetMaxSP(GetMaxSP() + amount);
                int sp = GetRealPoint(POINT_MAX_SP);
                int add_sp = MIN(800, sp * GetPoint(POINT_MAX_SP_PCT) / 100);
                add_sp += GetPoint(POINT_MAX_SP);
                add_sp += GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);

                SetMaxSP(sp + add_sp);

                val = GetMaxSP();
            }
            break;

        case POINT_MAX_HP_PCT:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);

            PointChange(POINT_MAX_HP, 0, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        case POINT_MAX_SP_PCT:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);

            PointChange(POINT_MAX_SP, 0, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        case POINT_MAX_STAMINA:
            SetMaxStamina(GetMaxStamina() + amount);
            val = GetMaxStamina();
            break;

        case POINT_GOLD:
            {
                const int64_t nTotalMoney = static_cast<int64_t>(GetGold()) + static_cast<int64_t>(amount);

                if (GOLD_MAX <= nTotalMoney)
                {
                    sys_err("[OVERFLOW_GOLD] OriGold %d AddedGold %d id %u Name %s ", GetGold(), amount, GetPlayerID(), GetName());
                    LogManager::instance().CharLog(this, GetGold() + amount, "OVERFLOW_GOLD", "");
                    return;
                }

                SetGold(GetGold() + amount);
                val = GetGold();
            }
            break;

        case POINT_SKILL:
        case POINT_STAT:
        case POINT_SUB_SKILL:
        case POINT_STAT_RESET_COUNT:
        case POINT_HORSE_SKILL:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);

            SetRealPoint(type, val);
            break;

        case POINT_DEF_GRADE:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);

            PointChange(POINT_CLIENT_DEF_GRADE, amount, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        case POINT_CLIENT_DEF_GRADE:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            break;

        case POINT_ST:
        case POINT_HT:
        case POINT_DX:
        case POINT_IQ:
        case POINT_HP_REGEN:
        case POINT_SP_REGEN:
        case POINT_ATT_SPEED:
        case POINT_ATT_GRADE:
        case POINT_MOV_SPEED:
        case POINT_CASTING_SPEED:
        case POINT_MAGIC_ATT_GRADE:
        case POINT_MAGIC_DEF_GRADE:
        case POINT_BOW_DISTANCE:
        case POINT_HP_RECOVERY:
        case POINT_SP_RECOVERY:

        case POINT_ATTBONUS_HUMAN:    // 42
        case POINT_ATTBONUS_ANIMAL:    // 43
        case POINT_ATTBONUS_ORC:    // 44
        case POINT_ATTBONUS_MILGYO:    // 45
        case POINT_ATTBONUS_UNDEAD:    // 46
        case POINT_ATTBONUS_DEVIL:    // 47

        case POINT_ATTBONUS_MONSTER:
        case POINT_ATTBONUS_SURA:
        case POINT_ATTBONUS_ASSASSIN:
        case POINT_ATTBONUS_WARRIOR:
        case POINT_ATTBONUS_SHAMAN:

        case POINT_POISON_PCT:

        case POINT_STUN_PCT:
        case POINT_SLOW_PCT:

        case POINT_BLOCK:
        case POINT_DODGE:

        case POINT_CRITICAL_PCT:
        case POINT_RESIST_CRITICAL:
        case POINT_PENETRATE_PCT:
        case POINT_RESIST_PENETRATE:
        case POINT_CURSE_PCT:

        case POINT_STEAL_HP:        // 48
        case POINT_STEAL_SP:        // 49

        case POINT_MANA_BURN_PCT:    // 50
        case POINT_DAMAGE_SP_RECOVER:    // 51
        case POINT_RESIST_NORMAL_DAMAGE:
        case POINT_RESIST_SWORD:
        case POINT_RESIST_TWOHAND:
        case POINT_RESIST_DAGGER:
        case POINT_RESIST_BELL:
        case POINT_RESIST_FAN:
        case POINT_RESIST_BOW:

        case POINT_RESIST_FIRE:
        case POINT_RESIST_ELEC:
        case POINT_RESIST_MAGIC:
        case POINT_RESIST_WIND:
        case POINT_RESIST_ICE:
        case POINT_RESIST_EARTH:
        case POINT_RESIST_DARK:
        case POINT_REFLECT_MELEE:    // 67
        case POINT_REFLECT_CURSE:    // 68
        case POINT_POISON_REDUCE:    // 69

        case POINT_KILL_SP_RECOVER:    // 70
        case POINT_KILL_HP_RECOVERY:    // 75
        case POINT_HIT_HP_RECOVERY:
        case POINT_HIT_SP_RECOVERY:
        case POINT_MANASHIELD:
        case POINT_ATT_BONUS:
        case POINT_DEF_BONUS:
        case POINT_SKILL_DAMAGE_BONUS:
        case POINT_NORMAL_HIT_DAMAGE_BONUS:

            // DEPEND_BONUS_ATTRIBUTES
        case POINT_SKILL_DEFEND_BONUS:
        case POINT_NORMAL_HIT_DEFEND_BONUS:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            break;
            // END_OF_DEPEND_BONUS_ATTRIBUTES

        case POINT_PARTY_ATTACKER_BONUS:
        case POINT_PARTY_TANKER_BONUS:
        case POINT_PARTY_BUFFER_BONUS:
        case POINT_PARTY_SKILL_MASTER_BONUS:
        case POINT_PARTY_HASTE_BONUS:
        case POINT_PARTY_DEFENDER_BONUS:

        case POINT_RESIST_WARRIOR :
        case POINT_RESIST_ASSASSIN :
        case POINT_RESIST_SURA :
        case POINT_RESIST_SHAMAN :

            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            break;

        case POINT_MALL_ATTBONUS:
        case POINT_MALL_DEFBONUS:
        case POINT_MALL_EXPBONUS:
        case POINT_MALL_ITEMBONUS:
        case POINT_MALL_GOLDBONUS:
        case POINT_MELEE_MAGIC_ATT_BONUS_PER:
            if (GetPoint(type) + amount > 100)
            {
                sys_err("MALL_BONUS exceeded over 100!! point type: %d name: %s amount %d", type, GetName(), amount);
                amount = 100 - GetPoint(type);
            }

            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            break;

            // PC_BANG_ITEM_ADD
        case POINT_PC_BANG_EXP_BONUS :
        case POINT_PC_BANG_DROP_BONUS :
        case POINT_RAMADAN_CANDY_BONUS_EXP:
            SetPoint(type, amount);
            val = GetPoint(type);
            break;
            // END_PC_BANG_ITEM_ADD

        case POINT_EXP_DOUBLE_BONUS:    // 71
        case POINT_GOLD_DOUBLE_BONUS:    // 72
        case POINT_ITEM_DROP_BONUS:    // 73
        case POINT_POTION_BONUS:    // 74
            if (GetPoint(type) + amount > 100)
            {
                sys_err("BONUS exceeded over 100!! point type: %d name: %s amount %d", type, GetName(), amount);
                amount = 100 - GetPoint(type);
            }

            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            break;

        case POINT_IMMUNE_STUN:        // 76
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            if (val)
            {
                // ChatPacket(CHAT_TYPE_INFO, "IMMUNE_STUN SET_BIT type(%u) amount(%d)", type, amount);
                SET_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_STUN);
            }
            else
            {
                // ChatPacket(CHAT_TYPE_INFO, "IMMUNE_STUN REMOVE_BIT type(%u) amount(%d)", type, amount);
                REMOVE_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_STUN);
            }
            break;

        case POINT_IMMUNE_SLOW:        // 77
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            if (val)
            {
                SET_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_SLOW);
            }
            else
            {
                REMOVE_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_SLOW);
            }
            break;

        case POINT_IMMUNE_FALL:    // 78
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            if (val)
            {
                SET_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_FALL);
            }
            else
            {
                REMOVE_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_FALL);
            }
            break;

        case POINT_ATT_GRADE_BONUS:
            SetPoint(type, GetPoint(type) + amount);
            PointChange(POINT_ATT_GRADE, amount, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            val = GetPoint(type);
            break;

        case POINT_DEF_GRADE_BONUS:
            SetPoint(type, GetPoint(type) + amount);
            PointChange(POINT_DEF_GRADE, amount, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            val = GetPoint(type);
            break;

        case POINT_MAGIC_ATT_GRADE_BONUS:
            SetPoint(type, GetPoint(type) + amount);
            PointChange(POINT_MAGIC_ATT_GRADE, amount, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            val = GetPoint(type);
            break;

        case POINT_MAGIC_DEF_GRADE_BONUS:
            SetPoint(type, GetPoint(type) + amount);
            PointChange(POINT_MAGIC_DEF_GRADE, amount, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            val = GetPoint(type);
            break;

        case POINT_VOICE:
        case POINT_EMPIRE_POINT:
            //sys_err("CHARACTER::PointChange: %s: point cannot be changed. use SetPoint instead (type: %d)", GetName(), type);
            val = GetRealPoint(type);
            break;

        case POINT_POLYMORPH:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            SetPolymorph(val);
            break;

        case POINT_MOUNT:
            SetPoint(type, GetPoint(type) + amount);
            val = GetPoint(type);
            MountVnum(val);
            break;

        case POINT_ENERGY:
        case POINT_COSTUME_ATTR_BONUS:
            {
                int old_val = GetPoint(type);
                SetPoint(type, old_val + amount);
                val = GetPoint(type);
                BuffOnAttr_ValueChange(type, old_val, val);
            }
            break;

        default:
            sys_err("CHARACTER::PointChange: %s: unknown point change type %d", GetName(), type);
            return;
    }

    switch (type)
    {
        case POINT_LEVEL:
        case POINT_ST:
        case POINT_DX:
        case POINT_IQ:
        case POINT_HT:
            ComputeBattlePoints(compute_point_status);//Fixed_[C]Martin#2376_001
            break;
        case POINT_MAX_HP:
        case POINT_MAX_SP:
        case POINT_MAX_STAMINA:
            break;
    }

    if (type == POINT_HP && amount == 0)
        return;

    if (compute_point_status)//Fixed_[C]Martin#2376_001
    {
        bool valid = false;
        for (std::vector<Tcomput>::iterator it = compute_point_list.begin(); it != compute_point_list.end(); it++)
        {
            if (it->type == type)
            {
                if (bAmount)
                    it->amount = amount;
                else
                    it->amount = 0;

                it->val = val;

                valid = true;
            }
        }
        if (!valid)
        {
            Tcomput ins;

            ins.type = type;

            if (bAmount)
                ins.amount = amount;
            else
                ins.amount = 0;

            ins.val = val;

            compute_point_list.push_back(ins);
        }
    }//Fixed_[C]Martin#2376_001

    if (GetDesc() && !compute_point_status)//Fixed_[C]Martin#2376_001
    {
        struct packet_point_change pack;

        pack.header = HEADER_GC_CHARACTER_POINT_CHANGE;
        pack.dwVID = m_vid;
        pack.type = type;
        pack.value = val;

        if (bAmount)
            pack.amount = amount;
        else
            pack.amount = 0;

        if (!bBroadcast)
            GetDesc()->Packet(&pack, sizeof(struct packet_point_change));
        else
            PacketAround(&pack, sizeof(pack));
    }
}

----------

( char.h dosyasına )void            ApplyPoint(BYTE bApplyType, int iVal, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CHARACTER::ApplyPoint(BYTE bApplyType, int iVal, bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    switch (bApplyType)
    {
        case APPLY_NONE:            // 0
            break;;

        case APPLY_CON:
            PointChange(POINT_HT, iVal, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            PointChange(POINT_MAX_HP, (iVal * JobInitialPoints[GetJob()].hp_per_ht), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            PointChange(POINT_MAX_STAMINA, (iVal * JobInitialPoints[GetJob()].stamina_per_con), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        case APPLY_INT:
            PointChange(POINT_IQ, iVal, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            PointChange(POINT_MAX_SP, (iVal * JobInitialPoints[GetJob()].sp_per_iq), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        case APPLY_SKILL:
            // SKILL_DAMAGE_BONUS
            {
                // 00000000 00000000 00000000 00000000

                // vnum     ^ add       change
                BYTE bSkillVnum = (BYTE) (((DWORD)iVal) >> 24);
                int iAdd = iVal & 0x00800000;
                int iChange = iVal & 0x007fffff;

                sys_log(1, "APPLY_SKILL skill %d add? %d change %d", bSkillVnum, iAdd ? 1 : 0, iChange);

                if (0 == iAdd)
                    iChange = -iChange;

                boost::unordered_map<BYTE, int>::iterator iter = m_SkillDamageBonus.find(bSkillVnum);

                if (iter == m_SkillDamageBonus.end())
                    m_SkillDamageBonus.insert(std::make_pair(bSkillVnum, iChange));
                else
                    iter->second += iChange;
            }
            // END_OF_SKILL_DAMAGE_BONUS
            break;

        case APPLY_MAX_HP:
        case APPLY_MAX_HP_PCT:
            {
                int i = GetMaxHP(); if(i == 0) break;
                PointChange(aApplyInfo[bApplyType].bPointType, iVal, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                float fRatio = (float)GetMaxHP() / (float)i;
                PointChange(POINT_HP, GetHP() * fRatio - GetHP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            }
            break;

        case APPLY_MAX_SP:
        case APPLY_MAX_SP_PCT:
            {
                int i = GetMaxSP(); if(i == 0) break;
                PointChange(aApplyInfo[bApplyType].bPointType, iVal, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
                float fRatio = (float)GetMaxSP() / (float)i;
                PointChange(POINT_SP, GetSP() * fRatio - GetSP(), false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            }
            break;

        case APPLY_STR:
        case APPLY_DEX:
        case APPLY_ATT_SPEED:
        case APPLY_MOV_SPEED:
        case APPLY_CAST_SPEED:
        case APPLY_HP_REGEN:
        case APPLY_SP_REGEN:
        case APPLY_POISON_PCT:

        case APPLY_STUN_PCT:
        case APPLY_SLOW_PCT:
        case APPLY_CRITICAL_PCT:
        case APPLY_PENETRATE_PCT:
        case APPLY_ATTBONUS_HUMAN:
        case APPLY_ATTBONUS_ANIMAL:
        case APPLY_ATTBONUS_ORC:
        case APPLY_ATTBONUS_MILGYO:
        case APPLY_ATTBONUS_UNDEAD:
        case APPLY_ATTBONUS_DEVIL:
        case APPLY_ATTBONUS_WARRIOR:    // 59
        case APPLY_ATTBONUS_ASSASSIN:    // 60
        case APPLY_ATTBONUS_SURA:    // 61
        case APPLY_ATTBONUS_SHAMAN:    // 62

        case APPLY_ATTBONUS_MONSTER:    // 63
        case APPLY_STEAL_HP:
        case APPLY_STEAL_SP:
        case APPLY_MANA_BURN_PCT:
        case APPLY_DAMAGE_SP_RECOVER:
        case APPLY_BLOCK:
        case APPLY_DODGE:
        case APPLY_RESIST_SWORD:
        case APPLY_RESIST_TWOHAND:
        case APPLY_RESIST_DAGGER:
        case APPLY_RESIST_BELL:
        case APPLY_RESIST_FAN:
        case APPLY_RESIST_BOW:

        case APPLY_RESIST_FIRE:
        case APPLY_RESIST_ELEC:
        case APPLY_RESIST_MAGIC:
        case APPLY_RESIST_WIND:
        case APPLY_RESIST_ICE:
        case APPLY_RESIST_EARTH:
        case APPLY_RESIST_DARK:
        case APPLY_REFLECT_MELEE:
        case APPLY_REFLECT_CURSE:
        case APPLY_ANTI_CRITICAL_PCT:
        case APPLY_ANTI_PENETRATE_PCT:
        case APPLY_POISON_REDUCE:

        case APPLY_KILL_SP_RECOVER:
        case APPLY_EXP_DOUBLE_BONUS:
        case APPLY_GOLD_DOUBLE_BONUS:
        case APPLY_ITEM_DROP_BONUS:
        case APPLY_POTION_BONUS:
        case APPLY_KILL_HP_RECOVER:
        case APPLY_IMMUNE_STUN:
        case APPLY_IMMUNE_SLOW:
        case APPLY_IMMUNE_FALL:
        case APPLY_BOW_DISTANCE:
        case APPLY_ATT_GRADE_BONUS:
        case APPLY_DEF_GRADE_BONUS:
        case APPLY_MAGIC_ATT_GRADE:
        case APPLY_MAGIC_DEF_GRADE:
        case APPLY_CURSE_PCT:
        case APPLY_MAX_STAMINA:
        case APPLY_MALL_ATTBONUS:
        case APPLY_MALL_DEFBONUS:
        case APPLY_MALL_EXPBONUS:
        case APPLY_MALL_ITEMBONUS:
        case APPLY_MALL_GOLDBONUS:
        case APPLY_SKILL_DAMAGE_BONUS:
        case APPLY_NORMAL_HIT_DAMAGE_BONUS:

            // DEPEND_BONUS_ATTRIBUTES
        case APPLY_SKILL_DEFEND_BONUS:
        case APPLY_NORMAL_HIT_DEFEND_BONUS:
            // END_OF_DEPEND_BONUS_ATTRIBUTES

        case APPLY_PC_BANG_EXP_BONUS :
        case APPLY_PC_BANG_DROP_BONUS :

        case APPLY_RESIST_WARRIOR :
        case APPLY_RESIST_ASSASSIN :
        case APPLY_RESIST_SURA :
        case APPLY_RESIST_SHAMAN :

        case APPLY_ENERGY:                    // 82
        case APPLY_DEF_GRADE:                // 83
        case APPLY_COSTUME_ATTR_BONUS:        // 84
        case APPLY_MAGIC_ATTBONUS_PER:        // 85
        case APPLY_MELEE_MAGIC_ATTBONUS_PER:            // 86

            PointChange(aApplyInfo[bApplyType].bPointType, iVal, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
            break;

        default:
            sys_err("Unknown apply type %d name %s", bApplyType, GetName());
            break;
    }
}

--------------------------------------------------

-- Char_affect.cpp

++++++++++

( char.h dosyasına )void            RefreshAffect(bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CHARACTER::RefreshAffect(bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    itertype(m_list_pkAffect) it = m_list_pkAffect.begin();

    while (it != m_list_pkAffect.end())
    {
        CAffect * pkAff = *it++;
        ComputeAffect(pkAff, true, compute_point_status);
    }
}

( char.h dosyasına )void            ComputeAffect(CAffect * pkAff, bool bAdd, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd, bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
    {
        if (!GetGuild())
            return;

        if (!GetGuild()->UnderAnyWar())
            return;
    }

    if (pkAff->dwFlag)
    {
        if (!bAdd)
            m_afAffectFlag.Reset(pkAff->dwFlag);
        else
            m_afAffectFlag.Set(pkAff->dwFlag);
    }

    if (bAdd)
        PointChange(pkAff->bApplyOn, pkAff->lApplyValue, false, false, compute_point_status);//Fixed_[C]Martin#2376_001
    else
        PointChange(pkAff->bApplyOn, -pkAff->lApplyValue, false, false, compute_point_status);//Fixed_[C]Martin#2376_001

    if (pkAff->dwType == SKILL_MUYEONG)
    {
        if (bAdd)
            StartMuyeongEvent();
        else
            StopMuyeongEvent();
    }
}

-----------------------------------------------------------

-- item.cpp

NOT : Kuşak kullananlar buradaki ApplyPoint kodlarını benim düzenlediğim gibi ModifyPoints içerisindeki hepsini düzenlemeniz kerekiyor

++++++++

( item.h dosyasına )void        ModifyPoints(bool bAdd, bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CItem::ModifyPoints(bool bAdd, bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    int accessoryGrade;


    if (false == IsAccessoryForSocket())
    {
        if (m_pProto->bType == ITEM_WEAPON || m_pProto->bType == ITEM_ARMOR)
        {

            for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
            {
                DWORD dwVnum;

                if ((dwVnum = GetSocket(i)) <= 2)
                    continue;

                TItemTable * p = ITEM_MANAGER::instance().GetTable(dwVnum);

                if (!p)
                {
                    sys_err("cannot find table by vnum %u", dwVnum);
                    continue;
                }

                if (ITEM_METIN == p->bType)
                {
                    //m_pOwner->ApplyPoint(p->alValues[0], bAdd ? p->alValues[1] : -p->alValues[1]);
                    for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
                    {
                        if (p->aApplies[i].bType == APPLY_NONE)
                            continue;

                        if (p->aApplies[i].bType == APPLY_SKILL)
                            m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : p->aApplies[i].lValue ^ 0x00800000, compute_point_status);//Fixed_[C]Martin#2376_001
                        else
                            m_pOwner->ApplyPoint(p->aApplies[i].bType, bAdd ? p->aApplies[i].lValue : -p->aApplies[i].lValue, compute_point_status);//Fixed_[C]Martin#2376_001
                    }
                }
            }
        }

        accessoryGrade = 0;
    }
    else
    {
        accessoryGrade = MIN(GetAccessorySocketGrade(), ITEM_ACCESSORY_SOCKET_MAX_NUM);
    }

    for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
    {
        if (m_pProto->aApplies[i].bType == APPLY_NONE)
            continue;

        long value = m_pProto->aApplies[i].lValue;
        if (m_pProto->aApplies[i].bType == APPLY_SKILL)
        {
            m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : value ^ 0x00800000, compute_point_status);//Fixed_[C]Martin#2376_001
        }
        else
        {
            if (0 != accessoryGrade)
                value += MAX(accessoryGrade, value * aiAccessorySocketEffectivePct[accessoryGrade] / 100);

            m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : -value, compute_point_status);//Fixed_[C]Martin#2376_001
        }
    }

    if (true == CItemVnumHelper::IsRamadanMoonRing(GetVnum()) || true == CItemVnumHelper::IsHalloweenCandy(GetVnum())
        || true == CItemVnumHelper::IsHappinessRing(GetVnum()) || true == CItemVnumHelper::IsLovePendant(GetVnum()))
    {
        // Do not anything.
    }
    else
    {
        for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
        {
            if (GetAttributeType(i))
            {
                const TPlayerItemAttribute& ia = GetAttribute(i);

                if (ia.bType == APPLY_SKILL)
                    m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : ia.sValue ^ 0x00800000, compute_point_status);//Fixed_[C]Martin#2376_001
                else
                    m_pOwner->ApplyPoint(ia.bType, bAdd ? ia.sValue : -ia.sValue, compute_point_status);//Fixed_[C]Martin#2376_001

            }
        }
    }

    switch (m_pProto->bType)
    {
        case ITEM_PICK:
        case ITEM_ROD:
            {
                if (bAdd)
                {
                    if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
                        m_pOwner->SetPart(PART_WEAPON, GetVnum());
                }
                else
                {
                    if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
                        m_pOwner->SetPart(PART_WEAPON, 0);
                }
            }
            break;

        case ITEM_WEAPON:
            {

                if (bAdd)
                {
                    if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
                        m_pOwner->SetPart(PART_WEAPON, GetVnum());
                }
                else
                {
                    if (m_wCell == INVENTORY_MAX_NUM + WEAR_WEAPON)
                        m_pOwner->SetPart(PART_WEAPON, 0);
                }
            }
            break;

        case ITEM_ARMOR:
            {

                if (0 != m_pOwner->GetWear(WEAR_COSTUME_BODY))
                    break;

                if (GetSubType() == ARMOR_BODY || GetSubType() == ARMOR_HEAD || GetSubType() == ARMOR_FOOTS || GetSubType() == ARMOR_SHIELD)
                {
                    if (bAdd)
                    {
                        if (GetProto()->bSubType == ARMOR_BODY)
                            m_pOwner->SetPart(PART_MAIN, GetVnum());
                    }
                    else
                    {
                        if (GetProto()->bSubType == ARMOR_BODY)
                            m_pOwner->SetPart(PART_MAIN, m_pOwner->GetOriginalPart(PART_MAIN));
                    }
                }
            }
            break;


        case ITEM_COSTUME:
            {
                DWORD toSetValue = this->GetVnum();
                EParts toSetPart = PART_MAX_NUM;


                if (GetSubType() == COSTUME_BODY)
                {
                    toSetPart = PART_MAIN;

                    if (false == bAdd)
                    {

                        const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY);
                        toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN);
                    }
                }

                else if (GetSubType() == COSTUME_HAIR)
                {
                    toSetPart = PART_HAIR;
                    toSetValue = (true == bAdd) ? this->GetValue(3) : 0;
                }

                if (PART_MAX_NUM != toSetPart)
                {
                    m_pOwner->SetPart((BYTE)toSetPart, toSetValue);
                    if (!compute_point_status)//Fixed_[C]Martin#2376_001
                        m_pOwner->UpdatePacket();
                }
            }
            break;
        case ITEM_UNIQUE:
            {
                if (0 != GetSIGVnum())
                {
                    const CSpecialItemGroup* pItemGroup = ITEM_MANAGER::instance().GetSpecialItemGroup(GetSIGVnum());
                    if (NULL == pItemGroup)
                        break;
                    DWORD dwAttrVnum = pItemGroup->GetAttrVnum(GetVnum());
                    const CSpecialAttrGroup* pAttrGroup = ITEM_MANAGER::instance().GetSpecialAttrGroup(dwAttrVnum);
                    if (NULL == pAttrGroup)
                        break;
                    for (itertype (pAttrGroup->m_vecAttrs) it = pAttrGroup->m_vecAttrs.begin(); it != pAttrGroup->m_vecAttrs.end(); it++)
                    {
                        m_pOwner->ApplyPoint(it->apply_type, bAdd ? it->apply_value : -it->apply_value, compute_point_status);//Fixed_[C]Martin#2376_001
                    }
                }
            }
            break;
    }
}

--------------------------------------------

-- PetSystem.cpp

++++

( PetSystem.h dosyasına )void            GiveBuff(bool compute_point_status = false);//Fixed_[C]Martin#2376_001
void CPetActor::GiveBuff(bool compute_point_status)//Fixed_[C]Martin#2376_001
{

    if (!__PetCheckBuff(this))
        return;
    LPITEM item = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID);
    if (NULL != item)
        item->ModifyPoints(true, compute_point_status);//Fixed_[C]Martin#2376_001
    return ;
}

( PetSystem.h dosyasına )void        RefreshBuff(bool compute_point_status = false);//Fixed_[C]Martin#2376_001

void CPetSystem::RefreshBuff(bool compute_point_status)//Fixed_[C]Martin#2376_001
{
    for (TPetActorMap::const_iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter)
    {
        CPetActor* petActor = iter->second;

        if (0 != petActor)
        {
            if (petActor->IsSummoned())
            {
                petActor->GiveBuff(compute_point_status);//Fixed_[C]Martin#2376_001
            }
        }
    }
}


------------------------------------------------

-- Packet.h

++++++

HEADER_GC_CHARACTER_POINT_CHANGE_DYNAMIC = 50,//Fixed_[C]Martin#2376_001


typedef struct packet_point_change_dynamic
{
    int        header;
    DWORD    dwVID;
    BYTE    count;

} TPacketGCPointChangeDynamic;//Fixed_[C]Martin#2376_001

typedef struct packet_point_change_dynamic_val
{
    BYTE    type;
    long    amount;
    long    value;
} TPacketGCPointChangeDynamicVal;//Fixed_[C]Martin#2376_001




---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------

--------------------------- Client Source -------------------------

---------------------------------------------------------------------------------------------------------------

--------------------------------

-- Packet.h

+++

HEADER_GC_PLAYER_POINT_CHANGE_DYNAMIC = 50,//Fixed_[C]Martin#2376_001

typedef struct packet_point_change_dynamic
{
    int        header;
    DWORD    dwVID;
    BYTE    count;

} TPacketGCPointChangeDynamic;//Fixed_[C]Martin#2376_001

typedef struct packet_point_change_dynamic_val
{
    BYTE        Type;

    long        amount;
    long        value;
} TPacketGCPointChangeDynamicVal;//Fixed_[C]Martin#2376_001



------------------------

-- PythonNetworkStream.h

+++++++++

bool RecvPointChangeDynamic();//Fixed_[C]Martin#2376_001


------------------------

-- PythonNetworkStreamPhaseGame.cpp

+++++++++

            case HEADER_GC_PLAYER_POINT_CHANGE_DYNAMIC: //Fixed_[C]Martin#2376_001
                ret = RecvPointChangeDynamic();
                break;

+++++++++

bool CPythonNetworkStream::RecvPointChangeDynamic()//Fixed_[C]Martin#2376_001
{
    TPacketGCPointChangeDynamic PointChange;

    if (!Peek(sizeof(TPacketGCPointChangeDynamic), &PointChange))
    {
        Tracen("RecvPointChangeDynamic Packet Error #1");
        return false;
    }

    if (!Peek(sizeof(TPacketGCPointChangeDynamicVal)*PointChange.count))
    {
        Tracen("RecvPointChangeDynamic Packet Error #2");
        return false;
    }

    Recv(sizeof(TPacketGCPointChangeDynamic));

    bool refresh_status = false;
    bool refresh_skil_window = false;
    bool refresh_point_gold = false;
    int refresh_point_gold_val = 0;

    for (BYTE loop = 0; loop < PointChange.count; loop++)
    {
        TPacketGCPointChangeDynamicVal point_val;

        if (!Recv(sizeof(TPacketGCPointChangeDynamicVal), &point_val))
        {
            Tracen("Recv Point Change Packet Error");
            return false;
        }

        CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
        rkChrMgr.ShowPointEffect(point_val.Type, PointChange.dwVID);

        CInstanceBase* pInstance = CPythonCharacterManager::Instance().GetMainInstancePtr();

        if (pInstance && PointChange.dwVID == pInstance->GetVirtualID())
        {
            CPythonPlayer& rkPlayer = CPythonPlayer::Instance();
            rkPlayer.SetStatus(point_val.Type, point_val.value);

            switch (point_val.Type)
            {
            case POINT_STAT_RESET_COUNT:
                refresh_status = true;
                break;
            case POINT_LEVEL:
            case POINT_ST:
            case POINT_DX:
            case POINT_HT:
            case POINT_IQ:
                refresh_status = true;
                refresh_skil_window = true;
                break;
            case POINT_SKILL:
            case POINT_SUB_SKILL:
            case POINT_HORSE_SKILL:
                refresh_skil_window = true;
                break;
            case POINT_ENERGY:
                if (point_val.value == 0)
                {
                    rkPlayer.SetStatus(POINT_ENERGY_END_TIME, 0);
                }
                refresh_status = true;
                break;
            default:
                refresh_status = true;
                break;
            }

            if (POINT_GOLD == point_val.Type)
            {
                if (point_val.amount > 0)
                {
                    refresh_point_gold = true;
                    refresh_point_gold_val = point_val.amount;
                }
            }
        }
    }

    if (refresh_status)
    {
        __RefreshStatus();
    }

    if (refresh_skil_window)
    {
        __RefreshSkillWindow();
    }

    if (refresh_point_gold)
    {
        PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "OnPickMoney", Py_BuildValue("(i)", refresh_point_gold_val));
    }

    return true;
}


-----------------------------

-- PythonNetworkStreamPhaseLoading.cpp

+++++++

        case HEADER_GC_PLAYER_POINT_CHANGE_DYNAMIC:
            if (RecvPointChangeDynamic())
                return;
            break;



-----------------------------

-- PythonNetworkStreamPhaseSelect.cpp

+++++++

        case HEADER_GC_PLAYER_POINT_CHANGE_DYNAMIC:
            TPacketGCPointChangeDynamic PointChangeDynamic;

            if (!Peek(sizeof(TPacketGCPointChangeDynamic), &PointChangeDynamic))
            {
                Tracen("RecvPointChangeDynamic Packet Error #1");
                return;
            }

            if (!Peek(sizeof(TPacketGCPointChangeDynamicVal) * PointChangeDynamic.count))
            {
                Tracen("RecvPointChangeDynamic Packet Error #2");
                return;
            }

            Recv(sizeof(TPacketGCPointChangeDynamic));
            for (size_t i = 0; i < PointChangeDynamic.count; i++)
            {
                TPacketGCPointChangeDynamicVal PointChangeDynamicVal;
                Recv(sizeof(TPacketGCPointChangeDynamicVal), &PointChangeDynamicVal);
            }
            return;
            break;
 

Ekli dosyalar

  • new optimization.txt
    49.1 KB · Görüntüleme: 0
Son düzenleme:

En Çok Reaksiyon Alan Mesajlar

Öncelikle paylaşım için teşekkürler, computepoint Metin2 kaynak kodları sızdırıldığından beri yazılımcı arkadaşlar tarafından sürekli tartışması yapılan bir konu seneler için bir çok platformda buna benzer alternatif arayışları oldu ama gördüğüm en kapsamlı çözüm alternatifi sizinki dolayısıyla tebrik ederim bir Türk'ten çıkmış olması beni mutlu etti.

Uygulama konusuna gelirsek şuan büyük projelerle bu piyasada olan veya globalde bu işlerle uğraşan çoğu insan Metin2 kaynak kodları sızdırıldığında 2013 yılında aktif olarak official sunucuların alt yapısını oluşturan o dosyalarla hiçbir fix uygulamadan veya optimizasyon yapmadan defalarca kez sunucu açtı ve bazıları anlık 2-3 bin oyuncu gördü şimdi burada söylemek istediğim şu, bu dosyalar bu ilkel haliyle bile iyi bir server ile sorunsuz şekilde aktif olabilir.Tabi ki zamanın getirdiği düzenlemeler, yeni derleyiciler ile optimize etmek, memory leakleri çözmek, bug fixleri vs.vs. yapılmalı ama oyunun çekirdeğinin ana hatlarını oluşturan (örneğin paketler) içerikleri kurcalamak bana pek mantıklı gelmiyor umarım kendimi açıklayabilmişimdir, büyük proje hedefleyen arkadaşların kendi alt yapılarında bu riski almalarını önermiyorum ileride çeşitli paket hatalarıyla uğraşabilirler. Saygılar.
sen kodu tam okuyup anlamamışsın computepoint içinde gecen tüm poin change headeri ile point güncellemesini cliente göndermek yerine bunları kayıt ediyoruz ardından bunu başka bir paket numarası üzerinden dinamik olarak gönderiyoruz paket yapısına müdahale etmiyoruz sadece topluyoruz ve aynı paketleri gereksiz yere tekrar tekrar gönderilmesinin önüne geçiyoruz sadece 1 pakette işlem bitiyor.

C++:
    for (int i = 0 ; i < WEAR_MAX_NUM; i++)
    {
        LPITEM pItem = GetWear(i);
        if (pItem)
        {
            pItem->ModifyPoints(true, load, compute_point_status);//Fixed_[C]Martin_001
            SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
        }
    }

bu kodu ele alırsak 5 tane itemde hp olsun bunları hesaplarken 5 tane hp için 5 paket gidiyor yani 5 tane update packet demek ama benim yaptığım dinamik yapıda bu tarz compute point içinde yapılan tüm point numaralarını 1 tane pakete toplayıp öyle gönderiliyor ve bu sayede 5 den 1 e düşüyor paket ve 1 kez update point çağrılıyor client de herhangi bir paket hatasına sebebiyet verebilecek birşeye dokunmuyoruz sadece toplayıp toplu olarak gönderiyoruz

kodu ekleyip test edersen daha net anlarsın
Teori'de sorun çıkarmaz gibi gözüküyor
Bu tarz işlemleri bende bazı sistemler üzerinde denedim hızlı yapılan işlemler toplu sandık açma item ayırma gibi gibi
Packet büyümesinin de bu güne kadar bir zararını görmedim
Fakat bunlar pratikte sorunsuz olacağı anlamına gelmiyor tam deneysel olmuş seninki biraz köklü bir değişiklik olmuş tutarsa çok faydalı olacağı kesin ondan şüphem yok defalarca deneyimledim
Konunun takipçisi olacam
Paylaşım için teşekkürler
Update Final paket boyutu tamamen düşürüldü maksimum 100 baytın üstüne çıkmıyor artık :

C++:
typedef struct character_point_instant
{
    long            points[POINT_MAX_NUM];
    long            points_computepoint[POINT_MAX_NUM];//Fixed_[C]Martin_001

//--------------------------------------------------------


void CHARACTER::ComputePoints()
{
    compute_point_status = true;//Fixed_[C]Martin_001
    memcpy(m_pointsInstant.points_computepoint, m_pointsInstant.points, sizeof(m_pointsInstant.points));//Fixed_[C]Martin_001

    long comp_hp = GetHP();//Fixed_[C]Martin_001
    long comp_max_hp = GetMaxHP();//Fixed_[C]Martin_001
    long comp_sp = GetSP();//Fixed_[C]Martin_001
    long comp_max_sp = GetMaxSP();//Fixed_[C]Martin_001
    long comp_stamina = GetStamina();//Fixed_[C]Martin_001
    long comp_max_stamina = GetMaxStamina();//Fixed_[C]Martin_001

    long lStat = GetPoint(POINT_STAT);
    long lStatResetCount = GetPoint(POINT_STAT_RESET_COUNT);
    long lSkillActive = GetPoint(POINT_SKILL);
    long lSkillSub = GetPoint(POINT_SUB_SKILL);
    long lSkillHorse = GetPoint(POINT_HORSE_SKILL);
    long lLevelStep = GetPoint(POINT_LEVEL_STEP);

    long lAttackerBonus = GetPoint(POINT_PARTY_ATTACKER_BONUS);
    long lTankerBonus = GetPoint(POINT_PARTY_TANKER_BONUS);
    long lBufferBonus = GetPoint(POINT_PARTY_BUFFER_BONUS);
    long lSkillMasterBonus = GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
    long lHasteBonus = GetPoint(POINT_PARTY_HASTE_BONUS);
    long lDefenderBonus = GetPoint(POINT_PARTY_DEFENDER_BONUS);

    long lHPRecovery = GetPoint(POINT_HP_RECOVERY);
    long lSPRecovery = GetPoint(POINT_SP_RECOVERY);

    memset(m_pointsInstant.points, 0, sizeof(m_pointsInstant.points));
    BuffOnAttr_ClearAll();
    m_SkillDamageBonus.clear();

    SetPoint(POINT_STAT, lStat);
    SetPoint(POINT_SKILL, lSkillActive);
    SetPoint(POINT_SUB_SKILL, lSkillSub);
    SetPoint(POINT_HORSE_SKILL, lSkillHorse);
    SetPoint(POINT_LEVEL_STEP, lLevelStep);
    SetPoint(POINT_STAT_RESET_COUNT, lStatResetCount);

    SetPoint(POINT_ST, GetRealPoint(POINT_ST));
    SetPoint(POINT_HT, GetRealPoint(POINT_HT));
    SetPoint(POINT_DX, GetRealPoint(POINT_DX));
    SetPoint(POINT_IQ, GetRealPoint(POINT_IQ));

    SetPart(PART_MAIN, GetOriginalPart(PART_MAIN));
    SetPart(PART_WEAPON, GetOriginalPart(PART_WEAPON));
    SetPart(PART_HEAD, GetOriginalPart(PART_HEAD));
    SetPart(PART_HAIR, GetOriginalPart(PART_HAIR));

#ifdef ENABLE_ACCE_SYSTEM
    SetPart(PART_ACCE, GetOriginalPart(PART_ACCE));
#endif

    SetPoint(POINT_PARTY_ATTACKER_BONUS, lAttackerBonus);
    SetPoint(POINT_PARTY_TANKER_BONUS, lTankerBonus);
    SetPoint(POINT_PARTY_BUFFER_BONUS, lBufferBonus);
    SetPoint(POINT_PARTY_SKILL_MASTER_BONUS, lSkillMasterBonus);
    SetPoint(POINT_PARTY_HASTE_BONUS, lHasteBonus);
    SetPoint(POINT_PARTY_DEFENDER_BONUS, lDefenderBonus);

    SetPoint(POINT_HP_RECOVERY, lHPRecovery);
    SetPoint(POINT_SP_RECOVERY, lSPRecovery);

    // PC_BANG_ITEM_ADD
    SetPoint(POINT_PC_BANG_EXP_BONUS, 0);
    SetPoint(POINT_PC_BANG_DROP_BONUS, 0);
    // END_PC_BANG_ITEM_ADD

    int iMaxHP, iMaxSP;
    int iMaxStamina;

    if (IsPC())
    {
        iMaxHP = JobInitialPoints[GetJob()].max_hp + m_points.iRandomHP + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].hp_per_ht;
        iMaxSP = JobInitialPoints[GetJob()].max_sp + m_points.iRandomSP + GetPoint(POINT_IQ) * JobInitialPoints[GetJob()].sp_per_iq;
        iMaxStamina = JobInitialPoints[GetJob()].max_stamina + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].stamina_per_con;

        {
            CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_ADD_HP);

            if (NULL != pkSk)
            {
                pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_ADD_HP) / 100.0f);

                iMaxHP += static_cast<int>(pkSk->kPointPoly.Eval());
            }
        }

        SetPoint(POINT_MOV_SPEED,    100);
        SetPoint(POINT_ATT_SPEED,    100);
        PointChange(POINT_ATT_SPEED, GetPoint(POINT_PARTY_HASTE_BONUS), false, false, compute_point_status);//Fixed_[C]Martin_001
        SetPoint(POINT_CASTING_SPEED,    100);
    }
    else
    {
        iMaxHP = m_pkMobData->m_table.dwMaxHP;
        iMaxSP = 0;
        iMaxStamina = 0;

        SetPoint(POINT_ATT_SPEED, m_pkMobData->m_table.sAttackSpeed);
        SetPoint(POINT_MOV_SPEED, m_pkMobData->m_table.sMovingSpeed);
        SetPoint(POINT_CASTING_SPEED, m_pkMobData->m_table.sAttackSpeed);
    }

    if (IsPC())
    {
        if (GetMountVnum())
        {
            if (GetHorseST() > GetPoint(POINT_ST))
                PointChange(POINT_ST, GetHorseST() - GetPoint(POINT_ST), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseDX() > GetPoint(POINT_DX))
                PointChange(POINT_DX, GetHorseDX() - GetPoint(POINT_DX), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseHT() > GetPoint(POINT_HT))
                PointChange(POINT_HT, GetHorseHT() - GetPoint(POINT_HT), false, false, compute_point_status);//Fixed_[C]Martin_001

            if (GetHorseIQ() > GetPoint(POINT_IQ))
                PointChange(POINT_IQ, GetHorseIQ() - GetPoint(POINT_IQ), false, false, compute_point_status);//Fixed_[C]Martin_001
        }

    }

    ComputeBattlePoints(compute_point_status);//Fixed_[C]Martin_001

    if (iMaxHP != GetMaxHP())
    {
        SetRealPoint(POINT_MAX_HP, iMaxHP);
    }

    PointChange(POINT_MAX_HP, 0, false, false, compute_point_status);//Fixed_[C]Martin_001

    if (iMaxSP != GetMaxSP())
    {
        SetRealPoint(POINT_MAX_SP, iMaxSP);
    }

    PointChange(POINT_MAX_SP, 0, false, false, compute_point_status);//Fixed_[C]Martin_001

    SetMaxStamina(iMaxStamina);
    // @fixme118 part1
    int iCurHP = this->GetHP();
    int iCurSP = this->GetSP();

    m_pointsInstant.dwImmuneFlag = 0;

    for (int i = 0 ; i < WEAR_MAX_NUM; i++)
    {
        LPITEM pItem = GetWear(i);
        if (pItem)
        {
            pItem->ModifyPoints(true, compute_point_status);//Fixed_[C]Martin_001
            SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
        }
    }

    if (DragonSoul_IsDeckActivated())
    {
        for (int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck();
            i < WEAR_MAX_NUM + DS_SLOT_MAX * (DragonSoul_GetActiveDeck() + 1); i++)
        {
            LPITEM pItem = GetWear(i);
            if (pItem)
            {
                if (DSManager::instance().IsTimeLeftDragonSoul(pItem))
                    pItem->ModifyPoints(true,compute_point_status);//Fixed_[C]Martin_001
            }
        }
    }

    if (GetHP() > GetMaxHP())
        PointChange(POINT_HP, GetMaxHP() - GetHP(), false, false, compute_point_status);//Fixed_[C]Martin_001

    if (GetSP() > GetMaxSP())
        PointChange(POINT_SP, GetMaxSP() - GetSP(), false, false, compute_point_status);//Fixed_[C]Martin_001

    ComputeSkillPoints();

    RefreshAffect(compute_point_status);//Fixed_[C]Martin_001

    CPetSystem * pPetSystem = GetPetSystem();
    if (NULL != pPetSystem)
        pPetSystem->RefreshBuff(compute_point_status);//Fixed_[C]Martin_001

    // @fixme118 part2 (after petsystem stuff)
    if (IsPC())
    {
        if (this->GetHP() != iCurHP)
            this->PointChange(POINT_HP, iCurHP-this->GetHP(), false, false, compute_point_status);//Fixed_[C]Martin_001
        if (this->GetSP() != iCurSP)
            this->PointChange(POINT_SP, iCurSP-this->GetSP(), false, false, compute_point_status);//Fixed_[C]Martin_001
    }

    compute_point_status = false;//Fixed_[C]Martin_001

    if (GetDesc())//Fixed_[C]Martin_001
    {
        BYTE send_count = 0;
        auto it = compute_point_list.begin();
        for (; it != compute_point_list.end(); it++)
        {
            if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                continue;

            if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                || it->type == POINT_HP && comp_hp == it->val
                )
            {
                continue;
            }

            if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                || it->type == POINT_SP && comp_sp == it->val
                )
            {
                continue;
            }

            if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                || it->type == POINT_STAMINA && comp_stamina == it->val
                )
            {
                continue;
            }
            send_count++;
        }

        if (send_count == 1)
        {
            auto it = compute_point_list.begin();
            for (; it != compute_point_list.end(); it++)
            {
                if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                    continue;

                if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                    || it->type == POINT_HP && comp_hp == it->val
                    )
                {
                    continue;
                }

                if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                    || it->type == POINT_SP && comp_sp == it->val
                    )
                {
                    continue;
                }

                if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                    || it->type == POINT_STAMINA && comp_stamina == it->val
                    )
                {
                    continue;
                }

                struct packet_point_change pack;

                pack.header = HEADER_GC_CHARACTER_POINT_CHANGE;
                pack.dwVID = m_vid;
                pack.type = it->type;
                pack.value = it->val;

                pack.amount = it->amount;

                GetDesc()->Packet(&pack, sizeof(struct packet_point_change));
            }
        }
        else
        {
            if (send_count > 1)
            {
                TPacketGCPointChangeDynamic pack;

                pack.header = HEADER_GC_CHARACTER_POINT_CHANGE_DYNAMIC;
                pack.dwVID = m_vid;
                pack.count = send_count;

                TEMP_BUFFER buf;
                buf.write(&pack, sizeof(TPacketGCPointChangeDynamic));

                auto it = compute_point_list.begin();
                for (; it != compute_point_list.end(); it++)
                {
                    if (m_pointsInstant.points_computepoint[it->type] == m_pointsInstant.points[it->type] && m_pointsInstant.points[it->type] == it->val)
                        continue;

                    if (it->type == POINT_MAX_HP && comp_max_hp == it->val
                        || it->type == POINT_HP && comp_hp == it->val
                        )
                    {
                        continue;
                    }

                    if (it->type == POINT_MAX_SP && comp_max_sp == it->val
                        || it->type == POINT_SP && comp_sp == it->val
                        )
                    {
                        continue;
                    }

                    if (it->type == POINT_MAX_STAMINA && comp_max_stamina == it->val
                        || it->type == POINT_STAMINA && comp_stamina == it->val
                        )
                    {
                        continue;
                    }

                    TPacketGCPointChangeDynamicVal pack_val;
                    pack_val.type = it->type;
                    pack_val.value = it->val;

                    pack_val.amount = it->amount;

                    buf.write(&pack_val, sizeof(TPacketGCPointChangeDynamicVal));
                }

                GetDesc()->Packet(buf.read_peek(), buf.size());
            }
        }
    }//Fixed_[C]Martin_001

    compute_point_list.clear();//Fixed_[C]Martin_001
    compute_point_list.shrink_to_fit();//Fixed_[C]Martin_001

    UpdatePacket();

    memset(m_pointsInstant.points_computepoint, 0, sizeof(m_pointsInstant.points_computepoint));//Fixed_[C]Martin_001
}
SOLID Prensiplerine göre her fonksiyonun bir işlemi olmalıdır. Toplamak dağıtmaktan daha çok zarara uğratabilir.

Packetlerin başında ve sonunda başlangıç ve bitiş baytları var mesela. 600 KB lık packetin tamamını indiremediği durumlarda ne gibi sorunlar yaşanacak bunu düşünmek lazım. Parçalı şekilde gönderilen packetlerin tek bir işlem dışında başka yerlerde parça parça kullanılıyor mu bunu araştırmak lazım.



- Mesela statü puanı verildiğinde clientten servera gönderiliyor ve tekrardan cliente OK dönüyor. Bunu kaldırıp, direkt olarak clientten servera gönderip, serverdan geri dönüş beklenmemeli. Oyun karakteri bir dizide tutmalı ve ona göre işlem yapmalı. Metin2 o kadar çok serverı zorluyor ki, çoğu işlem clientte çözülmesi gerekiyor diye düşünüyorum.

- Mesela at çağırmayı kullandın, servera packet gitti, server geriye döndü hesaplama yaptı, spawn etti. Bunun yerine at çağırmaya basınca item_use gönderip, spawnı cliente bırakıp daha sonrasında ata bindiğinde kontrolü sağlanabilir.

- Questi mesela direkt olarak cliente taşıyıp packet ile kontrolü sağlanabilir.

- Marketteki itemler direkt olarak clientte tutulup, buy packeti gittiğinde olumlu veya olumsuz dönülebilir.Her Markete tıklandığında serverdan gereksiz yere shopu sorgulatıp ona göre cliente packet atılıyor.

- Refine_Proto komple cliente taşınıp + basma olarak gelen packet denetlenebilir.



Evet move, attact kısmı hile kontrolü amacıyla serverda halledilir ama kalan fazlalıkları cliente taşımak bence daha mantıklı
Arkadaşım olan emirhanda aynısını yaptı yüksek bir onlinede anlam veremediği konudan alakasız paket hataları çıkmıştı sanırım o bunun sorununu çözememişti bireysel 5 10 kişilik oyunlarda sorun vermiyor olabilir fakat yüksek onlinelerde emirhanın başına gelen başınıza gelebilir. Emeğiniz için ayrı teşekkürler.
Komik 😂 senin baya Arkadaşın var galiba bide her konuda seni görüyorum herşeyde bi arkadaşın oluyor ve onlar uyguluyor bu işlemleri 😂

CаstieL

Level 8
Telefon Numarası Onaylanmış Üye TC Kimlik Numarası Doğrulanmış Üye
Fahri Üye
TM Üye
Katılım
17 Tem 2018
Konular
531
Mesajlar
3,952
Reaksiyon Skoru
1,624
Altın Konu
50
Başarım Puanı
312
TM Yaşı
4 Yıl 2 Ay 22 Gün
Online Süresi
309d 17h 45m
MmoLira
852
DevLira
70
Takipçiler
29
Paylaşım için teşekkürler.
 
Katılım
20 Kas 2016
Konular
64
Mesajlar
1,253
Reaksiyon Skoru
599
Altın Konu
0
Başarım Puanı
196
TM Yaşı
5 Yıl 10 Ay 21 Gün
Online Süresi
32d 22h 50m
MmoLira
1,853
DevLira
82
Takipçiler
23
Arkadaşım olan emirhanda aynısını yaptı yüksek bir onlinede anlam veremediği konudan alakasız paket hataları çıkmıştı sanırım o bunun sorununu çözememişti bireysel 5 10 kişilik oyunlarda sorun vermiyor olabilir fakat yüksek onlinelerde emirhanın başına gelen başınıza gelebilir. Emeğiniz için ayrı teşekkürler.
 
Konu Sahibi
Konu Sahibi
[C]Martin

[C]Martin

Level 4
TM Üye
Üye
Katılım
14 Ocak 2021
Konular
10
Mesajlar
441
Reaksiyon Skoru
336
Altın Konu
0
Başarım Puanı
82
TM Yaşı
1 Yıl 8 Ay 25 Gün
Online Süresi
149d 21h 34m
MmoLira
484
DevLira
9
Takipçiler
6
Arkadaşım olan emirhanda aynısını yaptı yüksek bir onlinede anlam veremediği konudan alakasız paket hataları çıkmıştı sanırım o bunun sorununu çözememişti bireysel 5 10 kişilik oyunlarda sorun vermiyor olabilir fakat yüksek onlinelerde emirhanın başına gelen başınıza gelebilir. Emeğiniz için ayrı teşekkürler.
kime ne oldu daha açıklayıcı olabilirmisiniz bu paylaştığım kodlar olumlu mu olumsuz mu arkadaşınızın başına gelene göre
 

REVOLTS

Mᴀᴋɪɴɢ ᴀ ᴄᴏᴅᴇ ᴍɪꜱᴛᴀᴋᴇ ɪꜱ ʟɪᴋᴇ ᴡᴀᴛᴇʀɪɴɢ ᴀ ғʟᴏᴡᴇʀ.
TM Üye
Katılım
12 Ara 2015
Konular
106
Mesajlar
1,849
Reaksiyon Skoru
926
Altın Konu
1
Başarım Puanı
211
TM Yaşı
6 Yıl 10 Ay
Online Süresi
37d 21h 11m
MmoLira
1,215
DevLira
165
Takipçiler
15
Arkadaşım olan emirhanda aynısını yaptı yüksek bir onlinede anlam veremediği konudan alakasız paket hataları çıkmıştı sanırım o bunun sorununu çözememişti bireysel 5 10 kişilik oyunlarda sorun vermiyor olabilir fakat yüksek onlinelerde emirhanın başına gelen başınıza gelebilir. Emeğiniz için ayrı teşekkürler.
Komik 😂 senin baya Arkadaşın var galiba bide her konuda seni görüyorum herşeyde bi arkadaşın oluyor ve onlar uyguluyor bu işlemleri 😂
 

Şu an konuyu görüntüleyenler (Toplam : 1, Üye: 0, Misafir: 1)

Üst