📄 humdb.pas
字号:
unit HumDB;
interface
uses
svn, Windows,Classes,SysUtils,Forms,MudUtil,Grobal2;
ResourceString
sDBHeaderDesc = '翎风游戏数据库文件 2005/04/20';
sDBIdxHeaderDesc = '翎风游戏数据库索引文件 2005/04/20';
type
TDBHeader = record
sDesc :String[35]; //0x00
n24 :Integer; //0x24
n28 :Integer; //0x28
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
nLastIndex :Integer; //0x5C
dLastDate :TDateTime; //0x60
nHumCount :Integer; //0x68
n6C :Integer; //0x6C
n70 :Integer; //0x70
dUpdateDate :TDateTime; //0x74
end;
pTDBHeader = ^TDBHeader;
TIdxHeader = record
sDesc :String[40]; //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
nHumCount :Integer; //0x68
nDeleteCount:Integer; //0x6C
nLastIndex :Integer; //0x70
dUpdateDate :TDateTime; //0x74
end;
pTHumInfo = ^THumInfo;
TIdxRecord = record
sChrName :String[15];
nIndex :Integer;
end;
pTIdxRecord = ^TIdxRecord;
TFileHumDB = class
n4 :Integer; //0x04
m_nFileHandle :Integer; //0x08
n0C :Integer; //0x0C
m_OnChange :TNotifyEvent;
m_boChanged :Boolean; //0x18
m_Header :TDBHeader; //0x1C
m_QuickList :TQuickList; //0x98
m_QuickIDList :TQuickIDList; //0x9C
m_DeletedList :TList; //0xA0 已被删除的记录号
m_sDBFileName :String; //0xA4
private
procedure LoadQuickList;
procedure Lock;
procedure UnLock;
function UpdateRecord(nIndex:Integer;HumRecord:THumInfo;boNew:Boolean):Boolean;
function DeleteRecord(nIndex:Integer):Boolean;
function GetRecord(n08:Integer;var HumDBRecord:THumInfo):Boolean;
public
constructor Create(sFileName:String);
destructor Destroy; override;
function Open():Boolean;
function OpenEx():Boolean;
procedure Close();
function Index(sName:String):Integer;
function Get(n08:Integer;var HumDBRecord:THumInfo):Integer;
function GetBy(n08:Integer;var HumDBRecord:THumInfo):Boolean;
function FindByName(sChrName:String;ChrList:TStringList):Integer;
function FindByAccount(sAccount:String;var ChrList:TStringList):Integer;
function ChrCountOfAccount(sAccount:String):Integer;
function Add(HumRecord:THumInfo):Boolean;
function Delete(sName:String):Boolean;
function Update(nIndex:Integer;var HumDBRecord:THumInfo):Boolean;
function UpdateBy(nIndex:Integer;var HumDBRecord:THumInfo):Boolean;
end;
TFileDB = class
n4 :Integer; //0x4
m_nFileHandle :Integer; //0x08
nC :Integer;
m_OnChange :TNotifyEvent; //0x10
m_boChanged :Boolean; //0x18
m_nLastIndex :Integer; //0x1C
m_dUpdateTime :TDateTime; //0x20
m_Header :TDBHeader; //0x28
m_QuickList :TQuickList; //0xA4
m_DeletedList :TList; //0xA8 已被删除的记录号
m_sDBFileName :String; //0xAC
m_sIdxFileName:String; //0xB0
private
procedure LoadQuickList;
function LoadDBIndex():Boolean;
procedure SaveIndex();
function GetRecord(nIndex:Integer;var HumanRCD:THumDataInfo):Boolean;
function UpdateRecord(nIndex:Integer;var HumanRCD:THumDataInfo;boNew:Boolean):Boolean;
function DeleteRecord(nIndex:Integer):Boolean;
public
constructor Create(sFileName:String);
destructor Destroy; override;
procedure Lock;
procedure UnLock;
function Open():Boolean;
function OpenEx():Boolean;
procedure Close();
function Index(sName:String):Integer;
function Get(nIndex:Integer;var HumanRCD:THumDataInfo):Integer;
function Update(nIndex:Integer;var HumanRCD:THumDataInfo):Boolean;
function Add(var HumanRCD:THumDataInfo):Boolean;
function Find(sChrName:String;List:TStrings):Integer;
procedure Rebuild();
function Count():Integer;
function Delete(sChrName:String):Boolean;overload;
function Delete(nIndex:Integer):Boolean;overload;
end;
var
HumChrDB :TFileHumDB;
HumDataDB :TFileDB;
implementation
uses DBShare, HUtil32;
{ TFileHumDB }
constructor TFileHumDB.Create(sFileName: String);//0x0048B73C
begin
m_sDBFileName := sFileName;
m_QuickList := TQuickList.Create;
m_QuickIDList := TQuickIDList.Create;
m_DeletedList := TList.Create;
n4ADAFC := 0;
n4ADB04 := 0;
boHumDBReady := False;
LoadQuickList();
end;
destructor TFileHumDB.Destroy;
begin
m_QuickList.Free;
m_QuickIDList.Free;
inherited;
end;
procedure TFileHumDB.Lock();//0x0048B870
begin
EnterCriticalSection(HumDB_CS);
end;
procedure TFileHumDB.UnLock();//0x0048B888
begin
LeaveCriticalSection(HumDB_CS);
end;
procedure TFileHumDB.LoadQuickList();
//0x48BA64
var
nRecordIndex :Integer;
nIndex :Integer;
AccountList :TStringList;
ChrNameList :TStringList;
DBHeader :TDBHeader;
DBRecord :THumInfo;
begin
n4:=0;
m_QuickList.Clear;
m_QuickIDList.Clear;
m_DeletedList.Clear;
nRecordIndex:=0;
n4ADAFC:=0;
n4ADB00:=0;
n4ADB04:=0;
AccountList:=TStringList.Create;
ChrNameList:=TStringList.Create;
try
if Open then begin
FileSeek(m_nFileHandle,0,0);
if FileRead(m_nFileHandle,DBHeader,SizeOf(TDBHeader)) = SizeOf(TDBHeader) then begin
n4ADB04:=DBHeader.nHumCount;
for nIndex:=0 to DBHeader.nHumCount - 1 do begin
Inc(n4ADAFC);
if FileRead(m_nFileHandle,DBRecord,SizeOf(THumInfo)) <> SizeOf(THumInfo) then begin
break;
end;
if not DBRecord.Header.boDeleted then begin
m_QuickList.AddObject(DBRecord.Header.sChrName,TObject(nRecordIndex));
AccountList.AddObject(DBRecord.sAccount,TObject(DBRecord.Header.nSelectID));
ChrNameList.AddObject(DBRecord.sChrName,TObject(nRecordIndex));
Inc(n4ADB00);
end else begin //0x0048BC04
m_DeletedList.Add(TObject(nIndex));
end;
Inc(nRecordIndex);
Application.ProcessMessages;
if Application.Terminated then begin
Close;
exit;
end;
end;
end; //0x0048BC52
end;
finally
Close();
end;
for nIndex:=0 to AccountList.Count -1 do begin
m_QuickIDList.AddRecord(AccountList.Strings[nIndex],
ChrNameList.Strings[nIndex],
Integer(ChrNameList.Objects[nIndex]),
Integer(AccountList.Objects[nIndex]));
if (nIndex mod 100) = 0 then
Application.ProcessMessages;
end;
//0x0048BCF4
AccountList.Free;
ChrNameList.Free;
m_QuickList.SortString(0,m_QuickList.Count -1);
boHumDBReady:=True;
end;
procedure TFileHumDB.Close;//0x0048BA24
begin
FileClose(m_nFileHandle);
if m_boChanged and Assigned(m_OnChange) then begin
m_OnChange(Self);
end;
UnLock();
end;
function TFileHumDB.Open: Boolean;//0x0048B928
begin
Lock();
n4:=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 //0x0048B999
m_nFileHandle:=FileCreate(m_sDBFileName);
if m_nFileHandle > 0 then begin
FillChar(m_Header,SizeOf(TDBHeader),#0);
m_Header.sDesc:= sDBHeaderDesc;
m_Header.nHumCount:=0;
m_Header.n6C:=0;
FileWrite(m_nFileHandle,m_Header,SizeOf(TDBHeader));
end;
end;
if m_nFileHandle > 0 then Result:=True
else Result:=False;
end;
function TFileHumDB.OpenEx: Boolean;//0x0048B8A0
var
DBHeader:TDBHeader;
begin
Lock();
m_boChanged:=False;
m_nFileHandle:=FileOpen(m_sDBFileName,fmOpenReadWrite or fmShareDenyNone);
if m_nFileHandle > 0 then begin
Result:=True;
if FileRead(m_nFileHandle,DBHeader,SizeOf(TDBHeader)) = SizeOf(TDBHeader) then
m_Header:=DBHeader;
n4:=0;
end else Result:=False;
end;
function TFileHumDB.Index(sName: String): Integer;//0x0048C384
begin
Result:=m_QuickList.GetIndex(sName);
end;
function TFileHumDB.Get(n08: Integer;
var HumDBRecord: THumInfo):Integer;//0x0048C0CC
var
nIndex:Integer;
begin
nIndex:=Integer(m_QuickList.Objects[n08]);
if GetRecord(nIndex,HumDBRecord) then Result:=nIndex
else Result:= -1;
end;
function TFileHumDB.GetRecord(n08: Integer;
var HumDBRecord: THumInfo): Boolean;
//0x0048BEEC
begin
if FileSeek(m_nFileHandle,SizeOf(THumInfo) * n08 + SizeOf(TDBHeader),0) <> -1 then begin
FileRead(m_nFileHandle,HumDBRecord,SizeOf(THumInfo));
FileSeek(m_nFileHandle,-SizeOf(THumInfo) * n08 + SizeOf(TDBHeader),1);
n4:=n08;
Result:=True;
end else Result:=False;
end;
function TFileHumDB.FindByName(sChrName: String;
ChrList: TStringList): Integer;//0x0048C3E0
var
I:Integer;
begin
for I:= 0 to m_QuickList.Count - 1 do begin
if CompareLStr(m_QuickList.Strings[I],sChrName,length(sChrName)) then begin
ChrList.AddObject(m_QuickList.Strings[I],m_QuickList.Objects[I]);
end;
end;
Result:=ChrList.Count;
end;
function TFileHumDB.GetBy(n08: Integer;
var HumDBRecord: THumInfo): Boolean;//0x0048C118
begin
if n08 >= 0 then
Result:=GetRecord(n08,HumDBRecord)
else Result:= False;
end;
function TFileHumDB.FindByAccount(sAccount: String;
var ChrList: TStringList): Integer;//0x0048C4DC
var
ChrNameList:TList;
QuickID:pTQuickID;
i:Integer;
begin
ChrNameList:=nil;
m_QuickIDList.GetChrList(sAccount,ChrNameList);
if ChrNameList <> nil then begin
for i:= 0 to ChrNameList.Count - 1 do begin
QuickID:=ChrNameList.Items[i];
ChrList.AddObject(QuickID.sAccount,TObject(QuickID));
end;
end;
Result:=ChrList.Count;
end;
// FixMe: For Some reason this code doesn't work!!!
function TFileHumDB.ChrCountOfAccount(sAccount: String): Integer;//0x0048C5B0
var
ChrList:TList;
I,n18:Integer;
HumDBRecord: THumInfo;
begin
n18:=0;
ChrList:=nil;
m_QuickIDList.GetChrList(sAccount,ChrList);
if ChrList <> nil then begin
for I:= 0 to ChrList.Count - 1 do begin
if GetBy(pTQuickID(ChrList.Items[I]).nIndex,HumDBRecord) and
(not HumDBRecord.boDeleted) then Inc(n18);
end;
end;
Result:=n18;
end;
function TFileHumDB.Add(HumRecord: THumInfo): Boolean;//0x0048C1F4
var
Header:TDBHeader;
nIndex:Integer;
begin
if m_QuickList.GetIndex(HumRecord.Header.sChrName) >= 0 then Result:=False
else begin
Header:=m_Header;
if m_DeletedList.Count > 0 then begin
nIndex:=Integer(m_DeletedList.Items[0]);
m_DeletedList.Delete(0);
end else begin
nIndex:=m_Header.nHumCount;
Inc(m_Header.nHumCount);
end;
if UpdateRecord(nIndex,HumRecord,True) then begin
m_QuickList.AddRecord(HumRecord.Header.sChrName,nIndex);
m_QuickIDList.AddRecord(HumRecord.sAccount,HumRecord.sChrName,nIndex,HumRecord.Header.nSelectID);
Result:=True;
end else begin
m_Header:=Header;
Result:=False;
end;
end;
end;
function TFileHumDB.UpdateRecord(nIndex: Integer; HumRecord: THumInfo;
boNew: Boolean): Boolean;//0x0048BF5C
var
HumRcd:THumInfo;
nPosion,n10:Integer;
begin
nPosion:=nIndex * SizeOf(THumInfo) + SizeOf(TDBHeader);
if FileSeek(m_nFileHandle,nPosion,0) = nPosion then begin
n10:=FileSeek(m_nFileHandle,0,1);
if boNew and
(FileRead(m_nFileHandle,HumRcd,SizeOf(THumInfo)) = SizeOf(THumInfo)) and
(not HumRcd.Header.boDeleted) and (HumRcd.Header.sChrName <> '') then Result:=True
else begin
HumRecord.Header.boDeleted:=False;
HumRecord.Header.dCreateDate:=Now();
m_Header.dUpdateDate:=Now();
FileSeek(m_nFileHandle,0,0);
FileWrite(m_nFileHandle,m_Header,SizeOf(TDBHeader));
FileSeek(m_nFileHandle,n10,0);
FileWrite(m_nFileHandle,HumRecord,SizeOf(THumInfo));
FileSeek(m_nFileHandle,-SizeOf(THumInfo),1);
n4:=nIndex;
m_boChanged:=True;
Result:=True;
end;
end else Result:=False;
end;
function TFileHumDB.Delete(sName: String): Boolean;//0x0048BDE0
var
n10:integer;
HumRecord:THumInfo;
ChrNameList:TList;
n14:Integer;
begin
Result:=False;
n10:=m_QuickList.GetIndex(sName);
if n10 < 0 then exit;
Get(n10,HumRecord);
if DeleteRecord(Integer(m_QuickList.Objects[n10])) then begin
m_QuickList.Delete(n10);
Result:=True;
end;
n14:=m_QuickIDList.GetChrList(HumRecord.sAccount,ChrNameList);
if n14 >= 0 then begin
m_QuickIDList.DelRecord(n14,HumRecord.sChrName);
end;
end;
function TFileHumDB.DeleteRecord(nIndex: Integer): Boolean;//0x0048BD58
var
HumRcdHeader:TRecordHeader;
begin
Result:=False;
if FileSeek(m_nFileHandle,nIndex * SizeOf(THumInfo) + SizeOf(TDBHeader),0) = -1 then exit;
HumRcdHeader.boDeleted:=True;
HumRcdHeader.dCreateDate:=Now();
FileWrite(m_nFileHandle,HumRcdHeader,SizeOf(TRecordHeader));
m_DeletedList.Add(Pointer(nIndex));
m_boChanged:=True;
Result:=True;
end;
function TFileHumDB.Update(nIndex: Integer;var HumDBRecord: THumInfo): Boolean;//0x0048C14C
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -