3DÄêÀ©½÷нÃæʸ»ñÎÁ [°ì»þ¸ø³«]

¡Ê暂̤´°À®¡¤¸¦µæÅÓÃæ¡Ë

CM3D2µÚCOM3D2对应Èó²ÃÌ©arc³Ê¼°Ê¬ÀÏ

Ãí°Õ¡§KISSŪarcʬ²ÃÌ©ÏÂÈó²ÃÌ©
²Ã̩Ū¼ûÍ×运¹Ô°ì¼¡Þâ戏进¹Ô²òÌ©
Í­º³*_2.arcÚÛË¡²òÌ©À§°ø为åþ¾¯DLC

¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö

77 61 72 63
4byte¡¤warc

FF AA 45 F1
4byte¡¤Ì¤ÃÎ

E8 03 00 00
4byte¡¤ÈÇËÜ1000

04 00 00 00
4byte¡¤Ì¤ÃÎ

02 00 00 00
4byte¡¤Ì¤ÃΡ¤°Ê¾åÀ§ArcHeader

¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö

xx xx 00 00 00 00 00 00
8byte ¿ô¿ø块总长ÅÙ¡©²¼ÌÌŪ¶è块 [UInt64]

============================
01 00 00 00
4byte¡¤É½¼¨压缩 [Bool]

00 00 00 00
4byte¡¤Junk Data?

xx xx 00 00
4byte ʸ·ï¿ô¿ø长ÅÙ¡¤¸¶»Ï [UInt32]

xx xx 00 00
4byte ʸ·ï¿ô¿ø长ÅÙ¡¤ÅöÁ° [UInt32]¡ÊÇ¡²Ì¿ô¿øË×进¹Ô压缩½¢Ï¸¶»ÏŪ°ì样¡Ë

xx xx ... xx xx
ʸ·ï¿ô¿ø¡¤Ç¡²ÌÀ§压缩Ū¿ô¿ø¡¤Ç·Á°²ñùá²Ã两Ф»ú节78 5E (ºß长ÅÙ统计Æâ)
Ãí°Õ*.ks *.menu *.tjs这»°种³Ê¼°¿ô¿øºÍ²ñ进¹ÔDeflate»»Ë¡压缩

============================

============================

00 00 00 00
4byte¡¤blockType;0 utf16HashData;1 utf8HashData;3 utf16NameData

xx 00 00 00 00 00 00 00
8byte¡¤blockSize [UInt64]

¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö
blockType = 0 or 1 Ū¾ðÑ×

¡ö=¡ö=¡ö=¡ö=¡ö
¡ÊÇ¡²Ìº¡¶è块½Ð现递归¡¤Ðº²¼ÌÌÍ­开»Ï处Íý¡Ë

20 00 00 00 10 00 00 00
8byte¡¤DirHeader

xx xx xx xx xx xx xx xx
8byte¡¤UniqueID¡¤Â¶实½¢À§8»ú节Hash值
这ФUniqueID¼ûÍ×结¹ç¹¡Ì̽Ð现ŪNameTableÆÀÅþ°ìФ½Ú确Ū»úÉä¶ú
这Ф»úÉä¶úɽ¼¨Ê¸·ï̾°¿Ê¸·ï夹̾

xx xx xx xx
4byte¡¤Dirs [Int32]
ɽ¼¨ÅöÁ°»úÉä¶ú·Á¼°ÅªÏ©·Â²¼Åª»Òʸ·ï夹¿ôÎÌ

xx xx xx xx
4byte¡¤Files [Int32]
ɽ¼¨ÅöÁ°»úÉä¶ú·Á¼°ÅªÏ©·Â²¼ÅªÊ¸·ï¿ôÎÌ

xx xx xx xx
4byte¡¤Depth [Int32]
ɽ¼¨ÅöÁ°»úÉä¶ú·Á¼°ÅªÏ©·Â½ê处ŪÌÜ录¿¼ÅÙ
Arcɬ须°Êʸ·ï夹Ū·Á¼°ÂÇÊñ¡¤°øº¡ÂÇÊñÌÜ录Ū¿¼ÅÙ为0

xx xx xx xx
4byte¡¤Ì¤ÃÎ

¡ö=¡ö=¡ö=¡ö=¡ö

for Dirs=>(к1开»Ï)
xx xx xx xx xx xx xx xx
8byte¡¤Hash¡ÊUniqueID¡Ë

xx xx xx xx xx xx xx xx
8byte¡¤offset [Int64]
ÊÐ°Ü = 32 + 16 * (Dirs + Files) + 8 * Depth
这Ф值ÁêÅöвÀ§¾åФDirHeaderŪµ¯»Ï°ÌÃÖÅþ²¼Ð¤DirHeader(开»ÏÁ°)Ū总ÎÌ
º¡处读´°¹¡Åª°ÌÃÖÅþÇ·Á°ÅªDirHeaderŪµ¯»Ï°ÌÃÖ¶¦32byte+16byte
°ø为»ê¾¯Í­Dirs=1(¶¾两Ф²Ä°ÊÀ§0)ºÍÍ­这Ф¿ô¿ø¡¤½ê°Ê这Ф值ºÇ¾¯ÌéÀ§48
为λ²Ã®检º÷¡¤Åö读´°这Ф值¹¡¡¤²Ä°ÊÍÑ这Ф值-40ŪÊаÜÎ̿׮Äê°ÌÅþ²¼Ð¤

¡ö=¡ö=¡ö=¡ö=¡ö

for Files=>(к1开»Ï)
xx xx xx xx xx xx xx xx
8byte¡¤Hash¡ÊUniqueID¡Ë

xx xx xx xx xx xx xx xx
8byte¡¤offset [Int64]
ÊаÜ值¡¤»Øʸ·ï¿ô¿øºßÇ·Á°À°Ð¤¿ô¿ø块Ū°ÌÃÖ
½é»Ï值为0¡¤²¼Ð¤Ê¸·ï则ÊаÜÁ°°ìФʸ·ïŪ¿ô¿ø长ÅÙ+16byte
â这Ф值ÖõÉÔÀ§ÅöÁ°Ê¸·ïŪ»Ø针°ÌÃÖ
读ʸ·ï时还Í×»»¾åArcHeaderµÚ¿ô¿ø块长Åٻؼ¨Åª8byte¡¤¹ç计28byte

¡ö=¡ö=¡ö=¡ö=¡ö

for Depth=>(к1开»Ï)
xx xx xx xx xx xx xx xx
8byte¡¤Parents UniqueID¡ÊÉã级ŪUniqueID¡Ë

¡ö=¡ö=¡ö=¡ö=¡ö

for Dirs=>(к1开»Ï)
20 00 00 00 10 00 00 00
Sub DirHeader...¡Ê进Æþ递归¡¤Ä¾ÅþË×Í­为»ß¡Ë

Ç¡²ÌÍ­¡¤½Å复进¹Ô创·ú»Ò项=>递归
这Τ开头Ū8byteÀ§»Ò项Ū头Éô
°ÌÃÖƱÁ°ÌÌDirHeader½ê处ÃÏÊý
¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö

¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö
blockType = 3 Ū¾ðÑ×

¡ö=¡ö=¡ö=¡ö=¡ö
01 00 00 00
4byte¡¤É½¼¨压缩 [Bool]

00 00 00 00
4byte¡¤Junk Data?

xx xx xx xx
4byte¡¤RawSize [UInt32]

xx xx xx xx
4byte¡¤DealSize [UInt32]

xx xx ... xx xx
NameListdata¡¤压缩ŪÊý¼°Æ±Á°ÌÌÄóÅþŪDeflate»»Ë¡
¡ö=¡ö=¡ö=¡ö=¡ö

=>²ò压´°À®Åª¿ô¿ø结构
¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á
xx xx xx xx xx xx xx xx
8byte¡¤Hash¡¤¸¶Íý½¢À§É¤ÇÛ这ФHash¡¤对应²¼ÌÌŪ¶ñÂλúÉä¶ú

xx xx xx xx
4byte¡¤Size [Int32]

xx 00 xx 00 ... xx 00 xx 00
Unicode»úÉä¶ú¡¤Í³Ð²UTF16编码Ū关·Ï¡¤实际Ū»ú节长ÅÙÀ§Size值Ū两ÇÜ

loop½Û环¡¤Ä¾Åþ结«
¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á¡á

Ãí°Õ¡¤°ø为这ФÀ§NameTable¡¤Æ±°ìФHashÂþǽ对应°ìФ»úÉä¶ú
另³°¡¤NameTableŪÂè°ì项ÅöÐöº¬ÌÜ录(root)¡¤值À§这ФarcºßÉõÊñ时Ūʸ·ï夹Ū´°À°Ï©·Â

¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö¡ö


UniqueIDŪ计»»ÊýË¡¡¤Ç¡²¼¡§

Function GetHash(ByVal data() As Byte) As ULong

'²Ã载种»ÒÏÂ键
SeedA = &H84222325UI
SeedB = &HCBF29CE4UI
KeyA = &H100UI
KeyB = &H1B3UI

'创·ú临时种»Ò
Dim tmpSeedA As UInteger
Dim tmpSeedB As UInteger

'创·úULong, ÈòÌÈUInt32Ū计»»结²Ì°î½Ð
Dim tmp64 As ULong
'创·úByte, ÍÑв٣ÃÇULong»ê·óÍÆUInt32
Dim buff As Byte()

For i As Long = 0 To data.LongLength - 1

'种»Ò1Í¿输Æþbyte进¹ÔXor运»»
SeedA = SeedA Xor data(i)

'ºß临时种»Ò²Ã载ÅöÁ°Åª种»Ò
tmpSeedA = SeedA
tmpSeedB = SeedB

'临时种»Ò1Í¿键1ÁêЫÖõÊÖ还临时种»Ò1
tmp64 = CULng(tmpSeedA)
buff = BitConverter.GetBytes(tmp64 * KeyA)
tmpSeedA = BitConverter.ToUInt32(buff, 0)

'临时种»Ò2Í¿键2ÁêЫÖõÊÖ还临时种»Ò2
tmp64 = CULng(tmpSeedB)
buff = BitConverter.GetBytes(tmp64 * KeyB)
tmpSeedB = BitConverter.ToUInt32(buff, 0)

'种»Ò2À¶Îí
SeedB = 0

'种»Ò1Í¿种»Ò2组¹çÀ®QWord¹¡Í¿键2ÁêЫ¡¤»ÈÍÑDecimalÈòÌÈULong计»»结²Ì°î½Ð
Dim dec As Decimal = CULng(SeedB) * &H100000000UL + CULng(SeedA) * CULng(KeyB)
tmp64 = (dec / &H100000000UL / &H100000000UL Mod 1) * &H100000000UL * &H100000000UL
buff = BitConverter.GetBytes(tmp64)
SeedA = BitConverter.ToUInt32(buff, 0)
SeedB = BitConverter.ToUInt32(buff, 4)

'种»Ò2Í¿临时种»Ò1Áê²ÃÖõÊÖ²ó种»Ò2
tmp64 = CULng(SeedB) + CULng(tmpSeedA)
buff = BitConverter.GetBytes(tmp64)
SeedB = BitConverter.ToUInt32(buff, 0)

'种»Ò2Í¿临时种»Ò2Áê²ÃÖõÊÖ²ó种»Ò2
tmp64 = CULng(SeedB) + CULng(tmpSeedB)
buff = BitConverter.GetBytes(tmp64)
SeedB = BitConverter.ToUInt32(buff, 0)

Next

'½êÍ­输Æþbyte½Û环´°À®, 种»Ò1Í¿种»Ò2进¹ÔXor运»»
SeedA = SeedA Xor SeedB

'种»Ò1Í¿种»Ò2组¹çÀ®QWordÆÀÅþULong·¿ÅªÊÖ²ó值
Dim ret As ULong = CULng(SeedB) * &H100000000UL + CULng(SeedA)

Return ret

End Function

¥³¥á¥ó¥È¤ò¤«¤¯


¡Öhttp://¡×¤ò´Þ¤àÅê¹Æ¤Ï¶Ø»ß¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

ÍøÍѵ¬Ìó¤ò¤´³Îǧ¤Î¤¦¤¨¤´µ­Æþ²¼¤µ¤¤

¥á¥ó¥Ð¡¼¤Î¤ßÊÔ½¸¤Ç¤­¤Þ¤¹