⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unttqqwry.pas

📁 原版翎风(LF)引擎(M2)源码(Delphi)
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit untTQQWry;

interface

uses
  Windows, SysUtils, Classes, StrUtils, Controls, Math;

const  //用于内存文件映射标志
  QQWryMapFileTag = 'QQWryMapFile';

type
  TQQWry = class(TObject)
    public
      constructor Create(AQQWryFileName: string);
      destructor Destroy; override;
      function GetQQWryFileName: string;
      function GetQQWryFileSize: int64;
      function GetIPDataNum: int64;
      function GetQQWryDate: TDate;
      function GetQQWryDataFrom: string;

      procedure GetIPDataByIPRecordID(IPRecordID: int64; var IPData: PChar); overload;
      procedure GetIPLocationByEndIPOffset(EndIPOffset: int64; var IPLocation: PChar);
      procedure GetIPDataByIPRecordID(IPRecordID: int64; var IPData: TStringlist); overload;
      function GetIPValue(IP: string): int64;
      function GetIPDataID(IP: string): int64;
      function ExtractIPDataToTxtFile(ATxtFileName: string): integer;
    private
      QQWryFileName: string;
      QQWryFileSize: int64;
      IPDataNum: int64;
      FirstIPIndexOffset, LastIPIndexOffset: integer;

      hQQWryFile, hQQWryMapFile: THandle;
      pQQWryMapFile: Pointer;
      pQQWryPos: PByte;
      function GetFileSize(AFileName: string): int64;
  end;

implementation

///**
//* 获取文件大小
//* @param  (AFileName) (文件全名)
//* @return (文件大小)
//*/
function TQQWry.GetFileSize(AFileName: string): int64;
var
  FileStream: TFileStream;
begin
  try
    FileStream:=TFileStream.Create(AFileName, fmOpenRead);
  except
    raise Exception.Create(format('文件 %s 无法打开!', [AFileName]));
    exit;
  end;
  result:=FileStream.Size;
  FileStream.Free;
end;

///**
//* 构造函数,构造一个TQQWry即纯真IP数据库处理对象
//* @param (AQQWryFileName) (纯真IP数据库文件的全文件名)
//* @return 无
//*/
constructor TQQWry.Create(AQQWryFileName: string);
var
  Buffer: TOFStruct;
begin
  inherited Create;
  try
    QQWryFileName:='QQWry.Dat';
    //测文件存在
    if not FileExists(QQWryFileName) then
      raise Exception.Create(format('文件 %s 不存在!', [QQWryFileName]));

    //测文件大小
    QQWryFileSize:=GetFileSize(QQWryFileName);
    if QQWryFileSize=0 then
      raise Exception.Create(format('文件 %s 大小为空!', [QQWryFileName]));

    //打开文件句柄
    hQQWryFile:=OpenFile(PChar(QQWryFileName),
                         Buffer,
                         OF_READWRITE);
    if hQQWryFile=-1 then
      raise Exception.Create(format('文件 %s 不能打开!', [QQWryFileName]));

    //创建文件映像对象      
    hQQWryMapFile:=CreateFileMapping(hQQWryFile,
                                     nil,
                                     PAGE_READWRITE,
                                     0,
                                     QQWryFileSize,
                                     PChar(QQWryMapFileTag));
    if hQQWryMapFile=0 then begin
      CloseHandle(hQQWryFile);
      raise Exception.Create('不能创建内存映象文件!');
    end;

    //获取映象文件映射地址
    pQQWryMapFile:=MapViewOfFile(hQQWryMapFile,
                                 FILE_MAP_ALL_ACCESS,
                                 0,
                                 0,
                                 0);
    if pQQWryMapFile=nil then begin
      CloseHandle(hQQWryFile);
      CloseHandle(hQQWryMapFile);
      raise Exception.Create('不能获取文件映射地址!');
    end;

    pQQWryPos:=pQQWryMapFile;
    FirstIPIndexOffset:=PInteger(pQQWryPos)^;
    Inc(pQQWryPos, 4);
    LastIPIndexOffset:=PInteger(pQQWryPos)^;
    IPDataNum:=(LastIPIndexOffset - FirstIPIndexOffset) div 7 + 1;
  except
    on E: Exception do begin
      raise Exception.Create(E.Message);
      exit;
    end;
  end;
end;

///**
//* 析构函数 (释放TQQWry对象,关闭文件映射,关闭文件映像对象句柄,关闭文件句柄)
//* @param  无
//* @return 无
//*/
destructor TQQWry.Destroy;
begin
  if pQQWryMapFile<>nil then UnMapViewOfFile(pQQWryMapFile);  //关闭文件映射
  if hQQWryMapFile<>0 then CloseHandle(hQQWryMapFile);        //关闭文件映像对象句柄
  if hQQWryFile<>0 then CloseHandle(hQQWryFile);              //关闭文件句柄
  inherited Destroy;
end;

///**
//* 获取纯真IP数据库文件的全文件名
//* @param  无
//* @return (纯真IP数据库文件的全文件名)
//*/
function TQQWry.GetQQWryFileName: string;
begin
  Result:=QQWryFileName;
end;

///**
//* 获取纯真IP数据库文件大小
//* @param  无
//* @return (纯真IP数据库文件大小)
//*/
function TQQWry.GetQQWryFileSize: int64;
begin
  Result:=QQWryFileSize;
end;

///**
//* 获取纯真IP数据库内含有的IP地址信息记录数
//* @param  无
//* @return (纯真IP数据库记录数)
//*/
function TQQWry.GetIPDataNum: int64;
begin
  Result:=IPDataNum;
end;

///**
//* 获取当前QQIP数据库的更新日期
//* @param  无
//* @return QQIP当前数据库的更新日期  TDate
//*/
function TQQWry.GetQQWryDate: TDate;
var
  DateString: string;
  IPData: TStringlist;
begin
  IPData:=TStringlist.Create;
  GetIPDataByIPRecordID(GetIPDataNum, IPData);
  DateString:=IPData[3];
  IPData.Free;
  
  DateString:=copy(DateString, 1, pos('IP数据', DateString) - 1);
  DateString:=StringReplace(DateString, '年', '-', [rfReplaceAll, rfIgnoreCase]);
  DateString:=StringReplace(DateString, '月', '-', [rfReplaceAll, rfIgnoreCase]);
  DateString:=StringReplace(DateString, '日', '-', [rfReplaceAll, rfIgnoreCase]);
  Result:=StrToDate(DateString);
end;

///**
//* 获取当前QQIP数据库的来源信息
//* @param  无
//* @return 当前QQIP数据库的来源信息  string
//*/
function TQQWry.GetQQWryDataFrom: string;
var
  FromString: string;
  IPData: TStringlist;
begin
  IPData:=TStringlist.Create;
  GetIPDataByIPRecordID(GetIPDataNum, IPData);
  FromString:=IPData[2];
  IPData.Free;
  Result:=FromString;
end;

///**
//* 给定一个IP地址信息记录号,返回该项记录的信息
//* @param  (IPRecordID, IPData) (IP地址信息记录号, 返回的该条信息:①起始IP 15字节 ②结束IP 15字节 ③国家 ④地区 ⑤回车键2字节)
//* @return 无
//*/
procedure TQQWry.GetIPDataByIPRecordID(IPRecordID: int64; var IPData: PChar);
var
  EndIPOffset: integer;
  i: integer;
  
  pBlank, pReturn: PChar;
  
  IPByteStr: string;
  IPByteStrLen: integer;
  IPDataPos: integer;
  IPLocation: PChar;
begin
  try
    if (IPRecordID<=0) or (IPRecordID>GetIPDataNum) then
      raise Exception.Create('IP信息记录号过小或越界!');
    
    pBlank:='               ';
    pReturn:=#13#10;
    EndIPOffset:=0;
    
    //取内存文件映射首地址
    pQQWryPos:=pQQWryMapFile;
    //根据记录的ID号移到该记录号的索引处,因为高位在后所以从后往前读
    Inc(pQQWryPos, FirstIPIndexOffset + (IPRecordID - 1) * 7 + 3);

    //取始末IP地址
    //索引的前4个字节为该条记录的起始IP地址
    IPDataPos:=0;
    for i:=0 to 3 do begin
      IPByteStr:=IntToStr(pQQWryPos^);
      IPByteStrLen:=Length(IPByteStr);
      CopyMemory(@IPData[IPDataPos], PChar(IPByteStr), IPByteStrLen);
      Inc(IPDataPos, IPByteStrLen);
      if i<>3 then begin
        IPData[IPDataPos]:='.';
        Inc(IPDataPos);
      end;
      dec(pQQWryPos);
    end;
    //填充空格至16位
    CopyMemory(@IPData[IPDataPos], pBlank, 16-IPDataPos);
    IPDataPos:=16;
    
    Inc(pQQWryPos, 5);
    //后3个字节是该条记录的内容区域的偏移值,内容区域的前4个字节为该条记录的结束IP地址
    CopyMemory(@EndIPOffset, pQQWryPos, 3);

    //取该条记录的结束IP地址
    pQQWryPos:=pQQWryMapFile;
    Inc(pQQWryPos, EndIPOffset + 3);
    for i:=0 to 3 do begin
      IPByteStr:=IntToStr(pQQWryPos^);
      IPByteStrLen:=Length(IPByteStr);
      CopyMemory(@IPData[IPDataPos], PChar(IPByteStr), IPByteStrLen);
      Inc(IPDataPos, IPByteStrLen);
      if i<>3 then begin
        IPData[IPDataPos]:='.';
        Inc(IPDataPos);
      end;
      dec(pQQWryPos);
    end;
    //填充空格至16位
    CopyMemory(@IPData[IPDataPos], pBlank, 32-IPDataPos);
    IPDataPos:=32;

    //取该条记录的国家地区信息
    IPLocation:=PChar(@IPData[IPDataPos]);
    GetIPLocationByEndIPOffset(EndIPOffset, IPLocation);

    //结尾的回车
    if IPLocation[StrLen(IPLocation) - 1]<>' ' then 
      Inc(IPDataPos, StrLen(IPLocation))
    else
      Inc(IPDataPos, StrLen(IPLocation) - 1);
    CopyMemory(@IPData[IPDataPos], pReturn, 2);
  except
    on E: Exception do begin
      Destroy;
      raise Exception.Create(E.Message);
      exit;
    end;
  end;
end;

///**
//* 给定一条记录的结束IP地址的偏移,返回该条记录的国家地区信息
//* @param  (EndIPOffset, IPLocation) (该条记录的结束IP地址偏移, 该条记录的国家地区信息)
//* @return 无
//*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -