Membru Ucenic
Membru Ucenic
Mesaje: 24
Membru din: 10 Mai 2026, 14:20
  • Reacții: 4
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Regat: Shinsoo
  • Medalii

    In summary, around 100 bugs were fixed or improvements were made.
    It was tested for a long time.
    The anti-cheat system was improved.

    https://www.mediafire.com/file/ajr2mig7 ... hd.7z/file

    https://www.mediafire.com/file/n1xk4eoy ... r.rar/file

    https://www.mediafire.com/file/6flylv79 ... 26.7z/file


    [img]/download/file.php?mode=view&id=10273[/img]
    fix
    Code:
    
    
    
    MarkImage.cpp
    
    #include "MarkImage.h"
    
    #include <base/Crc32.hpp>
    
    #include <lz4.h>
    
    // #define STB_IMAGE_IMPLEMENTATION
    #include "stb-master/stb_image.h"
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include "stb-master/stb_image_write.h"
    #include <vector>
    
    CGuildMarkImage::CGuildMarkImage()
        : m_aakBlock{} // m_aakBlock hala mevcut, kalabilir.
    {
        m_pPixels = nullptr; // Yeni eklediğimiz pointer'ı boş (null) olarak başlatıyoruz.
    }
    
    CGuildMarkImage::~CGuildMarkImage()
    {
        Destroy();
    }
    
    void CGuildMarkImage::Destroy()
    {
        if (m_pPixels)
        {
            free(m_pPixels);
            m_pPixels = nullptr;
        }
    }
    
    void CGuildMarkImage::Create()
    {
        if (m_pPixels)
            return;
    
        // Başlangıçta boş bir siyah resim oluştur
        m_pPixels = (Pixel*)malloc(sizeof(Pixel) * WIDTH * HEIGHT);
        memset(m_pPixels, 0, sizeof(Pixel) * WIDTH * HEIGHT);
    }
    
    bool CGuildMarkImage::Save(const char *c_szFileName)
    {
        if (!m_pPixels) return false;
    
        // Kaydetmeden önce kanalları ters çevir (BGRA -> RGBA)
        uint8_t* pRawByte = (uint8_t*)m_pPixels;
        uint32_t totalPixels = WIDTH * HEIGHT;
    
        for (uint32_t i = 0; i < totalPixels; ++i)
        {
            uint8_t tempB = pRawByte[i * 4 + 0];
            pRawByte[i * 4 + 0] = pRawByte[i * 4 + 2];
            pRawByte[i * 4 + 2] = tempB;
        }
    
        // STB ile kaydet
        bool result = stbi_write_tga(c_szFileName, WIDTH, HEIGHT, 4, m_pPixels) != 0;
    
        // Hafızadaki orijinal veriyi bozmamak için tekrar eski haline getir (RGBA -> BGRA)
        for (uint32_t i = 0; i < totalPixels; ++i)
        {
            uint8_t tempR = pRawByte[i * 4 + 0];
            pRawByte[i * 4 + 0] = pRawByte[i * 4 + 2];
            pRawByte[i * 4 + 2] = tempR;
        }
    
        return result;
    }
    
    bool CGuildMarkImage::Build(const char *c_szFileName)
    {
        Destroy();
        Create();
    
        return Save(c_szFileName);
    }
    
    bool CGuildMarkImage::Load(const char *c_szFileName)
    {
        Destroy();
    
        int width, height, channels;
        // TGA veya başka formatları yükle. zorla 4 kanal (RGBA) al.
        Pixel* loadedPixels = (Pixel*)stbi_load(c_szFileName, &width, &height, &channels, 4);
    
        if (!loadedPixels)
        {
            // Dosya yoksa oluştur
            if (!Build(c_szFileName)) return false;
            return Load(c_szFileName); // Yeni oluşturulanı yükle
        }
    
        if (width != WIDTH || height != HEIGHT)
        {
            SPDLOG_ERROR("CGuildMarkImage: {0} size mismatch!", c_szFileName);
            stbi_image_free(loadedPixels);
            return false;
        }
    
        // --- RENK KANALI DÜZELTME (RGBA -> BGRA) ---
        // STB veriyi RGBA yükler, ancak Metin2 BGRA bekler.
        // R (Kırmızı) ve B (Mavi) kanallarının yerini değiştiriyoruz.
        uint8_t* pRawByte = (uint8_t*)loadedPixels;
        uint32_t totalPixels = width * height;
    
        for (uint32_t i = 0; i < totalPixels; ++i)
        {
            uint8_t tempR = pRawByte[i * 4 + 0];     // İlk byte: R
            pRawByte[i * 4 + 0] = pRawByte[i * 4 + 2]; // R yerine B yaz (Son byte)
            pRawByte[i * 4 + 2] = tempR;             // B yerine R yaz
        }
        // -------------------------------------------
    
        m_pPixels = loadedPixels;
        BuildAllBlocks();
        return true;
    }
    
    // Resmin belirli bir bölgesine veri yazma
    void CGuildMarkImage::PutData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, void *data)
    {
        if (!m_pPixels || !data) return;
    
        Pixel* pSrc = (Pixel*)data;
        for (uint32_t i = 0; i < height; ++i)
        {
            // Y ekseni Metin2/DevIL mantığında bazen ters olabilir, duruma göre (y+i) veya (y+height-1-i) ayarlanır.
            Pixel* pDestRow = m_pPixels + ((y + i) * WIDTH) + x;
            memcpy(pDestRow, pSrc + (i * width), width * sizeof(Pixel));
        }
    }
    
    void CGuildMarkImage::GetData(uint32_t x, uint32_t y, uint32_t width, uint32_t height, void *data)
    {
        if (!m_pPixels || !data) return;
    
        Pixel* pDest = (Pixel*)data;
        for (uint32_t i = 0; i < height; ++i)
        {
            Pixel* pSrcRow = m_pPixels + ((y + i) * WIDTH) + x;
            memcpy(pDest + (i * width), pSrcRow, width * sizeof(Pixel));
        }
    }
    
    // 이미지 = 512x512
    //   블럭 = 마크 4 x 4
    //   마크 = 16 x 12
    // 한 이미지의 블럭 = 8 x 10
    
    bool CGuildMarkImage::SaveBlockFromCompressedData(uint32_t posBlock, const uint8_t *pbComp, uint32_t dwCompSize)
    {
        if (posBlock >= BLOCK_TOTAL_COUNT)
            return false;
    
        Pixel apxBuf[SGuildMarkBlock::SIZE];
        int32_t sizeBuf = LZ4_decompress_safe((const char *)pbComp, (char *)apxBuf, dwCompSize, sizeof(apxBuf));
        if (sizeBuf < 0)
        {
            SPDLOG_ERROR("cannot decompress, compressed size = {0}", dwCompSize);
            return false;
        }
    
        if (sizeBuf != sizeof(apxBuf))
        {
            SPDLOG_ERROR("image corrupted, decompressed size = {0}", sizeBuf);
            return false;
        }
    
        uint32_t rowBlock = posBlock / BLOCK_COL_COUNT;
        uint32_t colBlock = posBlock % BLOCK_COL_COUNT;
    
        PutData(colBlock * SGuildMarkBlock::WIDTH,
                rowBlock * SGuildMarkBlock::HEIGHT,
                SGuildMarkBlock::WIDTH,
                SGuildMarkBlock::HEIGHT,
                apxBuf);
    
        m_aakBlock[rowBlock][colBlock].CopyFrom(pbComp, dwCompSize,
                                                ComputeCrc32(0, (const char *)apxBuf,
                                                             sizeof(Pixel) * SGuildMarkBlock::SIZE));
        return true;
    }
    
    void CGuildMarkImage::BuildAllBlocks() // 이미지 전체를 블럭화
    {
        Pixel apxBuf[SGuildMarkBlock::SIZE];
        SPDLOG_INFO("CGuildMarkImage::BuildAllBlocks");
    
        for (uint32_t row = 0; row < BLOCK_ROW_COUNT; ++row)
        {
            for (uint32_t col = 0; col < BLOCK_COL_COUNT; ++col)
            {
                GetData(col * SGuildMarkBlock::WIDTH,
                        row * SGuildMarkBlock::HEIGHT,
                        SGuildMarkBlock::WIDTH,
                        SGuildMarkBlock::HEIGHT,
                        apxBuf);
    
                m_aakBlock[row][col].Compress(apxBuf);
            }
        }
    }
    
    uint32_t CGuildMarkImage::GetEmptyPosition()
    {
        SGuildMark kMark{};
    
        for (uint32_t row = 0; row < MARK_ROW_COUNT; ++row)
        {
            for (uint32_t col = 0; col < MARK_COL_COUNT; ++col)
            {
                GetData(col * SGuildMark::WIDTH,
                        row * SGuildMark::HEIGHT,
                        SGuildMark::WIDTH,
                        SGuildMark::HEIGHT,
                        kMark.m_apxBuf);
    
                if (kMark.IsEmpty())
                    return (row * MARK_COL_COUNT + col);
            }
        }
    
        return INVALID_MARK_POSITION;
    }
    
    void CGuildMarkImage::GetBlockCRCList(uint32_t *crcList)
    {
        for (uint32_t row = 0; row < BLOCK_ROW_COUNT; ++row)
            for (uint32_t col = 0; col < BLOCK_COL_COUNT; ++col)
                *(crcList++) = m_aakBlock[row][col].GetCRC();
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    void SGuildMark::Clear()
    {
        for (uint32_t iPixel = 0; iPixel < SIZE; ++iPixel)
            m_apxBuf[iPixel] = 0xff000000ul;
    }
    
    bool SGuildMark::IsEmpty()
    {
        for (uint32_t iPixel = 0; iPixel < SIZE; ++iPixel)
            if (m_apxBuf[iPixel] != 0x00000000ul)
                return false;
    
        return true;
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    uint32_t SGuildMarkBlock::GetCRC() const
    {
        return m_crc;
    }
    
    void SGuildMarkBlock::CopyFrom(const uint8_t *pbCompBuf, uint32_t dwCompSize, uint32_t crc)
    {
        if (dwCompSize > LZ4_compressBound(sizeof(Pixel) * SGuildMarkBlock::SIZE))
            return;
    
        m_sizeCompBuf = dwCompSize;
        memcpy(m_abCompBuf.data(), pbCompBuf, dwCompSize);
        m_crc = crc;
    }
    
    void SGuildMarkBlock::Compress(const Pixel *pxBuf)
    {
        m_sizeCompBuf = LZ4_compressBound(sizeof(Pixel) * SGuildMarkBlock::SIZE);
        m_abCompBuf.resize(m_sizeCompBuf);
    
        m_sizeCompBuf = LZ4_compress_default(reinterpret_cast<const char *>(pxBuf),
                                             reinterpret_cast<char *>(m_abCompBuf.data()),
                                             sizeof(Pixel) * SGuildMarkBlock::SIZE, m_sizeCompBuf);
        if (m_sizeCompBuf <= 0)
        {
            SPDLOG_ERROR("Compress: Error! {0} > {1}",
                         sizeof(Pixel) * SGuildMarkBlock::SIZE,
                         m_sizeCompBuf);
            return;
        }
    
        m_crc = ComputeCrc32(0, (const char *)pxBuf,
                             sizeof(Pixel) * SGuildMarkBlock::SIZE);
    }
    
    

    Nou Cum descarc de pe TeraBox?

    Afișează detalii Ascunde detalii
    • Este asemănător cu Mega.nz
    • Instalați-vă clientul lor de Download de aici
    • Faceți-vă un cont (vă puteți loga cu Facebook / Google / etc)
    • Nou Dacă nu vreți să descărcați clientul de Download, folosiți acest site
    • Gata! Acum puteți descărca resursele rapid & simplu.

    De ce folosim TeraBox?

    • Este gratuit
    • Primești 1TB de spațiu gratuit la orice cont creat!
    • Este ușor de folosit și varianta premium este foarte ieftină
    • Fișierele nu sunt șterse niciodată
    TeraBox logo

    Creează-ți un cont sau autentifică-te pentru a participa la discuție

    Trebuie să fii membru pentru a răspunde

    Creează-ți un cont

    Membrii pot crea subiecte noi și pot descărca resurse Metin2 Gratuit!


    Te poți înregistra sau conecta rapid utilizând contul tău de Discord, Github sau Google.

    Înregistrare

    Autentifică-te

    Înapoi la “Serverfiles resurse”

    Informații

    Utilizatori ce navighează pe acest forum: Azunay, DRCS2, pork1994, wenor0686, Zendaya și 5 vizitatori

    Discord ID copiat: