1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120:
| type TeDonkeyHeader = packed record Version: Byte; NumOfServers: LongWord; end;
TeDonkeyServer = packed record IP: Array[0..3] of Byte; Port: Word; NumOfMetaTags: LongWord; end;
TeDonkeyMetaTagHeader = packed record TagType: Byte; NameLength: Word; NameValue: String; end;
TeDonkeyMetaTag2 = packed record ValueLength: Word; Value: String; end;
TeDonkeyMetaTag3 = packed record Value: LongWord; end;
const TeDonkeyMetaTagSpecial: Array[0..21] of String = ('unknown', // 0x00 'Name', // 0x01 String 'Size', // 0x02 'MediaType', // 0x03 String (Audio, Video, Image, Pro, Doc, Col) 'Format', // 0x04 String (file extension) 'unknown', // 0x05 'unknown', // 0x06 'unknown', // 0x07 'Copied', // 0x08 'GapStart', // 0x09 Data keeps number of gap as string 'GapEnd', // 0x0A Data keeps number of gap as string 'Description', // 0x0B String 'Ping', // 0x0C 'Fail', // 0x0D 'Preference', // 0x0E 'Port', // 0x0F 'IP', // 0x10 'Version', // 0x11 'TempFile', // 0x12 String 'Priority', // 0x13 'Status', // 0x14 'Availability' // 0x15 ); TeDonkeyPreference: Array[0..2] of String = ('Normal', 'High', 'Low');
procedure TForm1.Button1Click(Sender: TObject); var ServMet: TFileStream; eDonkeyHeader: TeDonkeyHeader; eDonkeyServer: TeDonkeyServer; eDonkeyMetaTagHeader: TeDonkeyMetaTagHeader; eDonkeyMetaTag2: TeDonkeyMetaTag2; eDonkeyMetaTag3: TeDonkeyMetaTag3; iNumOfServers: Integer; iNumOfMetaTags: Integer; iSpecialTag: Byte; begin if OpenDialog.Execute then begin ServMet := TFileStream.Create(OpenDialog.FileName, fmOpenRead); try ServMet.Seek(0, soFromBeginning); ServMet.Read(eDonkeyHeader, SizeOf(eDonkeyHeader)); ShowMessage('Version: ' + IntToStr(eDonkeyHeader.Version) + ' entspricht: $' + IntToHex(eDonkeyHeader.Version, 2)); ShowMessage('Number Of Servers: ' + IntToStr(eDonkeyHeader.NumOfServers)); for iNumOfServers := 1 to eDonkeyHeader.NumOfServers do begin ServMet.Read(eDonkeyServer, SizeOf(eDonkeyServer)); ShowMessage('IP: ' + IntToStr(eDonkeyServer.IP[0]) + '.' + IntToStr(eDonkeyServer.IP[1]) + '.' + IntToStr(eDonkeyServer.IP[2]) + '.' + IntToStr(eDonkeyServer.IP[3])); ShowMessage('Port: ' + IntToStr(eDonkeyServer.Port)); for iNumOfMetaTags := 1 to eDonkeyServer.NumOfMetaTags do begin ServMet.Read(eDonkeyMetaTagHeader, SizeOf(Byte) + SizeOf(Word)); if eDonkeyMetaTagHeader.NameLength = 1 then // special tag begin ServMet.Read(iSpecialTag, SizeOf(iSpecialTag)); eDonkeyMetaTagHeader.NameValue := TeDonkeyMetaTagSpecial[iSpecialTag]; end else // string begin SetLength(eDonkeyMetaTagHeader.NameValue, eDonkeyMetaTagHeader.NameLength); ServMet.Read(eDonkeyMetaTagHeader.NameValue[1], eDonkeyMetaTagHeader.NameLength); end; // tag type 2 if (eDonkeyMetaTagHeader.TagType = 2) then begin ServMet.Read(eDonkeyMetaTag2, SizeOf(Word)); SetLength(eDonkeyMetaTag2.Value, eDonkeyMetaTag2.ValueLength); ServMet.Read(eDonkeyMetaTag2.Value[1], eDonkeyMetaTag2.ValueLength); ShowMessage(eDonkeyMetaTagHeader.NameValue + ': ' + eDonkeyMetaTag2.Value); end else // tag type 3 begin ServMet.Read(eDonkeyMetaTag3, SizeOf(eDonkeyMetaTag3)); if eDonkeyMetaTagHeader.NameValue = 'Preference' then begin ShowMessage(eDonkeyMetaTagHeader.NameValue + ': ' + TeDonkeyPreference[eDonkeyMetaTag3.Value]); end else begin ShowMessage(eDonkeyMetaTagHeader.NameValue + ': ' + IntToStr(eDonkeyMetaTag3.Value)); end; end; end; end; // EOF, if there's not a tail (28 unhandled bytes) finally ServMet.Free; end; end; end; |