İçeriğe geç

Metin2 Pack Dosyaları: EPK ve EIX Nedir?

Hazırlayan: Metin2VIP Editörleri Yayın: 7 dk okuma

Kısaca: Metin2 istemcisinde her paket iki dosyadır: .eix dosya listesini (ad, boyut, konum, sıkıştırma türü) tutar, .epk ise verinin kendisini. İstemci bir dosyayı adının CRC32 değeriyle eix'te bulur, epk'den okur ve türüne göre açar. 0-2 numaralı türler (düz, LZO, LZO ile şifreli) istemcinin kendi içindeki bilgiyle açılır; 3-5 numaralı türler anahtarlarını oturum açılırken sunucudan alır.
İçindekiler
  1. EIX dosyası ne içerir?
  2. EPK dosyası ve dosya adları
  3. Sıkıştırma ve şifreleme türleri
  4. İstemci paket listesini nasıl okur?
    1. Python betikleri paketten nasıl okur?
  5. Yeni bir pack nasıl eklenir?
  6. makepackscript dosyası ne anlatır?
  7. Sunucu tarafında paket anahtarları
  8. Paketlemede sık yapılan hatalar

Metin2 istemcisi oyun dosyalarını tek tek değil, paketler hâlinde taşır. Her paket iki dosyadan oluşur: .eix dosya listesini (ad, boyut, konum, sıkıştırma türü) tutar, .epk verinin kendisini. İstemci bir dosyaya ihtiyaç duyduğunda adını küçük harfe çevirip CRC32 değerini hesaplar, eix içindeki kaydı bulur, epk'den o bölümü okur ve gerekiyorsa açar ya da şifresini çözer.

Paketlerin istemci klasöründeki yeri ve hangi paketin ne taşıdığı Metin2 client klasör yapısı yazısında. Burada biçimin kendisi, sıkıştırma türleri ve istemcinin paketleri hangi sırayla okuduğu anlatılıyor.

EIX dosyası ne içerir?

eix dosyası 12 baytlık bir başlıkla başlar: EPKD imzası, sürüm numarası (2) ve kayıt sayısı. Ardından her dosya için sabit boyda bir kayıt gelir. İstemci kaynak kodundaki tanım şöyledir:

typedef struct SEterPackIndex
{
	long  id;               // kaydın sırası
	char  filename[161];    // sanal yol, en çok 160 karakter
	DWORD filename_crc;     // yolun CRC32 değeri
	long  real_data_size;   // epk içinde ayrılan yer
	long  data_size;        // verinin gerçek boyu
	DWORD data_crc;         // verinin CRC32 değeri
	long  data_position;    // epk içindeki başlangıç
	char  compressed_type;  // 0-5 arası tür
} TEterPackIndex;

Yapı 4 bayta hizalı tanımlandığı için her kayıt 192 bayt tutar. İstemci eix'i iki biçimde kabul eder: EPKD ile başlayan düz dosya ya da MCOZ ile başlayan, LZO ile sıkıştırılıp şifrelenmiş dosya. Sürüm 2 değilse ya da dosya boyu kayıt sayısını karşılamıyorsa "Pack index file ... error" hatası syserr.txt'ye düşer ve paket yüklenmez.

EPK dosyası ve dosya adları

epk'nin bir başlığı yoktur; her dosyanın verisi eix kaydındaki data_position noktasından başlar. Paketleme sırasında her dosyaya 256 baytlık bloklara yuvarlanmış bir yer ayrılır. Bir dosya silindiğinde ya da büyüyüp eski yerine sığmadığında eski yeri boş blok olarak kalır ve sonraki dosyalar için yeniden kullanılır. Aynı paket defalarca güncellendikçe epk'de bu boşluklar birikir; baştan oluşturulan pakette olmaz.

Dosya adları paketlenirken ve aranırken aynı dönüşümden geçer: bütün harfler küçültülür, \ işaretleri / olur. Bu yüzden SkillDesc.txt ile skilldesc.txt aynı dosyadır. Ad en çok 160 karakter olabilir. İstemci aramayı adın kendisiyle değil CRC32 değeriyle yapar, sonra adı ayrıca karşılaştırır.

Paket içindeki yollar sanaldır. Modeller ve efektler d:/ymir work/..., simgeler icon/..., dil dosyaları locale/tr/..., sesler sound/..., haritalar doğrudan harita klasörünün adıyla (metin2_map_a1/setting.txt) kayıtlıdır. Yolunda hiç / geçmeyen dosyalar (system.py gibi) root paketine aittir.

Sıkıştırma ve şifreleme türleri

Her kaydın son alanı dosyanın nasıl saklandığını söyler. Kaynak kodda altı tür tanımlıdır:

Tür Kodda adı Ne yapar Açmak için gereken
0 NONE Dosya olduğu gibi saklanır. Hiçbir şey
1 COMPRESS LZO ile sıkıştırılır. Yalnız istemci
2 SECURITY LZO ile sıkıştırılır, TEA ile şifrelenir. Anahtar istemcinin içinde
3 PANAMA Dosyanın en çok ilk 2 KB'ı Panama akış şifresiyle şifrelenir. Başlangıç vektörü sunucudan gelir
4 HYBRIDCRYPT Dosyaya göre Camellia, Twofish ya da XTEA ile şifrelenir. Anahtarlar sunucudan gelir
5 HYBRIDCRYPT_WITHSDB Tür 4'e ek olarak dosyanın bir parçası pakete konmaz. Eksik parça harita yüklenirken sunucudan gelir

1 ve 2 numaralı türlerde dosyayı açmak için gereken her şey istemcinin kendisinde bulunur. Bu türler veriyi gizlemekten çok paketi küçültmek ve sıradan düzenlemeyi zorlaştırmak içindir. 3, 4 ve 5 numaralı türler ise anahtarlarını oturum açılırken sunucudan alır; istemci tek başına çalıştırıldığında bu paketler açılamaz.

2 ve 3 numaralı türlerde istemci okuduğu verinin CRC32 değerini kayıttakiyle karşılaştırır. Paket bozulmuşsa dosya okunmaz ve oyun o dosyayı hiç yoktan sayar.

LZO sıkıştırılmış verinin başında da MCOZ imzalı 16 baytlık bir başlık vardır: imza, şifreli boy, sıkıştırılmış boy ve açılmış boy. İstemcinin item_proto ve mob_proto kopyaları da paketin içinde bu sarmalayıcıyla saklanır.

İstemci paket listesini nasıl okur?

Bu kaynakta paket listesi istemcinin C++ kodunun içine yazılıdır. Exe açılırken şu adları sırayla kaydeder, en sonda root paketini:

std::vector<std::string> packlist
{
	"bgm", "effect", "etc", "icon", "item", "locale", "maps",
	"monster", "npc", "pc", "pc2", "pc3", "property", "season",
	"sound", "textureset", "zone",
};
for (const auto& pack : packlist)
	CEterPackManager::Instance().RegisterPack((c_pszFolder + std::string("/") + pack).c_str(), "*");
CEterPackManager::Instance().RegisterRootPack((c_pszFolder + std::string("/") + std::string("root")).c_str());

c_pszFolder değeri pack olduğu için istemci pack/effect.eix ve pack/effect.epk gibi dosyaları arar. Listede olup klasörde bulunmayan paket (bu istemcide bgm ve season) sessizce atlanır; eksiklik ancak o paketteki bir dosya istendiğinde fark edilir.

Paketler "*" ile kaydedildiği için hepsinin dosya adları tek bir ortak sözlüğe girer. İstemci bir dosyayı ararken hangi pakette olduğuna bakmaz, yalnız yolunu bilir. Bu yüzden icon/item/00010.tga icon paketinde de, başka bir pakette de olsa bulunur.

Arama sırası derlemeye göre değişir. Yayın (Release) derlemesi önce paketlere, bulamazsa diske bakar. Hata ayıklama (Debug) derlemesi önce diske, sonra pakete bakar. Debug exe ile çalışırken bir dosyayı paketi yeniden oluşturmadan diskte değiştirip denemek bu yüzden mümkündür.

Aynı yol iki pakette varsa hangisinin döneceği kodda garanti edilmez. Tek istisna, sunucunun oturum açılırken kaydettirdiği paketlerdir: bunlar aynı yoldaki eski kaydın yerine geçer. Bir dosyayı güncellerken eski kopyasını başka pakette bırakmamak gerekir.

Python betikleri paketten nasıl okur?

Exe, Python'a pack.Exist ve pack.Get fonksiyonlarını verir. Bu kaynakta açık olan ENABLE_PACK_GET_CHECK bayrağı yüzünden pack.Get yalnız .py, .pyc ve .txt dosyalarını döndürür; uzantısız item_proto gibi dosyalar Python'dan okunamaz. root paketindeki system.py, Python'un open fonksiyonunu ve import komutunu pakete yönlendirir. Diskteki bir dosyayı okumak ya da yazmak gerektiğinde betiklerde old_open kullanılır.

Yeni bir pack nasıl eklenir?

İki yol var. Birincisi, yeni dosyaları var olan bir paketin içine koymaktır; istemci dosyayı yoluna göre bulduğu için hangi pakette durduğu fark etmez. Yeni bir harita da çoğu zaman maps, zone ve property paketlerine eklenen klasörlerle gelir; harita tarafının ayrıntısı harita ekleme yazısında.

İkincisi, yeni bir paket adı açmaktır. Bu kaynakta liste C++ kodunda olduğu için adı listeye ekleyip istemciyi yeniden derlemek gerekir. Derleme adımları Metin2 source derleme yazısında anlatılıyor. Yeni paketin dosyaları pack/<ad>.eix ve pack/<ad>.epk olarak konur.

makepackscript dosyası ne anlatır?

root paketinin içinde makepackscript_onlyrootnopython.txt adlı bir dosya duruyor. Bu, Ymir'in paketleme aracının (MakePack) okuduğu bir betiktir. Aracın kendisi kaynak paketinde yok; istemcinin paket kütüphanesinde yalnız onun izleri (paket yazma fonksiyonları ve paketleme günlüğü) var. Betiğin kısaltılmış hâli:

FolderName "pack"

List ExcludedFolderNameList
{
	"CVS"
}
List ExcludedFileNameList
{
	"syserr.txt"
	"log.txt"
	"loginInfo.py"
	"makepackscript.txt"
}
List SecurityExtNameList
{
	"txt"
	"msk"
	"msa"
	"msm"
	"py"
}
List CompressExtNameList
{
	"txt"
	"mss"
	"mse"
	"spt"
	"atr"
	"dds"
	"tga"
}

Group RootPackItemList
{
	Group ItemProto
	{
		FileName	"*item_proto"
		Fixed	TRUE
	}
	Group ModelFiles
	{
		FileName "*.msm"
		Fixed	TRUE
	}
}

Group PackList
{
	Group UIScript
	{
		PathName	"UIScript/*"
		Fixed		TRUE
	}
}

Asıl dosyada hariç tutulan dosya listesi daha uzundur ve CompressExtNameList ayrıca msk, msf, msa, raw, wtr, mde uzantılarını içerir; RootPackItemList'te mob_proto, TextureSet/*.txt, *.txt, *.tbl ve *.cvt kalıpları da vardır.

  • FolderName: Paketlerin yazılacağı klasör.
  • ExcludedFolderNameList, ExcludedFileNameList: Pakete girmeyecek klasör ve dosyalar. Günlükler ve geliştiricinin otomatik giriş dosyası (loginInfo.py) bilerek dışarıda bırakılmış.
  • SecurityExtNameList ve CompressExtNameList: Adları, istemcideki 2 numaralı (SECURITY) ve 1 numaralı (COMPRESS) türle örtüşüyor. Muhtemelen birinci listedeki uzantılar şifreli, ikincidekiler yalnız sıkıştırılmış olarak paketlenir; listelerde olmayan gr2, wav, jpg gibi uzantılar düz saklanır. txt, msk ve msa iki listede birden geçtiği için bunlara hangisinin uygulandığı aracın kendisine bağlıdır.
  • RootPackItemList: root paketine girecek dosya kalıpları (item_proto, mob_proto, metin dosyaları, .msm model betikleri).
  • PackList: Her grup ayrı bir paket tanımlar; burada UIScript klasörü.

Kaynakla gelen istemcinin pack klasöründe ayrıca EPack32 adlı, topluluk tarafından yazılmış bir paketleme aracı var. Onun da kaynak kodu pakette olmadığı için hangi türleri ürettiği burada anlatılmadı.

Sunucu tarafında paket anahtarları

3, 4 ve 5 numaralı türlerin anahtarları sunucunun share klasöründe tutulur ve istemciye auth girişi başarılı olduğu anda gönderilir:

  • panama/panama.lst: Her satırda bir paket yolu ve 32 baytlık başlangıç vektörü dosyasının adı. Sunucu açılışta bu dosyaları okur, giriş başarılı olunca her vektörü o oturuma özel bir değerle karıştırıp istemciye yollar. İstemci adı gelen paketi o anda kaydeder; bu paketlerin istemcinin sabit listesinde olması gerekmez ve aynı yoldaki eski dosyaların yerine geçerler.
  • package/ klasörü: 4 ve 5 numaralı türlerin anahtar ve ek parça (SDB) bilgileri. Anahtarlar giriş sırasında, ek parçalar ise karakter o paketle ilişkili bir haritaya girerken gönderilir.

Bu kaynakla gelen sunucu dosyalarında iki klasör de boş. Yani bu istemcinin paketleri sunucudan anahtar beklemiyor; 0, 1 ve 2 numaralı türlerle çalışıyor. Sunucunun bu adımı hangi bağlantıda yaptığı serverinfo.py ve bağlantı yazısında anlatılıyor.

Paketlemede sık yapılan hatalar

Belirti Olası neden
Yeni dosya oyunda görünmüyor Eski kopyası başka bir pakette duruyor ya da yol farklı yazılmış. Paket içindeki yol, kodun ve betiklerin istediği yolla birebir aynı olmalı.
syserr'de "Pack index file version error" eix dosyası başka bir araçla, farklı sürümde yazılmış.
Paket ekledim ama hiç okunmuyor Ad istemcinin listesinde yok; exe yeniden derlenmemiş.
Bazı dosyalar okunamıyor, diğerleri sorunsuz Dosya 2 ya da 3 numaralı türde ve veri CRC'si tutmuyor; paket bozulmuş ya da yarım kopyalanmış.
Müzik dosyası pakette ama çalmıyor Müzik paketten değil, diskteki BGM klasöründen akış olarak çalınır.

Dil dosyalarının paket içindeki yerleri ve biçimleri için istemci dil dosyaları yazısına bakılabilir.

Sık sorulan sorular

EIX ve EPK arasındaki fark nedir?
EIX paketin dizinidir: her dosyanın adı, boyutu, EPK içindeki konumu ve sıkıştırma türü burada yazar. EPK yalnız dosyaların verisini tutar. İkisi birlikte bir paket eder; biri eksikse paket açılmaz.
Yeni bir pack eklemek için exe'yi yeniden derlemek gerekir mi?
Bu kaynakta paket listesi C++ kodunun içinde yazılı olduğu için yeni bir paket adı eklemek exe'yi yeniden derlemeyi gerektirir. Dosyaları var olan bir pakete koymak ise yeterlidir, çünkü istemci dosyayı paket adına göre değil yoluna göre bulur.
Aynı dosya iki pakette olursa hangisi kullanılır?
Kodda bunun için bir sıra garanti edilmez. Sunucunun oturum açılırken kaydettirdiği paketler istisnadır, onlar aynı yoldaki eski kaydın yerine geçer. Karışıklık yaşamamak için aynı yolu iki pakete koymamak gerekir.

İlgili sayfalar

Kategori: Server Kurma Client (İstemci) istemci geliştirici pack epk eix

Bu sayfadaki bilgiler Metin2'nin sunucu yazılımındaki hesaplamalara ve standart oyun dosyalarına dayanır. Oyun dosyalarını değiştiren sunucularda değerler farklı olabilir. İçerikleri nasıl hazırlıyoruz?

Bu sayfa işine yaradı mı?

Giriş yap, oy ver ya da sayfayı kaydet. Okumak için üyelik gerekmez. WhatsApp X'te paylaş
Yanlış ya da eksik bir bilgi mi gördün? Bildir
Neyin yanlış olduğunu, doğrusunun ne olduğunu ve bunu nereden bildiğini yaz. Mesajın editörlere gider; yazı, kontrol edildikten sonra düzeltilir.
Yalnız editör görür.

Tartışma

Kurallar

Henüz yorum yok. Bu konuda bir deneyimin ya da sorun varsa ilk yorumu sen yaz.

Giriş yap ya da kayıt ol, sonra yorum yaz. Metin2VIP üyeliği hiçbir oyun sunucusunun hesabı değildir.