diff --git a/src/FarCry2MFL_Proc.pas b/src/FarCry2MFL_Proc.pas index 8c20a00..135a53e 100644 --- a/src/FarCry2MFL_Proc.pas +++ b/src/FarCry2MFL_Proc.pas @@ -126,10 +126,12 @@ procedure TrySetFarCry2ExeName(Path: string); function CalcFileCRC32(FileName: string): Cardinal; -function IndexByGameFilesInfo(FarCry2ExeSize: Integer; FarCry2ExeCRC32: Cardinal; DuniaDllSize: Integer): Integer; +function IndexByGameFilesInfo(FarCry2ExeSize: Integer; FarCry2ExeCRC32: Cardinal; DuniaDllSize: Integer; VersionStringOffset: Integer): Integer; function GetGameVersion(): Integer; +function SearchFileForBytes(const FileName: string; BytesBuffer: array of Byte): Integer; + //-------------------------------------------------------------------------------------------------- implementation //-------------------------------------------------------------------------------------------------- @@ -638,9 +640,9 @@ procedure TrySetFarCry2ExeName(Path: string); FileName := Path + SearchRec.Name; if SameText(SearchRec.Name, 'FarCry2.exe') then CurrentMatch := CurrentMatch + 1; - if IndexByGameFilesInfo(SearchRec.Size, 0, 0) > 0 then + if IndexByGameFilesInfo(SearchRec.Size, 0, 0, 0) > 0 then CurrentMatch := CurrentMatch + 2; - if IndexByGameFilesInfo(0, CalcFileCRC32(FileName), 0) > 0 then + if IndexByGameFilesInfo(0, CalcFileCRC32(FileName), 0, 0) > 0 then CurrentMatch := CurrentMatch + 4; if CurrentMatch > BestMatch then begin @@ -667,7 +669,7 @@ function CalcFileCRC32(FileName: string): Cardinal; Result := TCRC32.Calc(FileBuffer, Length(FileBuffer)); end; -function IndexByGameFilesInfo(FarCry2ExeSize: Integer; FarCry2ExeCRC32: Cardinal; DuniaDllSize: Integer): Integer; +function IndexByGameFilesInfo(FarCry2ExeSize: Integer; FarCry2ExeCRC32: Cardinal; DuniaDllSize: Integer; VersionStringOffset: Integer): Integer; var i: Integer; begin @@ -675,9 +677,10 @@ function IndexByGameFilesInfo(FarCry2ExeSize: Integer; FarCry2ExeCRC32: Cardinal for i := Low(GameFilesInfo) to High(GameFilesInfo) do begin {(*} - if (FarCry2ExeSize <> 0) and (GameFilesInfo[i].FarCry2ExeSize = FarCry2ExeSize) or - (FarCry2ExeCRC32 <> 0) and (GameFilesInfo[i].FarCry2ExeCRC32 = FarCry2ExeCRC32) or - (DuniaDllSize <> 0) and (GameFilesInfo[i].DuniaDllSize = DuniaDllSize) then + if (FarCry2ExeSize <> 0) and (GameFilesInfo[i].FarCry2ExeSize = FarCry2ExeSize) or + (FarCry2ExeCRC32 <> 0) and (GameFilesInfo[i].FarCry2ExeCRC32 = FarCry2ExeCRC32) or + (DuniaDllSize <> 0) and (GameFilesInfo[i].DuniaDllSize = DuniaDllSize) or + (VersionStringOffset <> 0 ) and (GameFilesInfo[i].VersionStringOffset = VersionStringOffset) then {*)} begin Result := i; @@ -696,11 +699,23 @@ function GetGameVersion(): Integer; begin Result := 0; DuniaDllSize := GetFileSize(DuniaDllName); - IndexByDuniaDll := IndexByGameFilesInfo(0, 0, DuniaDllSize); + IndexByDuniaDll := IndexByGameFilesInfo(0, 0, DuniaDllSize, 0); if (IndexByDuniaDll >= Low(GameFilesInfo)) and (IndexByDuniaDll <= High(GameFilesInfo)) then VersionStringOffset := GameFilesInfo[IndexByDuniaDll].VersionStringOffset else - raise Exception.Create(Format('Wrong size of Dunia.dll file (%d). Game version v1.03 supported only.', [DuniaDllSize])); + begin + // No size match. Then try to find version string + VersionStringOffset := SearchFileForBytes(DuniaDllName, [$76, $65, $72, $73, $69, $6F, $6E, $2E, $69, $6E, $69]); //version.ini + if VersionStringOffset > 0 then + begin + VersionStringOffset := VersionStringOffset + 12; + IndexByDuniaDll := IndexByGameFilesInfo(0, 0, 0, VersionStringOffset); + end; + if (IndexByDuniaDll >= Low(GameFilesInfo)) and (IndexByDuniaDll <= High(GameFilesInfo)) then + VersionStringOffset := GameFilesInfo[IndexByDuniaDll].VersionStringOffset + else + raise Exception.Create(Format('Wrong size of Dunia.dll file (%d). Game version v1.03 supported only.', [DuniaDllSize])); + end; FileStream := TFileStream.Create(DuniaDllName, fmOpenRead or fmShareDenyNone); FileStream.Seek(VersionStringOffset, soFromBeginning); FileStream.ReadBuffer(UpdateVersion, 4); @@ -710,6 +725,34 @@ function GetGameVersion(): Integer; Result := IndexByDuniaDll; end; +function SearchFileForBytes(const FileName: string; BytesBuffer: array of Byte): Integer; +var + FileBuffer: TByteDynArray; + FileSize: Integer; + PatternSize: Integer; + i, j: Integer; + FileStream: TFileStream; + BytesRead: Integer; +begin + Result := -1; + FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); + SetLength(FileBuffer, FileStream.Size); + BytesRead := FileStream.Read(Pointer(FileBuffer)^, FileStream.Size); + FileStream.Free; + FileSize := Length(FileBuffer); + PatternSize := Length(BytesBuffer); + for i := 0 to FileSize - PatternSize do + begin + j := 0; + while (FileBuffer[i + j] = BytesBuffer[j]) and (j < PatternSize) do + Inc(j); + if j = PatternSize then //FOUND + begin + Result := i; + end; + end; +end; + procedure FormOptionsAddSubItems(Nodes: IXMLNodeList; var SubItems: TOptionSubItems); var N: Integer; diff --git a/src/FarCry2MFLauncher.dof b/src/FarCry2MFLauncher.dof index a5ade2d..a0bc297 100644 --- a/src/FarCry2MFLauncher.dof +++ b/src/FarCry2MFLauncher.dof @@ -113,9 +113,9 @@ RootDir= IncludeVerInfo=1 AutoIncBuild=1 MajorVer=1 -MinorVer=8 +MinorVer=9 Release=0 -Build=49 +Build=50 Debug=0 PreRelease=0 Special=0 @@ -126,7 +126,7 @@ CodePage=1252 [Version Info Keys] CompanyName= FileDescription= -FileVersion=1.8.0.49 +FileVersion=1.9.0.50 InternalName= LegalCopyright= LegalTrademarks= diff --git a/src/FarCry2MFLauncher.res b/src/FarCry2MFLauncher.res index 775f063..a0fb5ed 100644 Binary files a/src/FarCry2MFLauncher.res and b/src/FarCry2MFLauncher.res differ