Kết quả 1 đến 10 của 52
-
29-08-16, 02:08 PM #1
- Ngày tham gia
- Jul 2008
- Bài viết
- 69
- Thanks
- 5
- Thanked 158 Times in 18 Posts
[Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
Đầ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) .
[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).
- Phần Header chứa 32 byte
[Only registered and activated users can see links. ]
- 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)
Code: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
Code: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;
(Ở đâ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ú ý
Code: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.
- SprHeader chứa 32 byte thông tin file spr gồm các trường sau
- 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
Code: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
Code: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
Code: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; }
500đ ảnh
[Only registered and activated users can see links. ]Lần sửa cuối bởi FanLoveJX, ngày 31-08-16 lúc 09:28 AM. Lý do: update bài
Khách viếng thăm hãy cùng FanLoveJX xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
The Following 61 Users Say Thank You to FanLoveJX For This Useful Post:
6558503 (29-08-16), AlexKing (29-08-16), alopay (30-08-16), Anh2SiTinh (29-08-16), anhhungkiemthe (07-09-21), anhtuanapt (30-08-16), assaa (30-08-16), authanhi (02-09-16), BladeKnight109 (29-08-16), Century (04-08-19), cuongvh93 (29-08-16), davidtuan25 (29-12-18), dongmau (29-08-16), dongnguyen0510 (31-08-18), dovietthai (29-08-16), duccom0123 (31-08-18), duynguyenjx (06-09-16), giangleloi (06-09-21),
gztlove114(07-09-21), HoangTVT (29-08-16),HungDevJX(29-08-16), huntersun (29-08-16), hu_go1224 (29-08-16), JXDev (04-09-16), kanhtien (29-08-16), kehuydietUS (29-08-16), khainqps01237 (31-08-16), khungboktvn (01-09-16), kuroo123 (29-08-16), langnhatanh (04-04-20), lengoctuan.dl (29-08-16), minhduc_aa (29-08-16), minhkhanh109 (29-08-16), Mr.N2K (29-08-16), mrdoanhit (30-01-18), nampinn (30-08-16), ngaolun (29-08-16), ngockiem (31-08-16), nhaodzo (29-08-16), operabn (26-12-20), pykhung (04-09-16), SaoThaiBinh72 (28-11-18), satthupro95 (29-08-16), shinrenkyo (31-08-16), tan_vu646 (29-08-16), thanhtunghk (29-08-16), tianlong (31-12-22), toan1993 (14-09-18), togashi007 (29-08-16), trananh88vt (29-08-16), trung135 (29-08-16), TruongPhi0802 (22-09-18), tuanhdvn (05-09-16), tului (11-10-21), vd_tt (29-08-16), volamchina1 (25-08-17), vuduymanh (29-08-16), wermanhme1990 (29-08-16), xomnhalalop12 (06-09-16), xtfcpwffg (05-06-24), yoken9x (30-08-16)
-
29-08-16, 03:49 PM #2
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
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?
Khách viếng thăm hãy cùng hu_go1224 xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 04:11 PM #3
- Ngày tham gia
- Jul 2008
- Bài viết
- 69
- Thanks
- 5
- Thanked 158 Times in 18 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
Khách viếng thăm hãy cùng FanLoveJX xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 04:45 PM #4
-
29-08-16, 04:52 PM #5
- Ngày tham gia
- Oct 2008
- Bài viết
- 456
- Thanks
- 58
- Thanked 114 Times in 96 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
Cái này không dành cho người "yếu tim" nhỉ
Khách viếng thăm hãy cùng vocweb xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 05:37 PM #6
- Ngày tham gia
- Aug 2008
- Bài viết
- 959
- Thanks
- 338
- Thanked 585 Times in 249 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
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 ..
Keep Moving Forward
-
29-08-16, 06:15 PM #7
- Ngày tham gia
- Mar 2014
- Bài viết
- 274
- Thanks
- 42
- Thanked 165 Times in 97 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
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.
Khách viếng thăm hãy cùng HoangTVT xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 06:31 PM #8
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
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?.Khách viếng thăm hãy cùng wermanhme1990 xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 06:43 PM #9
- Ngày tham gia
- Mar 2014
- Bài viết
- 274
- Thanks
- 42
- Thanked 165 Times in 97 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
.................................................. ................
Khách viếng thăm hãy cùng HoangTVT xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
-
29-08-16, 07:46 PM #10
- Ngày tham gia
- Sep 2014
- Đang ở
- Lâm An
- Bài viết
- 957
- Thanks
- 490
- Thanked 427 Times in 231 Posts
Ðề: [Source] Cấu trúc file Pak/Spr và cách tạo ra chúng
Chủ topic làm 1 cái tool unpach script và settings trong pak mới của vng đc ko bác
Khách viếng thăm hãy cùng vuduymanh xây dựng diễn đàn CLBGAMESVN vững mạnh nhé!
Các Chủ đề tương tự
-
[Gunny] Các bac Pro chỉ giáo. file nào trong source là file hiệu ứng châu báu
Bởi laibixoa trong diễn đàn Hỏi Đáp/ Yêu CầuTrả lời: 1Bài viết cuối: 09-07-14, 01:47 PM -
[Gunny] Hệ thống châu báu gồm những file nào trong source
Bởi hoanganhgo trong diễn đàn Hỏi Đáp/ Yêu CầuTrả lời: 5Bài viết cuối: 07-06-13, 10:06 AM -
[JX] Cần tìm file để trong source để việt hóa
Bởi assaa trong diễn đàn Hỏi Đáp/ Yêu CầuTrả lời: 1Bài viết cuối: 07-08-12, 04:07 PM -
source VB tạo file logIn cho MU đây
Bởi congacon trong diễn đàn SQL Server & WebsiteTrả lời: 36Bài viết cuối: 10-04-09, 04:26 PM -
Source tạo file Login cho Mu
Bởi congacon trong diễn đàn ReleasesTrả lời: 1Bài viết cuối: 01-01-09, 09:36 PM