Initial PoC commit
This commit is contained in:
commit
2e7f4bb4f5
|
@ -0,0 +1,234 @@
|
|||
"""
|
||||
#define FT_FILENAME 0x01 // <string>
|
||||
#define FT_FILESIZE 0x02 // <uint32> (or <uint64> when supported)
|
||||
#define FT_FILESIZE_HI 0x3A // <uint32>
|
||||
#define FT_FILETYPE 0x03 // <string>
|
||||
#define FT_FILEFORMAT 0x04 // <string>
|
||||
#define FT_LASTSEENCOMPLETE 0x05 // <uint32>
|
||||
#define TAG_PART_PATH "\x06" // <string>
|
||||
#define TAG_PART_HASH "\x07"
|
||||
#define FT_TRANSFERRED 0x08 // <uint32>
|
||||
#define TAG_TRANSFERRED "\x08" // <uint32>
|
||||
#define FT_GAPSTART 0x09 // <uint32>
|
||||
#define TAG_GAPSTART "\x09" // <uint32>
|
||||
#define FT_GAPEND 0x0A // <uint32>
|
||||
#define TAG_GAPEND "\x0A" // <uint32>
|
||||
#define FT_DESCRIPTION 0x0B // <string>
|
||||
#define TAG_DESCRIPTION "\x0B" // <string>
|
||||
#define TAG_PING "\x0C"
|
||||
#define TAG_FAIL "\x0D"
|
||||
#define TAG_PREFERENCE "\x0E"
|
||||
#define FT_PARTFILENAME 0x12 // <string>
|
||||
//#define FT_PRIORITY 0x13 // Not used anymore
|
||||
#define FT_STATUS 0x14 // <uint32>
|
||||
#define FT_SOURCES 0x15 // <uint32>
|
||||
#define FT_PERMISSIONS 0x16 // <uint32>
|
||||
//#define FT_ULPRIORITY 0x17 // Not used anymore
|
||||
#define FT_DLPRIORITY 0x18 // Was 13
|
||||
#define FT_ULPRIORITY 0x19 // Was 17
|
||||
#define FT_COMPRESSION 0x1A
|
||||
#define FT_CORRUPTED 0x1B
|
||||
#define FT_KADLASTPUBLISHKEY 0x20 // <uint32>
|
||||
#define FT_KADLASTPUBLISHSRC 0x21 // <uint32>
|
||||
#define FT_FLAGS 0x22 // <uint32>
|
||||
#define FT_DL_ACTIVE_TIME 0x23 // <uint32>
|
||||
#define FT_CORRUPTEDPARTS 0x24 // <string>
|
||||
#define FT_DL_PREVIEW 0x25
|
||||
#define FT_KADLASTPUBLISHNOTES 0x26 // <uint32>
|
||||
#define FT_AICH_HASH 0x27
|
||||
#define FT_FILEHASH 0x28
|
||||
#define FT_COMPLETE_SOURCES 0x30 // nr. of sources which share a complete version of the associated file (supported by eserver 16.46+)
|
||||
#define FT_COLLECTIONAUTHOR 0x31
|
||||
#define FT_COLLECTIONAUTHORKEY 0x32
|
||||
#define FT_PUBLISHINFO 0x33 // <uint32>
|
||||
#define FT_LASTSHARED 0x34 // <uint32>
|
||||
#define FT_AICHHASHSET 0x35 // <uint32>
|
||||
#define TAG_KADAICHHASHPUB "\x36" // <AICH Hash>
|
||||
|
||||
// statistic
|
||||
#define FT_ATTRANSFERRED 0x50 // <uint32>
|
||||
#define FT_ATREQUESTED 0x51 // <uint32>
|
||||
#define FT_ATACCEPTED 0x52 // <uint32>
|
||||
#define FT_CATEGORY 0x53 // <uint32>
|
||||
#define FT_ATTRANSFERREDHI 0x54 // <uint32>
|
||||
#define FT_MAXSOURCES 0x55 // <uint32>
|
||||
#define FT_MEDIA_ARTIST 0xD0 // <string>
|
||||
#define TAG_MEDIA_ARTIST "\xD0" // <string>
|
||||
#define FT_MEDIA_ALBUM 0xD1 // <string>
|
||||
#define TAG_MEDIA_ALBUM "\xD1" // <string>
|
||||
#define FT_MEDIA_TITLE 0xD2 // <string>
|
||||
#define TAG_MEDIA_TITLE "\xD2" // <string>
|
||||
#define FT_MEDIA_LENGTH 0xD3 // <uint32> !!!
|
||||
#define TAG_MEDIA_LENGTH "\xD3" // <uint32> !!!
|
||||
#define FT_MEDIA_BITRATE 0xD4 // <uint32>
|
||||
#define TAG_MEDIA_BITRATE "\xD4" // <uint32>
|
||||
#define FT_MEDIA_CODEC 0xD5 // <string>
|
||||
#define TAG_MEDIA_CODEC "\xD5" // <string>
|
||||
#define FT_FILECOMMENT 0xF6 // <string>
|
||||
#define FT_FILERATING 0xF7 // <uint8>
|
||||
"""
|
||||
|
||||
import binascii
|
||||
|
||||
|
||||
HEADER_MET_FILE = b'\x0e'
|
||||
|
||||
FT_FILENAME = 0x01
|
||||
FT_FILESIZE = 0x02
|
||||
FT_PARTFILENAME = 0x12
|
||||
FT_PERMISSIONS = 0x16
|
||||
FT_ULPRIORITY = 0x19
|
||||
|
||||
FT_KADLASTPUBLISHKEY = 0x20
|
||||
FT_KADLASTPUBLISHSRC = 0x21
|
||||
FT_FLAGS = 0x22
|
||||
FT_KADLASTPUBLISHNOTES = 0x26
|
||||
FT_AICH_HASH = 0x27
|
||||
|
||||
FT_LASTSHARED = 0x34
|
||||
FT_AICHHASHSET = 0x35
|
||||
|
||||
FT_ATTRANSFERRED = 0x50
|
||||
FT_ATREQUESTED = 0x51
|
||||
FT_ATACCEPTED = 0x52
|
||||
FT_ATTRANSFERREDHI = 0x54
|
||||
|
||||
FT_MEDIA_ARTIST = 0xd0
|
||||
FT_MEDIA_ALBUM = 0xd1
|
||||
FT_MEDIA_TITLE = 0xd2
|
||||
FT_MEDIA_LENGTH = 0xd3
|
||||
FT_MEDIA_BITRATE = 0xd4
|
||||
FT_MEDIA_CODEC = 0xd5
|
||||
|
||||
FT_STRING = (
|
||||
0x03, 0x04, 0x06, 0x0b, 0x11, 0x24, 0x28, 0xf6
|
||||
)
|
||||
|
||||
FT_INT = (
|
||||
0x05, 0x08, 0x09, 0x0a, 0x14, 0x15, 0x18, 0x1a, 0x1b, 0x23, 0x25, 0x30, 0x33, 0x53, 0x55, 0xf7
|
||||
)
|
||||
|
||||
def met_readstring(fd):
|
||||
string_len = int.from_bytes(fd.read(2), byteorder='little')
|
||||
return fd.read(string_len).decode('utf-8', errors='replace')
|
||||
|
||||
|
||||
def met_readinteger(fd, size=4):
|
||||
return int.from_bytes(fd.read(size), byteorder='little')
|
||||
|
||||
|
||||
def record_last_changed(fd):
|
||||
return met_readinteger(fd)
|
||||
|
||||
|
||||
def record_read_hash16(fd):
|
||||
aichash = fd.read(16)
|
||||
return binascii.hexlify(aichash).decode('utf-8')
|
||||
|
||||
|
||||
def record_tags(fd):
|
||||
tagcount = met_readinteger(fd)
|
||||
print('Tags: {}'.format(tagcount))
|
||||
for index in range(tagcount):
|
||||
filetag = fd.read(4)
|
||||
if filetag[:3] not in [b'\x02\x01\x00', b'\x03\x01\x00']:
|
||||
print('<<< Premature end of record at offset 0x{:08X}'.format(fd.tell()))
|
||||
return True
|
||||
tagid = filetag[-1]
|
||||
if tagid == FT_FILENAME:
|
||||
filename = met_readstring(fd)
|
||||
print('Filename: {}'.format(filename))
|
||||
elif tagid == FT_FILESIZE:
|
||||
filesize = met_readinteger(fd)
|
||||
print('Filesize: {}'.format(filesize))
|
||||
elif tagid == FT_ATTRANSFERRED:
|
||||
print('Transfered: {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_ATREQUESTED:
|
||||
print('Requested: {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_ATACCEPTED:
|
||||
print('Accepted: {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_ATTRANSFERREDHI:
|
||||
print('Transfered (HI): {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_ULPRIORITY:
|
||||
print('FT_ULPRIORITY')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_KADLASTPUBLISHSRC:
|
||||
print('FT_KADLASTPUBLISHSRC')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_KADLASTPUBLISHNOTES:
|
||||
print('FT_KADLASTPUBLISHNOTES')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_FLAGS:
|
||||
print('FT_FLAGS')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_PERMISSIONS:
|
||||
print('FT_PERMISSIONS')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_KADLASTPUBLISHKEY:
|
||||
print('FT_KADLASTPUBLISHKEY')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_AICH_HASH:
|
||||
print('AIC Hash: {}'.format(met_readstring(fd)))
|
||||
elif tagid == FT_LASTSHARED:
|
||||
print('FT_LASTSHARED')
|
||||
met_readinteger(fd)
|
||||
elif tagid == FT_AICHHASHSET:
|
||||
print('FT_AICHHASHSET')
|
||||
aichashcount = met_readinteger(fd, 1)
|
||||
elif tagid == FT_PARTFILENAME:
|
||||
print('Part filename: {}'.format(met_readstring(fd)))
|
||||
elif tagid == FT_MEDIA_LENGTH:
|
||||
print('Media Length: {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_MEDIA_CODEC:
|
||||
print('Media Codec: {}'.format(met_readstring(fd)))
|
||||
elif tagid == FT_MEDIA_BITRATE:
|
||||
print('Media Bitrate: {}'.format(met_readinteger(fd)))
|
||||
elif tagid == FT_MEDIA_TITLE:
|
||||
print('Media Title: {}'.format(met_readstring(fd)))
|
||||
elif tagid == FT_MEDIA_ARTIST:
|
||||
print('Media Artist: {}'.format(met_readstring(fd)))
|
||||
elif tagid == FT_MEDIA_ALBUM:
|
||||
print('Media Album: {}'.format(met_readstring(fd)))
|
||||
elif tagid in FT_STRING:
|
||||
print('... Reading data with tag: {}'.format(tagid))
|
||||
met_readstring(fd)
|
||||
elif tagid in FT_INT:
|
||||
print('... Reading data with tag: {}'.format(tagid))
|
||||
met_readstring(fd)
|
||||
return True
|
||||
|
||||
|
||||
def record_num_parts(fd):
|
||||
return met_readinteger(fd, 2)
|
||||
|
||||
|
||||
def load_record(fd):
|
||||
last_changed = record_last_changed(fd)
|
||||
aichash = record_read_hash16(fd)
|
||||
partshashes = []
|
||||
for i in range(record_num_parts(fd)):
|
||||
partshashes.append(record_read_hash16(fd))
|
||||
record_tags(fd)
|
||||
|
||||
print('Last changed: {}'.format(last_changed))
|
||||
print('ED2K Hash: {}'.format(aichash))
|
||||
print('Num Parts: {}'.format(len(partshashes)))
|
||||
print('Parts Hashes: {}'.format(partshashes))
|
||||
|
||||
|
||||
def load_knownfiles(filename):
|
||||
with open(filename, 'rb') as fd:
|
||||
magic = fd.read(1)
|
||||
count = int.from_bytes(fd.read(4), byteorder='little')
|
||||
print('Number of records: {}'.format(count))
|
||||
if magic == HEADER_MET_FILE:
|
||||
for index in range(count):
|
||||
print('>>> [{}] NEW RECORD ***'.format(index+1))
|
||||
print('Record offset: {}'.format(fd.tell()))
|
||||
load_record(fd)
|
||||
|
||||
print('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
load_knownfiles('.\\data\\known.met')
|
Loading…
Reference in New Issue