PDA

View Full Version : [JX] [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng



FanLoveJX
29-08-16, 02:08 PM
Đầu tiên xin gửi lời chúc sức khỏe đến các anh em trong box VLTK.

Mình có ít kinh nghiệm về resources xin phép chia sẻ với anh em, bài viết này chủ yếu dành cho newbie mong các bạn đã biết đừng ném đá ạ, ai chưa biết thì cứ hỏi nhiệt tình, còn ai biết rồi thì đóng góp thêm với ạ.

Sau bài viết này bạn sẽ có cái nhìn rõ hơn cũng như có thể tự mình viết được tools nén và xả nén file pak/spr hoặc làm hẵn một cái Editor để edit file pak, spr(Tĩnh/Động) :D.

[Phần 1] Pak


Cấu trúc file pak

File pack của king soft là file nén chứa resources của game như file txt, ini, dat, jpg, bmp, spr .v.v.v(mình sẽ dùng tên gọi chung là res).
Cấu trúc file pak gồm 3 phần:

Header: chứa thông tin chung cả file pak(Số lượng res trong file pak, vị trí truy cập của Block Offsets, .v.v.v).
Block Datas: chứa dữ liệu của từng file(Mỗi res được đưa vào file Pak dưới dạng block và được quản lý thông qua id, và id này được hash theo path của res vì vậy các tool unpack không thể tách được tên file, mà chỉ đưa ra dạng chung chung là các số thứ tự).
Block Offsets: chứa thông tin bộ nhớ của từng block(vị trí truy cập trên file pak, độ dài của block tính bằng byte).


Chi tiết trực quan: (Mình chỉ giải thích một số thông tin cần thiết)

Phần Header chứa 32 byte

Signature: chứa 4 byte nhận dạng file pak có giá trị "PAK ".
Count: số lượng res được nén trong file pak.
Index: Vị trí offset của BlockHeader đầu tiên


Phần Block Data chứa toàn bộ dữ liệu của res
Phần Block Offset chứa thông tin của từng res, mỗi res sẽ lưu thông tin tại đây với độ dài 16 byte bao gồm các thông tin sau:

ID: là định danh của file được hash bằng path của res (vd: /spr/ui/ui3/series/0.spr -> 127598303, cái này mình ví dụ thôi chứ không chính xác) toàn bộ file pak quản lý thông qua ID này, chính là lý do cần phải có path/tên mới unpak được res, và không thể hash ngược lại thành path/tên nhé = . = .
Offset: là vị trí bắt đầu dữ liệu của block nằm trên phần Block Datas.
RealLength: là kích thước trước khi nén(mọi đơn vị mình sẽ tính bằng byte hết).
Length: Kích thước sau khi nén cũng chính là kích thước của block nằm trên phần Block Datas, vậy ở đây ta có thể tính được độ lớn tối đa của một res trong file pak là 2^24 = 16777216 byte = 16 mbyte
Method: quy định phương thức nén của từng block ở đây mình check được một số phương thức như sau

Method = 0: Không nén dữ liệu chỉ đọc và rãi dữ liệu lên block.
Method = 1: Nén toàn bộ block bằng ucl(ucl là thư viện nén dữ liệu mà kingsoft sử dụng).
Method = 16: Hôm qua mới detect được, chưa xem kỹ dữ liệu giãi mã có đúng không nhưng dùng ucl decompress ra thì được đầu ra khớp số liệu trên BlockHeader
Method = 32: tương tự nhưng dạng 1. thường sử dụng để nén cả file spr(file pak mới của vina hay dùng mã này).
Method = 17: thường dùng nén frame file spr.(chi tiết cách nén frame mình sẽ đề cập ở phần tiếp theo).









<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> (<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>)

Cách đọc dữ liệu từ file pak(IDE mình dùng VS2013, Source mình viết theo cách ExportDll, Form mình dùng .Net cho nhanh do ko rành code form trên c++)

Đọc thông tin header file pak(Cấu trúc Header và BlockHeader xem trên hình bên trên)





inline static unsigned long GetCompressSize(BLOCKHEADER* header) {
return (((unsigned long)header->Length[2]) << 16) | (((unsigned long)header->Length[1]) << 8) | (unsigned long)header->Length[0];
}


int CPak::Load(const char* path, PACKHEDER* *Header) {
CString csPath(path);

PACKHEDER* pHeader; //Khởi tạo biến nhớ đọc header file pak
PBYTE pTemp; //Khởi tạo con trỏ đọc header
PBYTE oTemp; //Khởi tạo con trỏ đọc blockHeader

CFileException e;
if (m_File.m_hFile != (HANDLE)0xffffffff) {
m_File.Close();
}

if (!m_File.Open(csPath, CFile::modeRead | CFile::shareDenyWrite, &e))
{
return 0;
}


m_HeaderBuffer = new BYTE[32];
pTemp = m_HeaderBuffer; // đưa con trỏ về vị trí bộ nhớ chứa 32 byte thông tin header
m_File.Read(pTemp, 32); // Đọc 32 byte chứa header từ fileStream lên con trỏ pTemp
pHeader = (PACKHEDER*)pTemp; // Chuyển bộ nhớ con trỏ pTemp lên pHeader

m_OffsetBuffer = new BYTE[pHeader->Count * 16]; // Khởi tạo bộ nhớ chưa toàn bộ thông tin các offset
m_File.Seek(pHeader->Index, 0); // di chuyển con trỏ fileStream tới vị trí đầu tiên của blockHeader
m_File.Read(m_OffsetBuffer, pHeader->Count * 16); // Đọc toàn bộ dữ liệu lên bộ nhớ chứa thông tin blockOffset
oTemp = m_OffsetBuffer; // Chuyển vị trí con trỏ oTemp lên bộ nhớ vừa đọc để đọc thông tin BlockHeader

//for (int i = 0; i < pHeader->Count; i++) { //UnCommend đoạn này để xem bảng index các file show ở cửa sổ OutPut VS
//BLOCKHEADER* bHeader;
//bHeader = (BLOCKHEADER*)oTemp;
//CString outPutString;
//outPutString.Format(L"ID: %02x\tMethod: %d\tLength: %lu\tCompress: %lu\tOffset: %d \n", bHeader->ID, bHeader->Method, bHeader->RealLength, GetCompressSize(bHeader), bHeader->Offset);
//OutputDebugString(outPutString);
//oTemp += 16;
//}

*Header = (PACKHEDER*)m_HeaderBuffer; //Đưa con trỏ trên tham số đầu vào của phương thức về bộ nhớ 32 byte của header, do mình sử dụng .net nên set thế này rồi dung Marshal để đọc dữ liệu từ c++ qua c#
m_Count = pHeader->Count;
return m_Count;
}



Tách dữ liệu block

Sau khi lấy được danh sách các blockHeader dùng thông tin từ block header để bóc tách dữ liệu của res:

các bạn khai báo một số cấu trúc và biến để tiến hành phân tích block data


struct PACKHEDER {
unsigned char Signature[4];
unsigned long Count;
unsigned long Index;
unsigned long Data;
unsigned long CRC32;
unsigned char Reserved[12];
};

struct BLOCKHEADER {
unsigned long ID;
unsigned long Offset;
unsigned long RealLength;
BYTE Length[3];
unsigned char Method;
inline void operator = (BLOCKHEADER a) {
ID = a.ID;
Offset = a.Offset;
RealLength = a.RealLength;
Length[0] = a.Length[0];
Length[1] = a.Length[1];
Length[2] = a.Length[2];
Method = a.Method;
}
};

struct COMPRESSINFO {
long Compress;
long Size;
};

typedef struct
{
BYTE Comment[4];
WORD Width;
WORD Height;
WORD CenterX;
WORD CenterY;
WORD Frames;
WORD Colors;
WORD Directions;
WORD Interval;
WORD Reserved[6];
} SPRHEAD;

typedef struct
{
DWORD Offset;
DWORD Length;
} SPROFFS;

typedef struct
{
WORD Width;
WORD Height;
WORD OffsetX;
WORD OffsetY;
BYTE Sprite[1];
} SPRFRAME;


typedef struct {
BYTE Blue;
BYTE Green;
BYTE Red;
BYTE Alpha;
} KPAL32;

typedef struct {
BYTE Red;
BYTE Green;
BYTE Blue;
} KPAL24;

typedef WORD KPAL16;

BYTE* m_Buffer;
BYTE* m_Palette;
KPAL24* m_pPal24;
KPAL16* m_pPal16;
SPROFFS* m_pOffset;
PBYTE m_pSprite;
int m_nWidth;
int m_nHeight;
int m_nCenterX;
int m_nCenterY;
ULONG m_nFrames;
int m_nColors;
ULONG m_nDirections;
int m_nInterval;
int m_nColorStyle;
int m_nLum;
ULONG m_size;
int m_nFrameInfo;
CString m_sprPath;
DWORD* m_buffer32;




Tiến hành đọc và phân tích thông tin từ BlockHeader sau đó giải mã block data tương ứng với từng Method
(Ở đây mình viết inout theo cách lấy block thứ n của file, sau đó đổ dữ liệu đã giải mã ra buffer, bên c# dùng Marshal để đọc dữ liệu. Marshal là thư viện bên c# dùng để thao tác với dữ liệu unsafe anh em muốn tìm hiểu rõ hơn thì gg thêm nhé) mình có chú thích một chút ở từng đoạn code các bạn chú ý



int CPak::ReadBlock(int block, DWORD* *data) {
if (block < 0 || block >= m_Count) {
return 0;
}
if (m_ExtractBuffer != NULL) {
delete m_ExtractBuffer;
}

//Init File Mem Poiter
PBYTE oTemp = m_OffsetBuffer;
//Jump to Block Header Info Offset
oTemp += block * 16;
//Get Block Info from Mem
BLOCKHEADER* Header = (BLOCKHEADER*)oTemp;
if (Header->ID <= 0 || Header->Length <= 0 || Header->Offset <= 0) {
m_ExtractBuffer = new BYTE[1];
return 0;
}
//Caculate Compress Size of The Block
int size = GetCompressSize(Header);
//Init Block data Buffer
m_BlockBuffer = new BYTE[size];
//Seek File Mem To The Block Offset
m_File.Seek(Header->Offset, 0);
//Read Block Mem To Buffer
m_File.Read(m_BlockBuffer, size);

//Method = 1: Compress Image, ini, txt, ...etc
if (Header->Method == 0) {
//Get UnCompress Length
size = Header->RealLength;
//Return Mem Handle
*data = (DWORD*)m_BlockBuffer;
}
else if (Header->Method == 1) {
//Get UnCompress Length
size = Header->RealLength;
unsigned int dest_length = Header->RealLength;
//Init Buffer
m_ExtractBuffer = new BYTE[Header->RealLength];
unsigned int CompressSize = GetCompressSize(Header);
//Call Decompress Source Buffer
ucl_nrv2b_decompress_8(m_BlockBuffer, CompressSize, m_ExtractBuffer, &dest_length, 0);
//Release Buffer
delete m_BlockBuffer;
//Return Mem Handle
*data = (DWORD*)m_ExtractBuffer;
}
else if (Header->Method == 32) { // Phương thức nén mới(pak mới của vina), thực chất chỉ đổi id method, cách nén thì như Method 1
//Get UnCompress Length
size = Header->RealLength;
unsigned int dest_length = 0;
//Init Buffer
m_ExtractBuffer = new BYTE[Header->RealLength];
unsigned int CompressSize = GetCompressSize(Header);
//Call Decompress Source Buffer
ucl_nrv2b_decompress_8(m_BlockBuffer, CompressSize, m_ExtractBuffer, &dest_length, 0);
//Release Buffer
delete m_BlockBuffer;
//Return Mem Handle
*data = (DWORD*)m_ExtractBuffer;
}
//Method = 17: Compress Spr Image
else {
// Update sau phần 2;
}

return size;
}




- Các Method 0,1, 32 thì tương đối đơn giản chỉ nén toàn bộ block rồi ghi vào BlockData, Method 17 thì phức tạp hơn chỉ dùng cho file Spr và nén từng Frame
Mình xin tạm dừng phần này tại đây để mình đi chi tiết về cấu trúc SPR file, khi các bạn đã rõ về cấu trúc Spr thì phần nén frame này sẽ dễ hiểu hơn.

[Phần 2] Spr

Cấu trúc file Spr

File Spr(SpriteSheet) là loại file chứa nội dung hình ảnh trong game(Giao diện, NPC, Item .v.v.v)
Cấu trúc gồm:

SprHeader: chứa thông tin chung của file spr.
SprOffset: chứa thông tin vị trí và chiều dài dữ liệu từng frame.
SprFrame: chứa thông tin frame(chiều dài, rộng, độ lệch x, y.
SprColor: chứa bảng màu của file spr.


Chi tiết trực quan:

SprHeader chứa 32 byte thông tin file spr gồm các trường sau

Signature: chứa 4byte định danh file spr có giá trị là "SPR "
Width: chiều rộng spr
Height: chiều cao spr
CenterX: độ lệch X
CenterY: độ lệch Y
Frames: số frame của spr
Colors: số màu trên spr
Directions: số góc trên spr(mặc định có 1 hoặc 8 góc) chia đều frame cho các góc
Interval: tốc độ chạy frame mặc định


SprOffset chứa vị trí và chiều dài(byte) các frame gồm các thông tin sau

Offset: vị trí bộ nhớ của frame trên file pak
Length: chiều dài của frame


Array KPAL24 chứa bộ mã màu cho spr(về xử lý ảnh mình không đào sâu lắm nên mình không giải thích nhiều về phần này): số lượng màu được khai báo tại SprHeader->Colors
SprFrame: Định nghĩa chi tiết thông số của frame

Width: chiều rộng frame.
Height: chiều cao frame.
OriginX: độ lệch x.
OriginY: độ lệch y.
Data: được tính từ vị trí bắt đầu frame trừ đi độ lớn của thông tin frame kéo dài tới frame tiếp theo.








<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> (<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>)



Giải mã FrameSpr sang định dạng ARGB(Ảnh có nền trong suốt)

Toàn bộ ảnh spr trong game đều mã hóa dạng chiều sâu 24 bit tức là dùng KPAL24 để đánh bảng index màu cho spr
Từ bảng màu này qua một vài phép toán dịch bit và tách lấy màu từ bảng màu KPAL24 sẽ lấy được ảnh với format argb
Mình sẽ chỉ gới thiệu về giải mã từ 24 bit sang ARGB 32 bit, các bạn nào muốn lấy ảnh thấp hơn thì cách làm cũng tương tự






Khai báo biến



BYTE* m_Buffer;
BYTE* m_Palette;
KPAL24* m_pPal24;
KPAL16* m_pPal16;
SPROFFS* m_pOffset;
PBYTE m_pSprite;
int m_nWidth;
int m_nHeight;
int m_nCenterX;
int m_nCenterY;
ULONG m_nFrames;
int m_nColors;
ULONG m_nDirections;
int m_nInterval;
int m_nColorStyle;
int m_nLum;
ULONG m_size;
int m_nFrameInfo;
CString m_sprPath;
DWORD* m_buffer32;


Đọc thông tin file SPR



int CSpr::LoadSpr(const char* path)
{
CStringW szWide(path);
m_sprPath = path;

CFile File;
SPRHEAD* pHeader;
PBYTE pTemp;

CFileException e;
if (!File.Open(szWide, CFile::modeRead | CFile::shareDenyWrite, &e))
{
return 0;
}
m_sprPath = path;

m_size = File.GetLength();

m_Buffer = new BYTE[m_size];
pTemp = m_Buffer;

File.Read(pTemp, File.GetLength());

// check file header setup sprite member
pHeader = (SPRHEAD*)pTemp;

// get sprite info
m_nWidth = pHeader->Width;
m_nHeight = pHeader->Height;
m_nCenterX = pHeader->CenterX;
m_nCenterY = pHeader->CenterY;
m_nFrames = pHeader->Frames;
m_nColors = pHeader->Colors;
m_nDirections = pHeader->Directions;
m_nInterval = pHeader->Interval;

// setup palette pointer
pTemp += sizeof(SPRHEAD);
m_pPal24 = (KPAL24*)pTemp;

// setup offset pointer
pTemp += m_nColors * sizeof(KPAL24);
m_pOffset = (SPROFFS*)pTemp;

// setup sprite pointer
pTemp += m_nFrames * sizeof(SPROFFS);
m_pSprite = (LPBYTE)pTemp; // Ïà¶ÔÆ«ÒÆ

// make color table
m_Palette = new BYTE[m_nColors * sizeof(KPAL16)];


//caculate palete color
Make4444Palette();

return m_size;
}


Đọc thông tin frame và dịch sang mảng byte b-r-g-a, Những hàm còn thiếu ở đây đã có sẵn trong source Utility\Source\Image



int CSpr::GetSprFrame(DWORD* *data, int nFrame) {
if (nFrame < 0 || nFrame >= m_nFrames)
return 2;

//extract image size
ULONG width,height;
GetSize(nFrame,width,height);

WORD* pDest = new WORD[width*height];
ZeroMemory(pDest,sizeof(WORD)*width*height);
stImageRender render;
render.ptDes.x = 0;
render.ptDes.y = 0;
render.buffer = pDest;
render.nPitch = width * 2;
render.nFrame = nFrame;
RenderToA4R4G4B4(render);
if (!m_buffer32) {
delete m_buffer32;
}
m_buffer32 = new DWORD[width*height];

char* p32 = (char*)m_buffer32;
WORD* p16 = pDest;
BYTE a,r,g,b;
for (int i=0; i<width*height; i++)
{
GetColorA4R4G4B4Format(*p16++,a,r,g,b);
*p32++ = b;
*p32++ = g;
*p32++ = r;
*p32++ = a;
}
*data = (DWORD*)m_buffer32;

delete pDest;
return width*height*4;
}


HRESULT CSpr::RenderToA4R4G4B4(stImageRender& render)
{
if (render.nFrame < 0 || render.nFrame >= m_nFrames)
return FALSE;

SPRFRAME* pFrame = (SPRFRAME*)(GetFrame(render.nFrame));
int height = pFrame->Height;
int width = pFrame->Width;

long nNextLine = render.nPitch - width * 2;
PBYTE pSrc = pFrame->Sprite;
PBYTE pPalette = (PBYTE)GetPalette();
WORD* pDest = (WORD*)render.buffer;
pDest += ( render.ptDes.y * render.nPitch / 2 + render.ptDes.x ) ;

__asm
{

mov edi, pDest
mov esi, pSrc

loc_DrawSprite_0100:

mov edx, width

loc_DrawSprite_0101:


movzx eax, byte ptr[esi]
inc esi
movzx ebx, byte ptr[esi]
inc esi
or ebx, ebx
jnz loc_DrawSprite_0102

push eax
mov ecx, eax

loc_FillZeroAlpha:


mov [edi], 0
inc edi
inc edi
dec ecx
jnz loc_FillZeroAlpha
pop eax

sub edx, eax
jg loc_DrawSprite_0101
add edi, nNextLine
dec height
jnz loc_DrawSprite_0100
jmp loc_DrawSprite_exit



loc_DrawSprite_0102:

push eax
push edx

and bx, 0x00f0
shl bx, 8
push ebx

mov ecx, eax


loc_DrawSprite_0103:

mov ebx, pPalette
movzx eax, byte ptr[esi]
inc esi
mov dx, [ebx + eax * 2]

pop ebx
push ebx

or dx, bx
mov [edi], dx
inc edi
inc edi
dec ecx
jnz loc_DrawSprite_0103
pop ebx
pop edx
pop eax
sub edx, eax
jg loc_DrawSprite_0101
add edi, nNextLine
dec height
jnz loc_DrawSprite_0100
jmp loc_DrawSprite_exit

loc_DrawSprite_exit:


}
return S_OK;
}


Sắp tới share cho anh em PakEditor dùng chơi, unpack được file pak mới, có preview cho Spr và hỗ trợ luôn file Spr mới
500đ ảnh
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> (<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>)

hu_go1224
29-08-16, 03:49 PM
Bài viết rất hữu ích thớt, bác có thể đi sâu vào phần làm thế nào để source load được pak mới của VNG hem?

FanLoveJX
29-08-16, 04:11 PM
Bài viết rất hữu ích thớt, bác có thể đi sâu vào phần làm thế nào để source load được pak mới của VNG hem?

Mai mình sẽ chi tiết sâu về phần nén file, và so sánh pak của source cũ và pak mới của vinagame nhé, Bác cứ theo dõi hết phần pak này, từ đây bạn dò vào source sẽ sửa được source load pak mới của vinagame.

BladeKnight109
29-08-16, 04:45 PM
Ai muốn hiểu thêm về cách load file pak của jx thì xem thêm trong source Engine.

vocweb
29-08-16, 04:52 PM
Cái này không dành cho người "yếu tim" nhỉ :">

nhaodzo
29-08-16, 05:37 PM
nhìn một nùi là thấy chóng mặt rồi :(. thôi đành ngậm ngùi đợi cao nhân vô vậy ..

HoangTVT
29-08-16, 06:15 PM
Những spr được ra đời sau này theo cách load của engine hiện tại thì vị lỗi hình ảnh vẫn hiển thị màu nền, không giống những spr cũ. Mình thì ngu vụ này lắm theo mình đoán thì có lẽ họ thêm định nghĩa màu được hiển thị trong suốt nên engine cũ không thể load được, theo hướng đó mình đã tìm rất nhiều đoạn quy định về mã màu nhưng cũng k khả quan mấy, có lẽ mình sai. May mắn hôm nay gặp được bạn, bạn có thể nào giải thích giúp mình được không.

wermanhme1990
29-08-16, 06:31 PM
Chủ toppic cho mình hỏi chút:
Mình để ý thấy folder data của jx vng rất nặng không phải vì tài nguyên đã được chọn lọc, loại bỏ, mà bị trùng tài nguyên rất nhiều, ví dụ: phần login game, nếu bỏ những pack update mới đi, ta sẽ được phần login của pack củ. Nếu bỏ đi những phần tài nguyên trùng lặp, dung lượng client sẽ rất nhẹ.
Vậy có phải không thể đọc được chính xác tên file trong pack nếu không có file list?.

HoangTVT
29-08-16, 06:43 PM
.................................................. ................

vuduymanh
29-08-16, 07:46 PM
Chủ topic làm 1 cái tool unpach script và settings trong pak mới của vng đc ko bác

dongmau
29-08-16, 07:50 PM
HAYYYYYYYYYYYYYYYYYYYYYYYY QUÁ

<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
Khi nào rảnh sẽ học
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

FanLoveJX
29-08-16, 08:28 PM
Những spr được ra đời sau này theo cách load của engine hiện tại thì vị lỗi hình ảnh vẫn hiển thị màu nền, không giống những spr cũ. Mình thì ngu vụ này lắm theo mình đoán thì có lẽ họ thêm định nghĩa màu được hiển thị trong suốt nên engine cũ không thể load được, theo hướng đó mình đã tìm rất nhiều đoạn quy định về mã màu nhưng cũng k khả quan mấy, có lẽ mình sai. May mắn hôm nay gặp được bạn, bạn có thể nào giải thích giúp mình được không.

Engine trên source gốc đã có định nghĩa hàm giải mã màu ARGB rồi, bị màu nền đen là do tool convert spr nằm trong source không sử dụng hàm này, nó xài hàm r4g4b4 nhé thành ra spr mà bạn convert đc bị nền đen cho nên bạn mà dùng tools có sẳn trên diễn đàn để tạo spr động thì dính nền đen thì phải :D, mình xem qua source "SprConvert" và "ImageCreator" thì thấy vậy.

FanLoveJX
29-08-16, 08:40 PM
Chủ toppic cho mình hỏi chút:
Mình để ý thấy folder data của jx vng rất nặng không phải vì tài nguyên đã được chọn lọc, loại bỏ, mà bị trùng tài nguyên rất nhiều, ví dụ: phần login game, nếu bỏ những pack update mới đi, ta sẽ được phần login của pack củ. Nếu bỏ đi những phần tài nguyên trùng lặp, dung lượng client sẽ rất nhẹ.
Vậy có phải không thể đọc được chính xác tên file trong pack nếu không có file list?.

Về trùng file: Chính xác rồi bạn, thay vì ghi đè res lên pak file thì tạo file pak mới rồi trong config đặt nó lên độ ưu tiên cao hơn, Engine sẽ hash path spr thành id rồi rò ra đúng địa chỉ bộ nhớ chứa res rồi xử lý theo từng loại file,

Về tên file: Cũng đúng luôn bạn, do tên/path res đã bị hash 1 chiều, không dịch ngược được nên mình chỉ có thể tách res khi có tên/path đầy đủ của res

Mình có viết 1 tool bóc tách lấy toàn bộ list file .spr .txt .ini .jpg .bmp được khoảng vài ngàn file =)) mở lên thì thấy vẫn thiếu nhiều đc tầm 30-40%

--- Chế độ gộp bài viết ---


Chủ topic làm 1 cái tool unpach script và settings trong pak mới của vng đc ko bác

Xem bài + nghiên cứu source rồi tự làm mới thú vị chứ bạn :D

HoangTVT
29-08-16, 08:49 PM
Engine trên source gốc đã có định nghĩa hàm giải mã màu ARGB rồi, bị màu nền đen là do tool convert spr nằm trong source không sử dụng hàm này, nó xài hàm r4g4b4 nhé thành ra spr mà bạn convert đc bị nền đen cho nên bạn mà dùng tools có sẳn trên diễn đàn để tạo spr động thì dính nền đen thì phải :D, mình xem qua source "SprConvert" và "ImageCreator" thì thấy vậy.

không phải spr được mình convert đâu bạn ơi, như bạn xem trong hình, với spr cũ thì không hiển thị phần màu đen như trong hình


<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> (<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>)

wermanhme1990
29-08-16, 08:51 PM
Về trùng file: Chính xác rồi bạn, thay vì ghi đè res lên pak file thì tạo file pak mới rồi trong config đặt nó lên độ ưu tiên cao hơn, Engine sẽ hash path spr thành id rồi rò ra đúng địa chỉ bộ nhớ chứa res rồi xử lý theo từng loại file,

Về tên file: Cũng đúng luôn bạn, do tên/path res đã bị hash 1 chiều, không dịch ngược được nên mình chỉ có thể tách res khi có tên/path đầy đủ của res

Mình có viết 1 tool bóc tách lấy toàn bộ list file .spr .txt .ini .jpg .bmp được khoảng vài ngàn file =)) mở lên thì thấy vẫn thiếu nhiều đc tầm 30-40%


Cảm ơn bạn, Theo mình hiểu thế này: thường file bị pack, cụ thể ở đây pack thành .pak. Khi file game.exe chạy bắt buộc phải giải mã .pak đó?, load vào ram(Vì mình có thể dùng 1 số chương trình đọc bộ nhớ ram để lấy đường dẫn res để unpack mặc dù không đầy đủ).
Vậy tên/path res đã bị hash 1 chiều, game nó sẽ dùng trực tiếp mã hash đó hay nó sẽ chuyển hash sang tên/path rồi mới dùng.

FanLoveJX
29-08-16, 09:01 PM
không phải spr được mình convert đâu bạn ơi, như bạn xem trong hình


<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> (<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>)

Bạn có thể úp spr này lên được ko? gửi mình debug với, mình đoán chiều sâu ảnh đầu vào và đầu ra không khớp.

--- Chế độ gộp bài viết ---


Cảm ơn bạn, Theo mình hiểu thế này: thường file bị pack, cụ thể ở đây pack thành .pak. Khi file game.exe chạy bắt buộc phải giải mã .pak đó?, load vào ram(Vì mình có thể dùng 1 số chương trình đọc bộ nhớ ram để lấy đường dẫn res để unpack mặc dù không đầy đủ).
Vậy tên/path res đã bị hash 1 chiều, game nó sẽ dùng trực tiếp mã hash đó hay nó sẽ chuyển hash sang tên/path rồi mới dùng.

Mình bổ sung thêm một ý là nó ko giải mã hết mà cần res nào thì game tìm rồi load chứ ko load hết nên bạn ko lấy đc đầy đủ res.
ví dụ như khi draw một item nào đấy: /Spr/Ui/Item/item01.spr, Game sẽ hash path spr thành id rồi dò trên từng file pak cho đến khi tìm được block có id đấy, => giải mã rồi draw

HoangTVT
29-08-16, 09:12 PM
ngại quá, loại spr này mình không thể view bằng rpg, tool mình dùng cũng k unpack được, mình có đường dẫn hi vọng bạn có cách

\spr\skill\1502\em\em_150_jiane_ice.spr
nằm trong updatejx09.pak

wermanhme1990
29-08-16, 09:13 PM
Mình bổ sung thêm một ý là nó ko giải mã hết mà cần res nào thì game tìm rồi load chứ ko load hết nên bạn ko lấy đc đầy đủ res.
ví dụ như khi draw một item nào đấy: /Spr/Ui/Item/item01.spr, Game sẽ hash path spr thành id rồi dò trên từng file pak cho đến khi tìm được block có id đấy, => giải mã rồi draw

Có cách nào dịch được hash sang tên/path không bạn, Ở một số game mình thấy có tools unpack data hoặc lấy được list file trong data bị pack.

FanLoveJX
29-08-16, 09:17 PM
Có cách nào dịch được hash sang tên/path không bạn, Ở một số game mình thấy có tools unpack data hoặc lấy được list file trong data bị pack.

Những game chắc đấy có lưu thông tin đầy đủ nên unpack được, còn file pak của kingsoft thì không được bạn bạn ngồi xem source pack vs unpack của nó là biết, cách quản lý theo id ntn thì tìm kiếm file cực nhanh :D tối ưu chi phí

data1990
29-08-16, 09:20 PM
Những game chắc đấy có lưu thông tin đầy đủ nên unpack được, còn file pak của kingsoft thì không được bạn bạn ngồi xem source pack vs unpack của nó là biết, cách quản lý theo id ntn thì tìm kiếm file cực nhanh :D tối ưu chi phí

Bác có bộ source trắng nào update lên VS 2013 không, share cho a e với. Chứ VC++6 cũ quá rồi

trananh88vt
29-08-16, 09:26 PM
ngại quá, loại spr này mình không thể view bằng rpg, tool mình dùng cũng k unpack được, mình có đường dẫn hi vọng bạn có cách

\spr\skill\1502\em\em_150_jiane_ice.spr
nằm trong updatejx09.pak

Tưởng bác làm được cái này rùi chứ. Hihi.
Spr mới của VNG nó vẽ ra kiểu khác nó dùng thuật toán blend màu giống PTS á.
Không tin bác cứ mang spr mới vào PTS rùi chỉnh sang dạng blend là xem được ngon.

Cái này thần đèn bật mí và đã làm thành công. Chúc bác thành công theo nhé keke.

hxhhxhz
29-08-16, 09:36 PM
thường thường thỳ làm s để canh được độ dài rộng to nhỏ của 1 trang bị nhỉ ???????????????

HoangTVT
29-08-16, 09:56 PM
Tưởng bác làm được cái này rùi chứ. Hihi.
Spr mới của VNG nó vẽ ra kiểu khác nó dùng thuật toán blend màu giống PTS á.
Không tin bác cứ mang spr mới vào PTS rùi chỉnh sang dạng blend là xem được ngon.

Cái này thần đèn bật mí và đã làm thành công. Chúc bác thành công theo nhé keke.

Không phải không tin mà tại cái thằng dốt bền nó cứ theo <b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> Phải theo cách giải thích như này k trananh


Với Screen nó sẽ tìm từng kênh thông tin màu và nhân với màu ngược lại của màu hoà trộn và màu cơ bản. Màu kết quả sẽ luôn luôn là một màu sáng hơn. Nếu bạn thiết lập chế độ Screen với màu đen thì màu sẽ không thay đổi, ngược lại, hoà trộn với màu trắng sẽ cho ra màu trắng. Hiệu ứng này giống như kiểu chiếu sáng những tấm phim ảnh chồng lên nhau

kanhtien
29-08-16, 11:14 PM
Topic hay, anh em dung tool nào để lấy spr ở file lớn ra vậy

HoangTVT
29-08-16, 11:24 PM
Bạn có thể úp spr này lên được ko? gửi mình debug với, mình đoán chiều sâu ảnh đầu vào và đầu ra không khớp.[COLOR="Silver"]

<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

link spr đây bạn

trananh88vt
29-08-16, 11:29 PM
Không phải không tin mà tại cái thằng dốt bền nó cứ theo <b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b> Phải theo cách giải thích như này k trananh

Chắc là zậy hehe. Nói chung nó nhức đầu lém. Code màu thì code = ASM cả ngàn dòng đọc không cũng nhức đầu rùi :D

FanLoveJX
29-08-16, 11:49 PM
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

link spr đây bạn
Spr không có gì khác, bác viết thêm mode Additive cho Core Draw là ngon nhé :3

<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

bác để ý kỹ xem, quăng skill dồn spr nó nháy càng sáng hơn => Additive Mode ấy
cho bác 500đ ảnh

<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

FanLoveJX
29-08-16, 11:56 PM
Chắc là zậy hehe. Nói chung nó nhức đầu lém. Code màu thì code = ASM cả ngàn dòng đọc không cũng nhức đầu rùi :D

Bác nói chuẩn rồi dưới core phần draw toàn ASM :3 thôi bỏ qua :v

BladeKnight109
30-08-16, 04:33 AM
Bác nói chuẩn rồi dưới core phần draw toàn ASM :3 thôi bỏ qua :v

Dịch ngược hoặc viết lại phần đó luôn :)

assaa
30-08-16, 05:39 PM
Tưởng bác làm được cái này rùi chứ. Hihi.
Spr mới của VNG nó vẽ ra kiểu khác nó dùng thuật toán blend màu giống PTS á.
Không tin bác cứ mang spr mới vào PTS rùi chỉnh sang dạng blend là xem được ngon.

Cái này thần đèn bật mí và đã làm thành công. Chúc bác thành công theo nhé keke.

Unpack được spr nhưng chưa có cách để export ra file ảnh để mở trên pts. Nên cũng ko blend đc

FanLoveJX
30-08-16, 07:47 PM
Unpack được spr nhưng chưa có cách để export ra file ảnh để mở trên pts. Nên cũng ko blend đc

bác cứ bám theo bài viết này sẽ unpack từ pak mới và export ra ảnh vô tư nhé :D

nhulaichuong
30-08-16, 10:57 PM
hix hix, source biết ta mà ta ko biết source, đọc vô như đám rừng, bị hack não luôn. Các bác thông minh quá.

BladeKnight109
04-09-16, 05:47 PM
Load Pak mới của VNG: <b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

FanLoveJX
04-09-16, 09:00 PM
Load Pak mới của VNG: <b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

bác giải thích luôn chứ ném lên thế mấy ae mới tập code lại không rõ

kudespkc
25-08-17, 10:22 AM
Bác FanloveJX ơi share mình tool Kingsoft Resource Editor bác chụp trong bài viết được không, mình muốn sửa vs update thêm mớ hiệu ứng nhưng không rành code cho lắm nên muốn dùng editor để edit trực tiếp hình ảnh.:-<

xtnet123
31-08-18, 06:01 AM
Bạn có thể úp spr này lên được ko? gửi mình debug với, mình đoán chiều sâu ảnh đầu vào và đầu ra không khớp.

--- Chế độ gộp bài viết ---



Mình bổ sung thêm một ý là nó ko giải mã hết mà cần res nào thì game tìm rồi load chứ ko load hết nên bạn ko lấy đc đầy đủ res.
ví dụ như khi draw một item nào đấy: /Spr/Ui/Item/item01.spr, Game sẽ hash path spr thành id rồi dò trên từng file pak cho đến khi tìm được block có id đấy, => giải mã rồi draw

Làm thế nào để đối phó với nền đen này?

ntquang.info
14-09-18, 03:10 PM
Xin info liên hệ hoặc add skype ntquang.info có việc nha FanLoveJX

FanLoveJX
15-09-18, 11:10 PM
Làm thế nào để đối phó với nền đen này?

draw với chế độ additive là được

xtnet123
16-09-18, 12:41 AM
draw với chế độ additive là được

Làm thế nào để đạt được nó? Có mã không? Cảm ơn ..

FanLoveJX
17-09-18, 06:34 PM
Làm thế nào để đạt được nó? Có mã không? Cảm ơn ..

Tìm function "g_DrawSpriteAlpha" trong KDrawSpriteAlpha và chỉnh thêm KCanvas class

xtnet123
17-09-18, 06:48 PM
Tìm function "g_DrawSpriteAlpha" trong KDrawSpriteAlpha và chỉnh thêm KCanvas class

Đây là ASM Mã, rất khó để điều chỉnh.Có giúp được gì không?Hoặc cho một mã......

FanLoveJX
22-09-18, 09:03 AM
Đây là ASM Mã, rất khó để điều chỉnh.Có giúp được gì không?Hoặc cho một mã......
quá đơn giản, nhưng mình ko quan tâm tới jx nữa :D

xtnet123
22-09-18, 01:59 PM
quá đơn giản, nhưng mình ko quan tâm tới jx nữa :D

Giúp tôi, cho tôi bức thư, cám ơn!

thanhhovn
20-10-18, 09:00 PM
Nhá hàng :
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
Cần tool làm thì pm,Có giá để trả công làm ra.

thienson062
25-05-19, 03:33 PM
Xin giúp đỡ lấy SPR của game Kiếm Thế .. đã upack file PAK ra txt

ililpi
03-08-19, 02:31 PM
Cho mình xin link download PakEditor được không chủ thớt ơi

btbaotrung90
04-09-21, 10:10 PM
Có ai còn ở đây không?
sao cái code của chủ thớt ở trang 1 thiếu tùm lum thế nhỉ
VD CStringW szWide(path); CFile File;
mình ko biết lấy ở đâu luôn, ai chạy dc code này xin chỉ giáo với ạ.

BladeKnight109
05-09-21, 08:07 AM
Có ai còn ở đây không?
sao cái code của chủ thớt ở trang 1 thiếu tùm lum thế nhỉ
VD CStringW szWide(path); CFile File;
mình ko biết lấy ở đâu luôn, ai chạy dc code này xin chỉ giáo với ạ.

thớt chỉ hướng dẫn cấu trúc của 1 file spr thôi, còn mục đích các bạn muốn làm gì khi đã hiểu về spr thì đó là do các bạn. Chứ không ai share hết mọi thứ đâu

btbaotrung90
05-09-21, 11:01 AM
thớt chỉ hướng dẫn cấu trúc của 1 file spr thôi, còn mục đích các bạn muốn làm gì khi đã hiểu về spr thì đó là do các bạn. Chứ không ai share hết mọi thứ đâu
Ờ do mình ko rành c++ mà h mình đang muốn xuất spr sang ảnh nhưng vướng 1 vài đoạn code.
Đâu phải ai cũng có khả năng làm dc.
Ai giúp mình với, mình xin gửi tiền cafe

BladeKnight109
05-09-21, 04:22 PM
Ờ do mình ko rành c++ mà h mình đang muốn xuất spr sang ảnh nhưng vướng 1 vài đoạn code.
Đâu phải ai cũng có khả năng làm dc.
Ai giúp mình với, mình xin gửi tiền cafe

Bạn tham khảo bên source engine của jx win. Đầy đủ, chi tiết.

banynavy
06-09-21, 12:16 PM
mình cần tool này bạn check tin nhắn nhé

Learning
06-09-21, 03:34 PM
mình cần tool này bạn check tin nhắn nhé

éo có mùa xuân ấy đâu, bớt khùng đi thằng khùng.