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

📄 iddb.pas

📁 传奇源代码的delphi版本
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit IDDB;

interface
uses
  svn, Windows,Classes,SysUtils,Forms,Grobal2,MudUtil;
ResourceString
  sDBHeaderDesc     = '翎风游戏数据库文件 2005/04/20';
  sDBIdxHeaderDesc  = '翎风游戏数据库索引文件 2005/04/20';
type
  TDBHeader = packed record
    sDesc       :String[34]; //0x00
    n23         :Integer;    //0x23
    n28         :Integer;    //0x27
    n2C         :Integer;    //0x2B
    n30         :Integer;    //0x2F
    n34         :Integer;    //0x33
    n38         :Integer;    //0x37
    n3C         :Integer;    //0x3B
    n40         :Integer;    //0x3F
    n44         :Integer;    //0x43
    n48         :Integer;    //0x47
    n4B         :Byte;       //0x4B
    n4C         :Integer;    //0x4C
    n50         :Integer;    //0x50
    n54         :Integer;    //0x54
    n58         :Integer;    //0x58
    nLastIndex  :Integer;    //0x5C
    dLastDate   :TDateTime;  //0x60
    nIDCount    :Integer;    //0x68
    n6C         :Integer;    //0x6C
    nDeletedIdx :Integer;    //0x70
    dUpdateDate :TDateTime;  //0x74
  end;
  pTDBHeader = ^TDBHeader;
  TIdxHeader = packed record
    sDesc       :String[43]; //0x00
    n2C         :Integer;    //0x2C
    n30         :Integer;    //0x30
    n34         :Integer;    //0x34
    n38         :Integer;    //0x38
    n3C         :Integer;    //0x3C
    n40         :Integer;    //0x40
    n44         :Integer;    //0x44
    n48         :Integer;    //0x48
    n4C         :Integer;    //0x4C
    n50         :Integer;    //0x50
    n54         :Integer;    //0x54
    n58         :Integer;    //0x58
    n5C         :Integer;    //0x5C
    n60         :Integer;    //0x60
    nQuickCount :Integer;    //0x64
    nIDCount    :Integer;    //0x68
    nLastIndex  :Integer;    //0x6C
    dUpdateDate :TDateTime;  //0x70
  end;


  TRecordDeletedHeader = packed record
    boDeleted     :Boolean;
    bt1           :Byte;
    bt2           :Byte;
    bt3           :Byte;
    CreateDate    :TDateTime; //0x04
    LastLoginDate :TDateTime; //0x0C
    n14           :Integer;
    nNextDeletedIdx  :Integer;
//    sAccount   :String[11];//0x14
  end;



  TIdxRecord = packed record
    sName       :String[11];
    nIndex      :Integer;
  end;
  pTIdxRecord = ^TIdxRecord;
  //TNotifyEvent = procedure(Sender: TObject) of object;
  TFileIDDB = class
    m_nLastReadIdx  :Integer;        //0x4  最后访问的记录号
    m_nDeletedIdx   :Integer;        //0x8  已删除的最后一个记录号
    nC              :Integer;        //0x0C
//    w10         :Word;           //0x10
//    w12         :Word;           //0x12
//    n14         :Integer;
    m_OnChange      :TNotifyEvent;
    m_boChanged     :Boolean;        //0x18 数据库已被更改
    m_nLastIndex    :Integer;        //0x1C 最后一次写数据的记录号
    m_dLastDate     :TDateTime;      //0x20 最后修改日期
    m_nFileHandle   :Integer;        //0x28
    m_Header        :TDBHeader;      //0x2C 数据库头
    m_QuickList     :TQuickList;     //0xA4 数据索引表
    m_sDBFileName   :String;         //0xAC
    m_sIdxFileName  :String;         //0xB0
    FCriticalSection:TRTLCriticalSection;
  private
    function LoadDBIndex: Boolean;
    procedure LoadQuickList;
    procedure SaveDBIndex;
    function GetRecord(nIndex: Integer; var DBRecord: TAccountDBRecord): Boolean;

    function UpdateRecord(nIndex: Integer; DBRecord: TAccountDBRecord;
      boNew: Boolean): Boolean;

  public
    constructor Create(sFileName:String);
    destructor Destroy; override;
    procedure Lock;
    procedure UnLock;
    function Open: Boolean;
    function OpenEx: Boolean;
    function Index(sName:String):Integer;
    function Get(nIndex:Integer;var DBRecord: TAccountDBRecord):Integer;
    function FindByName(sName:string; var List:TStringList):Integer;
    function GetBy(nIndex:Integer;var DBRecord:TAccountDBRecord):Boolean;
    function Update(nIndex: Integer; var DBRecord: TAccountDBRecord): Boolean;
    function Add(var DBRecord: TAccountDBRecord):Boolean;
    procedure Close;
  end;
var
  AccountDB     :TFileIDDB;  
implementation

uses LSShare, HUtil32;

{ TFileIDDB }
//00457D5C
constructor TFileIDDB.Create(sFileName: String);
begin
  InitializeCriticalSection(FCriticalSection);
  m_nLastReadIdx              := 0;
  m_sDBFileName               := sFileName;
  m_sIdxFileName              := sFileName + '.idx';
  m_QuickList                 := TQuickList.Create;
  m_QuickList.boCaseSensitive := False;
  g_n472A6C                   := 0;
  g_n472A74                   := 0;
  g_boDataDBReady             := False;
  m_nLastIndex                := -1;
  m_nDeletedIdx               := -1;
  if LoadDBIndex then g_boDataDBReady:=True
  else LoadQuickList();
end;

destructor TFileIDDB.Destroy;
//0x00457E64
begin
  if g_boDataDBReady then SaveDBIndex();
  m_QuickList.Free;
  DeleteCriticalSection(FCriticalSection);
end;
procedure TFileIDDB.Lock; //0x00457EA8
begin
  EnterCriticalSection(FCriticalSection);
end;
procedure TFileIDDB.UnLock;
begin
  LeaveCriticalSection(FCriticalSection);
end;
//00457F60
function TFileIDDB.Open: Boolean;
begin
  Lock();
  m_nLastReadIdx:=0;
  m_boChanged:=False;
  if FileExists(m_sDBFileName) then begin
    m_nFileHandle:=FileOpen(m_sDBFileName,fmOpenReadWrite or fmShareDenyNone);
    if m_nFileHandle > 0 then
      FileRead(m_nFileHandle,m_Header,SizeOf(TDBHeader));
  end else begin
    m_nFileHandle:=FileCreate(m_sDBFileName);
    if m_nFileHandle > 0 then begin
      m_Header.sDesc       := sDBHeaderDesc;
      m_Header.nIDCount    := 0;
      m_Header.n6C         := 0;
      m_Header.nDeletedIdx := -1;
      FileWrite(m_nFileHandle,m_Header,SizeOf(TDBHeader));
    end;
  end;
  if m_nFileHandle > 0 then begin
    Result:=True;
//    nDeletedIdx:=Header.n70; //Jacky 增加
  end else Result:=False;
end;
procedure TFileIDDB.Close();//0x00458064
begin
  FileClose(m_nFileHandle);
  if m_boChanged and Assigned(m_OnChange) then begin
    m_OnChange(Self);
  end;
    
  UnLock();
end;

//加载数据索引文件
//00458508
function TFileIDDB.LoadDBIndex():Boolean;
var
  nIdxFileHandle :Integer;
  IdxHeader      :TIdxHeader;
  DBHeader       :TDBHeader;
  IdxRecord      :TIdxRecord;
  HumRecord      :TAccountDBRecord;
  I              :Integer;
  n14            :Integer;
begin
  Result:=False;
  nIdxFileHandle:=0;
  FillChar(IdxHeader,SizeOf(TIdxHeader),#0);
  if FileExists(m_sIdxFileName) then
    nIdxFileHandle:=FileOpen(m_sIdxFileName,fmOpenReadWrite or fmShareDenyNone);
  if nIdxFileHandle > 0 then begin
    Result:=True;
    FileRead(nIdxFileHandle,IdxHeader,SizeOf(TIdxHeader));

    try
      if Open then begin
        FileSeek(m_nFileHandle,0,0);
        if FileRead(m_nFileHandle,DBHeader,SizeOf(TDBHeader)) = SizeOf(TDBHeader) then begin
          if IdxHeader.nIDCount <> DBHeader.nIDCount then
            Result:=False;
        end;
        if IdxHeader.nLastIndex <> DBHeader.nLastIndex then begin
          Result:=False;
        end;
        if IdxHeader.nLastIndex > -1 then begin
          FileSeek(m_nFileHandle,IdxHeader.nLastIndex * SizeOf(TAccountDBRecord) + SizeOf(TDBHeader),0);
          if FileRead(m_nFileHandle,HumRecord,SizeOf(TAccountDBRecord)) = SizeOf(TAccountDBRecord) then
            if IdxHeader.dUpdateDate <> HumRecord.Header.UpdateDate then
              Result:=False;
        end;
      end;
    finally
      Close();
    end;
    if Result then begin
      m_nLastIndex  := IdxHeader.nLastIndex;
      m_dLastDate   := IdxHeader.dUpdateDate;
      for i:=0 to IdxHeader.nQuickCount -1 do begin
        if FileRead(nIdxFileHandle,IdxRecord,SizeOf(TIdxRecord)) = SizeOf(TIdxRecord) then begin
          m_QuickList.AddObject(IdxRecord.sName,TObject(IdxRecord.nIndex));
        end else begin
          Result:=False;
          break;
        end;

⌨️ 快捷键说明

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