- Katılım
- 6 Mayıs 2022
- Konular
- 48,270
- Mesajlar
- 48,580
- Tepkime puanı
- 74
- M2 Yaşı
- 3 yıl 11 ay 10 gün
- Trophy Puan
- 48
- M2 Yang
- 488,669
Kod:
#include "StdAfx.h" #include "../eterBase/MappedFile.h" #include "../eterPack/EterPackManager.h" #include "GrpImageTexture.h" #include "SOIL2.h" #pragma comment(lib, "soil2.lib") #pragma comment(lib, "legacy_stdio_definitions.lib") #pragma comment(lib, "Opengl32.lib")
tekrardan güncellendi.
fonksiyonun dx8 okuması devam edecek.
herhangi bir okumama çökme durumunda soil2 devreye giricek.
grpimageinstance.cpp
Kod:
bool CGraphicImageTexture::CreateFromMemoryFile(UINT bufSize, const void * c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter) { assert(ms_lpd3dDevice != NULL); assert(m_lpd3dTexture == NULL); static CDXTCImage image; // --- 1. ADIM: DDS (DXTC) KONTROLÜ --- if (image.LoadHeaderFromMemory((const BYTE *) c_pvBuf)) { if (CreateDDSTexture(image, (const BYTE *) c_pvBuf)) { m_bEmpty = false; return true; } } // --- 2. ADIM: STANDART D3DX YÜKLEME DENEMESİ --- D3DXIMAGE_INFO imageInfo; HRESULT hr = D3DXCreateTextureFromFileInMemoryEx( ms_lpd3dDevice, c_pvBuf, bufSize, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, d3dFmt, D3DPOOL_MANAGED, dwFilter, dwFilter, 0xffff00ff, // Color Key (Magenta) &imageInfo, NULL, &m_lpd3dTexture); if (SUCCEEDED(hr)) { m_width = imageInfo.Width; m_height = imageInfo.Height; // Orijinal kodunuzdaki format optimizasyonları D3DFORMAT format = imageInfo.Format; switch(imageInfo.Format) { case D3DFMT_A8R8G8B8: format = D3DFMT_A4R4G4B4; break; case D3DFMT_X8R8G8B8: case D3DFMT_R8G8B8: format = D3DFMT_A1R5G5B5; break; } UINT uTexBias = 0; extern bool GRAPHICS_CAPS_HALF_SIZE_IMAGE; if (GRAPHICS_CAPS_HALF_SIZE_IMAGE) uTexBias = 1; if (IsLowTextureMemory() && (uTexBias || format != imageInfo.Format)) { IDirect3DTexture8* pkTexSrc = m_lpd3dTexture; IDirect3DTexture8* pkTexDst = NULL; if (SUCCEEDED(D3DXCreateTexture( ms_lpd3dDevice, imageInfo.Width >> uTexBias, imageInfo.Height >> uTexBias, imageInfo.MipLevels, 0, format, D3DPOOL_MANAGED, &pkTexDst))) { m_lpd3dTexture = pkTexDst; for(int i = 0; i < (int)imageInfo.MipLevels; ++i) { IDirect3DSurface8* ppsSrc = NULL; IDirect3DSurface8* ppsDst = NULL; if (SUCCEEDED(pkTexSrc->GetSurfaceLevel(i, &ppsSrc))) { if (SUCCEEDED(pkTexDst->GetSurfaceLevel(i, &ppsDst))) { D3DXLoadSurfaceFromSurface(ppsDst, NULL, NULL, ppsSrc, NULL, NULL, D3DX_FILTER_LINEAR, 0); ppsDst->Release(); } ppsSrc->Release(); } } pkTexSrc->Release(); } } m_bEmpty = false; return true; } // --- 3. ADIM: HATA DURUMUNDA SOIL2 FALLBACK --- // Eğer buraya geldiyse D3DX dosyayı açamamış demektir. int width, height, channels; unsigned char* imgData = SOIL_load_image_from_memory( (const unsigned char*)c_pvBuf, bufSize, &width, &height, &channels, SOIL_LOAD_RGBA ); if (imgData) { // SOIL2 ile başarıyla decode edildi, şimdi manuel D3D Texture oluşturuyoruz if (SUCCEEDED(D3DXCreateTexture(ms_lpd3dDevice, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_lpd3dTexture))) { D3DLOCKED_RECT rect; if (SUCCEEDED(m_lpd3dTexture->LockRect(0, &rect, NULL, 0))) { unsigned char* pDestBase = (unsigned char*)rect.pBits; for (int y = 0; y < height; ++y) { unsigned char* pDestRow = pDestBase + (y * rect.Pitch); for (int x = 0; x < width; ++x) { int srcIdx = (y * width + x) * 4; int dstIdx = x * 4; // SOIL (RGBA) -> D3D (BGRA) dönüşümü pDestRow[dstIdx + 0] = imgData[srcIdx + 2]; // B pDestRow[dstIdx + 1] = imgData[srcIdx + 1]; // G pDestRow[dstIdx + 2] = imgData[srcIdx + 0]; // R pDestRow[dstIdx + 3] = imgData[srcIdx + 3]; // A } } m_lpd3dTexture->UnlockRect(0); m_width = width; m_height = height; m_bEmpty = false; SOIL_free_image_data(imgData); return true; } } SOIL_free_image_data(imgData); } // Tüm yöntemler başarısız oldu TraceError("CreateFromMemoryFile: Texture creation failed (D3DX and SOIL2)"); return false; }
pythonappilciionmodule
Kod:
#include "SOIL2.h" // #include <SOIL2.h> PyObject* appGetImageInfo(PyObject* poSelf, PyObject* poArgs) { char* szFileName; if (!PyTuple_GetString(poArgs, 0, &szFileName)) return Py_BuildException(); int width = 0; int height = 0; int channels = 0; BOOL canLoad = FALSE; // SOIL_load_image doğrudan resmi yüklemeye çalışır. // Eğer dosya yoksa veya formatı desteklemiyorsa NULL döner. unsigned char* temp_info = SOIL_load_image(szFileName, &width, &height, &channels, SOIL_LOAD_AUTO); if (temp_info) { canLoad = TRUE; // Boyutları aldık, belleği hemen temizle SOIL_free_image_data(temp_info); } else { // Dosya bulunamadı veya SOIL2 okuyamadı canLoad = FALSE; width = 0; height = 0; } return Py_BuildValue("iii", canLoad, width, height); }
hazır vs 2022 c++20 lib. 32 bit
Çok iş parçacıklı (/MT)
build ederken dx10 32 bitte build olmuyor dx10 satırları silin öyle build edin.
lib konuya ekliyorum.
cmake ile build alabilirsiniz.
cmke v3 latest
Kod:
#include "image_array.h" #include <stdlib.h> #include <string.h> #include "image_helper.h" extern const char *result_string_pointer; void SOIL_image_array_free(SOIL_ImageArray *imgArray){ if(imgArray == NULL){ return; } if(imgArray->data != NULL){ for(int i = 0; i < imgArray->layers; i++){ if(imgArray->data[i] != NULL){ free(imgArray->data[i]); } } free(imgArray->data); } imgArray->data = NULL; imgArray->width = 0; imgArray->height = 0; imgArray->layers = 0; imgArray->channels = 0; } void image_array_invert_y(SOIL_ImageArray* imgArray){ if (!imgArray || !imgArray->data) return; const size_t rowBytes = (size_t)(imgArray->width) * (size_t)(imgArray->channels); for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *image = imgArray->data[layer]; if (!image) continue; for (int y = 0; y < imgArray->height / 2; ++y) { unsigned char *rowTop = image + (size_t)y * rowBytes; unsigned char *rowBottom = image + (size_t)(imgArray->height - 1 - y) * rowBytes; for (size_t x = 0; x < rowBytes; ++x) { unsigned char temp = rowTop[x]; rowTop[x] = rowBottom[x]; rowBottom[x] = temp; } } } } void image_array_premultiply_alpha(SOIL_ImageArray* imgArray){ if (!imgArray || !imgArray->data) return; const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height); for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *image = imgArray->data[layer]; if (!image) continue; for (size_t i = 0; i < numPixels; ++i) { unsigned char *pixel = image + i * (size_t)(imgArray->channels); if (imgArray->channels >= 4) { float alpha = pixel[3] / 255.0f; pixel[0] = (unsigned char)(pixel[0] * alpha); pixel[1] = (unsigned char)(pixel[1] * alpha); pixel[2] = (unsigned char)(pixel[2] * alpha); } } } } void image_array_to_NTSC_safe(SOIL_ImageArray* imgArray){ if (!imgArray || !imgArray->data) return; const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height); for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *image = imgArray->data[layer]; if (!image) continue; for (size_t i = 0; i < numPixels; ++i) { unsigned char *pixel = image + i * (size_t)(imgArray->channels); if (imgArray->channels >= 3) { unsigned char r = pixel[0]; unsigned char g = pixel[1]; unsigned char b = pixel[2]; unsigned char y = (unsigned char)(0.299f * r + 0.587f * g + 0.114f * b); unsigned char co = (unsigned char)(r - b + 128); unsigned char cg = (unsigned char)(-0.168736f * r - 0.331264f * g + 0.5f * b + 128); pixel[0] = co; pixel[1] = cg; pixel[2] = y; } } } } void image_array_to_YCoCg(SOIL_ImageArray* imgArray){ if (!imgArray || !imgArray->data) return; const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height); for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *image = imgArray->data[layer]; if (!image) continue; for (size_t i = 0; i < numPixels; ++i) { unsigned char *pixel = image + i * (size_t)(imgArray->channels); if (imgArray->channels >= 3) { unsigned char r = pixel[0]; unsigned char g = pixel[1]; unsigned char b = pixel[2]; int y = ( r + ( 2 * g ) + b ) >> 2; int co = ( r - b ) >> 1; int cg = ( -r + ( 2 * g ) - b ) >> 2; pixel[0] = (unsigned char)(co + 128); pixel[1] = (unsigned char)(cg + 128); pixel[2] = (unsigned char)(y); } } } } static int next_power_of_two(int v) { int r = 1; while (r < v) r <<= 1; return r; } int image_array_resize_POT(SOIL_ImageArray *imgArray) { if (!imgArray || !imgArray->data) return 1; int new_w = next_power_of_two(imgArray->width); int new_h = next_power_of_two(imgArray->height); if (new_w == imgArray->width && new_h == imgArray->height) return 1; for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *src = imgArray->data[layer]; if (!src) continue; unsigned char *dst = (unsigned char*)malloc( (size_t)new_w * (size_t)new_h * (size_t)imgArray->channels ); if (!dst) return 0; up_scale_image( src, imgArray->width, imgArray->height, imgArray->channels, dst, new_w, new_h ); free(src); imgArray->data[layer] = dst; } imgArray->width = new_w; imgArray->height = new_h; return 1; } int image_array_reduce_to_max(SOIL_ImageArray *imgArray, int max_size) { if (!imgArray || !imgArray->data) return 1; if (imgArray->width <= max_size && imgArray->height <= max_size) return 1; int reduce_block_x = 1; int reduce_block_y = 1; if (imgArray->width > max_size) reduce_block_x = imgArray->width / max_size; if (imgArray->height > max_size) reduce_block_y = imgArray->height / max_size; int new_w = imgArray->width / reduce_block_x; int new_h = imgArray->height / reduce_block_y; for (int layer = 0; layer < imgArray->layers; ++layer) { unsigned char *src = imgArray->data[layer]; if (!src) continue; unsigned char *dst = (unsigned char*)malloc( (size_t)new_w * (size_t)new_h * (size_t)imgArray->channels ); if (!dst) return 0; mipmap_image( src, imgArray->width, imgArray->height, imgArray->channels, dst, reduce_block_x, reduce_block_y ); free(src); imgArray->data[layer] = dst; } imgArray->width = new_w; imgArray->height = new_h; return 1; } SOIL_ImageArray extract_image_array_from_atlas_grid( const unsigned char *atlasData, int atlasW, int atlasH, int cols, int rows, int channels ){ SOIL_ImageArray result = {0}; if (!atlasData || cols <= 0 || rows <= 0 || channels <= 0) return result; if (atlasW % cols != 0 || atlasH % rows != 0) { result_string_pointer = "Atlas cannot be evenly divided by grid"; return result; } int tile_w = atlasW / cols; int tile_h = atlasH / rows; int numLayers = cols * rows; result.width = tile_w; result.height = tile_h; result.layers = numLayers; result.channels = channels; result.data = (unsigned char**)malloc(sizeof(unsigned char*) * numLayers); if (!result.data){ SOIL_ImageArray empty; memset(&empty, 0, sizeof(empty)); return empty; } for (int i = 0; i < numLayers; ++i) result.data[i] = NULL; const size_t bytesPerPixel = (size_t)channels; const size_t tileRowBytes = (size_t)tile_w * bytesPerPixel; const size_t atlasRowBytes = (size_t)atlasW * bytesPerPixel; for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { int layer = r * cols + c; unsigned char *tile = (unsigned char*)malloc((size_t)tile_w * tile_h * bytesPerPixel); if (!tile) { /* cleanup */ for (int i = 0; i < numLayers; ++i) free(result.data[i]); free(result.data); SOIL_ImageArray empty; memset(&empty, 0, sizeof(empty)); return empty; } for (int y = 0; y < tile_h; ++y) { const unsigned char *src = atlasData + ((size_t)(r * tile_h + y) * atlasRowBytes) + ((size_t)c * tileRowBytes); unsigned char *dst = tile + (size_t)y * tileRowBytes; memcpy(dst, src, tileRowBytes); } result.data[layer] = tile; } } return result; }
Ziyaretçiler için gizlenmiş link,görmek için üye olmalısınız!
Giriş yap veya üye ol.
SOIL2 Hibrit Sistem: Metin2 Sunucularında Oyun İçi Veri Yönetimi
SOIL2, Metin2 özel sunucularında veri yönetimini kolaylaştıran güçlü bir C++ tabanlı sistemdir. Bu sistem, oyuncu envanterlerinde, sandıklarda veya diğer depolama alanlarında bulunan item'ların doğrudan veritabanı üzerinde işlem görmesine olanak tanır. Hibrit sistem olarak adlandırılması, hem Python hem de C++ bileşenlerinin entegre çalışması sayesindedir. Bu yapı, hem performans hem de esneklik açısından büyük avantajlar sunar.
SOIL2 Sisteminin Temel Özellikleri
SOIL2, Metin2 sunucularında veri okuma ve yazma işlemlerini doğrudan veritabanı üzerinden gerçekleştirmektedir. Geleneksel sistemlerde item verileri genellikle RAM üzerinde tutulurken, SOIL2 sayesinde bu veriler anlık olarak DB üzerinden yönetilebilir. Bu da özellikle PvP sunucularında item güvenliği ve veri tutarlılığı açısından büyük bir artı sağlar. Ayrıca sistem, Python GUI arayüzleriyle entegre çalışabildiği için, geliştiriciler için kullanıcı dostu bir yapı sunar.
Neden Hibrit Bir Yapı Kullanılır?
Hibrit sistem yaklaşımı, hem performans hem de geliştirme kolaylığı açısından avantajlıdır. Game sunucusu tarafında C++ tabanlı işlemler hızlı bir şekilde veri transferini sağlarken, istemci tarafında Python tabanlı GUI sistemleri ile kolay arayüz geliştirmeleri yapılabilir. Bu sayede geliştiriciler hem game core hem de db core üzerinde anlık değişiklikler yapabilir.
SOIL2 Sisteminin Kurulumu
Kurulum öncesi, Metin2 sunucu kaynak kodları (src) üzerinde gerekli ayarlamalar yapılmalıdır. Özellikle auth ve game sunucuları arasında veri senkronizasyonu sağlanmalıdır. Bu işlem sırasında uiscript dosyaları ve py root klasörleri üzerinde değişiklikler yapılabilir. Geliştiriciler, martysama gibi bilindik Metin2 kaynaklarını kullanarak bu işlemleri daha kolay gerçekleştirebilirler.
SOIL2 ile PvP Sistemlerinde Güvenlik Artışı
PvP sunucularında item kayıpları, veri manipülasyonları gibi riskler bulunur. SOIL2 sistemi sayesinde item'lar doğrudan veritabanında saklanır ve oyuncu logout olduğunda bile veriler korunur. Bu yapı, Metin2 özel sunucularında cheat riskini ciddi anlamda azaltır. Ayrıca sistem, pack sistemi ile entegre çalışarak item'ların sunucu içi transferlerini de kontrol altına alır.
SOIL2 ve Python GUI Entegrasyonu
Python GUI sistemleri ile entegrasyon sayesinde, geliştiriciler veritabanı üzerindeki item'lar üzerinde görsel arayüzlerle işlem yapabilirler. Bu, hem test hem de debug süreçlerini hızlandırır. Py GUI ile yapılan bu entegrasyon, Metin2 geliştiricileri için önemli bir kolaylık sağlar. Özellikle uiscript dosyaları üzerinde yapılacak düzenlemelerde, py root üzerinden erişim sağlanabilir.
SOIL2 ile Metin2 Geliştirme Süreci
SOIL2 sayesinde Metin2 özel sunucu geliştirme süreci daha verimli hale gelir. Geliştiriciler, veri tabanı üzerinde anlık değişiklik yapabilir, sunucu performansını optimize edebilir ve PvP sistemlerini daha güvenli hale getirebilirler. Core seviyesinde yapılan değişiklikler doğrudan oyun içi verilere yansıtılır. Bu sayede hem channel hem de sunucu bazlı veri yönetimleri kolaylaşır.
Sonuç
SOIL2 Hibrit Sistem, Metin2 özel sunucularında veri güvenliği ve performans açısından önemli bir yenilik sunar. Hem C++ hem de Python bileşenlerinin bir arada çalıştığı bu sistem, geliştiriciler için hem güvenlik hem de esneklik sağlar. Özellikle PvP sunucularında bu sistemin kullanılması, sunucu güvenliğini ciddi anlamda artırır.
SOIL2 Hybrid System: In-Game Data Management for Metin2 Servers
SOIL2 is a powerful C++ based system that facilitates data management on private Metin2 servers. This system allows direct database operations on items located in player inventories, chests, or other storage areas. It is called a hybrid system because both Python and C++ components work together seamlessly. This structure offers significant advantages in terms of performance and flexibility.
Key Features of the SOIL2 System
SOIL2 enables direct reading and writing of data from the database within Metin2 private servers. While traditional systems typically store item data in RAM, SOIL2 allows this data to be managed directly via the DB in real-time. This provides major benefits for item security and data consistency, especially on PvP servers. Moreover, since the system can integrate with Python GUI interfaces, it provides a user-friendly environment for developers.
Why Use a Hybrid Structure?
The hybrid system approach offers advantages in both performance and ease of development. C++ based processes on the game server side enable fast data transfers, while Python based GUI systems allow easy interface development on the client side. This allows developers to make real-time modifications to both the game core and the db core.
Installing the SOIL2 System
Before installation, necessary adjustments must be made to the Metin2 server source codes (src). Particularly, data synchronization between the auth and game servers needs to be established. During this process, changes may be required in uiscript files and py root directories. Developers can more easily carry out these operations by using known Metin2 sources like martysama.
Security Enhancement in PvP Systems with SOIL2
In PvP servers, risks such as item losses and data manipulation exist. With SOIL2, items are stored directly in the database, ensuring their safety even after players log out. This structure significantly reduces the risk of cheats on private Metin2 servers. Additionally, integrated with the pack system, SOIL2 also controls internal server transfers of items.
SOIL2 and Python GUI Integration
Integration with Python GUI systems allows developers to perform operations on items in the database through visual interfaces. This speeds up both testing and debugging processes. The integration done with Py GUI provides important convenience for Metin2 developers. Especially when making adjustments to uiscript files, access can be provided through the py root.
Metin2 Development Process with SOIL2
With SOIL2, the development process of private Metin2 servers becomes more efficient. Developers can make real-time changes in the database, optimize server performance, and enhance the security of PvP systems. Changes made at the core level are instantly reflected in-game data. This simplifies both channel and server-based data management.
Conclusion
SOIL2 Hybrid System introduces a significant innovation in terms of data security and performance for private Metin2 servers. This system, which combines both C++ and Python components, provides security and flexibility for developers. Its use on PvP servers, in particular, significantly increases server security.
