Initial Revision
This commit is contained in:
commit
5bca4ba6a2
38
SmartPatcher.cfg
Normal file
38
SmartPatcher.cfg
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
-$A8
|
||||||
|
-$B-
|
||||||
|
-$C+
|
||||||
|
-$D+
|
||||||
|
-$E-
|
||||||
|
-$F-
|
||||||
|
-$G+
|
||||||
|
-$H+
|
||||||
|
-$I+
|
||||||
|
-$J-
|
||||||
|
-$K-
|
||||||
|
-$L+
|
||||||
|
-$M-
|
||||||
|
-$N+
|
||||||
|
-$O+
|
||||||
|
-$P+
|
||||||
|
-$Q-
|
||||||
|
-$R-
|
||||||
|
-$S-
|
||||||
|
-$T-
|
||||||
|
-$U-
|
||||||
|
-$V+
|
||||||
|
-$W-
|
||||||
|
-$X+
|
||||||
|
-$YD
|
||||||
|
-$Z1
|
||||||
|
-cg
|
||||||
|
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||||
|
-H+
|
||||||
|
-W+
|
||||||
|
-M
|
||||||
|
-$M16384,1048576
|
||||||
|
-K$00400000
|
||||||
|
-LE"c:\program files\borland\delphi7\Projects\Bpl"
|
||||||
|
-LN"c:\program files\borland\delphi7\Projects\Bpl"
|
||||||
|
-w-UNSAFE_TYPE
|
||||||
|
-w-UNSAFE_CODE
|
||||||
|
-w-UNSAFE_CAST
|
140
SmartPatcher.dof
Normal file
140
SmartPatcher.dof
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
[FileVersion]
|
||||||
|
Version=7.0
|
||||||
|
[Compiler]
|
||||||
|
A=8
|
||||||
|
B=0
|
||||||
|
C=1
|
||||||
|
D=1
|
||||||
|
E=0
|
||||||
|
F=0
|
||||||
|
G=1
|
||||||
|
H=1
|
||||||
|
I=1
|
||||||
|
J=0
|
||||||
|
K=0
|
||||||
|
L=1
|
||||||
|
M=0
|
||||||
|
N=1
|
||||||
|
O=1
|
||||||
|
P=1
|
||||||
|
Q=0
|
||||||
|
R=0
|
||||||
|
S=0
|
||||||
|
T=0
|
||||||
|
U=0
|
||||||
|
V=1
|
||||||
|
W=0
|
||||||
|
X=1
|
||||||
|
Y=1
|
||||||
|
Z=1
|
||||||
|
ShowHints=1
|
||||||
|
ShowWarnings=1
|
||||||
|
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
||||||
|
NamespacePrefix=
|
||||||
|
SymbolDeprecated=1
|
||||||
|
SymbolLibrary=1
|
||||||
|
SymbolPlatform=1
|
||||||
|
UnitLibrary=1
|
||||||
|
UnitPlatform=1
|
||||||
|
UnitDeprecated=1
|
||||||
|
HResultCompat=1
|
||||||
|
HidingMember=1
|
||||||
|
HiddenVirtual=1
|
||||||
|
Garbage=1
|
||||||
|
BoundsError=1
|
||||||
|
ZeroNilCompat=1
|
||||||
|
StringConstTruncated=1
|
||||||
|
ForLoopVarVarPar=1
|
||||||
|
TypedConstVarPar=1
|
||||||
|
AsgToTypedConst=1
|
||||||
|
CaseLabelRange=1
|
||||||
|
ForVariable=1
|
||||||
|
ConstructingAbstract=1
|
||||||
|
ComparisonFalse=1
|
||||||
|
ComparisonTrue=1
|
||||||
|
ComparingSignedUnsigned=1
|
||||||
|
CombiningSignedUnsigned=1
|
||||||
|
UnsupportedConstruct=1
|
||||||
|
FileOpen=1
|
||||||
|
FileOpenUnitSrc=1
|
||||||
|
BadGlobalSymbol=1
|
||||||
|
DuplicateConstructorDestructor=1
|
||||||
|
InvalidDirective=1
|
||||||
|
PackageNoLink=1
|
||||||
|
PackageThreadVar=1
|
||||||
|
ImplicitImport=1
|
||||||
|
HPPEMITIgnored=1
|
||||||
|
NoRetVal=1
|
||||||
|
UseBeforeDef=1
|
||||||
|
ForLoopVarUndef=1
|
||||||
|
UnitNameMismatch=1
|
||||||
|
NoCFGFileFound=1
|
||||||
|
MessageDirective=1
|
||||||
|
ImplicitVariants=1
|
||||||
|
UnicodeToLocale=1
|
||||||
|
LocaleToUnicode=1
|
||||||
|
ImagebaseMultiple=1
|
||||||
|
SuspiciousTypecast=1
|
||||||
|
PrivatePropAccessor=1
|
||||||
|
UnsafeType=0
|
||||||
|
UnsafeCode=0
|
||||||
|
UnsafeCast=0
|
||||||
|
[Linker]
|
||||||
|
MapFile=0
|
||||||
|
OutputObjs=0
|
||||||
|
ConsoleApp=1
|
||||||
|
DebugInfo=0
|
||||||
|
RemoteSymbols=0
|
||||||
|
MinStackSize=16384
|
||||||
|
MaxStackSize=1048576
|
||||||
|
ImageBase=4194304
|
||||||
|
ExeDescription=SmartPatcher for new versions of cracked software.
|
||||||
|
[Directories]
|
||||||
|
OutputDir=
|
||||||
|
UnitOutputDir=
|
||||||
|
PackageDLLOutputDir=
|
||||||
|
PackageDCPOutputDir=
|
||||||
|
SearchPath=
|
||||||
|
Packages=vcl;dclOfficeXP;vcldb;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL
|
||||||
|
Conditionals=
|
||||||
|
DebugSourceDirs=
|
||||||
|
UsePackages=0
|
||||||
|
[Parameters]
|
||||||
|
RunParams=
|
||||||
|
HostApplication=
|
||||||
|
Launcher=
|
||||||
|
UseLauncher=0
|
||||||
|
DebugCWD=
|
||||||
|
[Language]
|
||||||
|
ActiveLang=
|
||||||
|
ProjectLang=
|
||||||
|
RootDir=
|
||||||
|
[Version Info]
|
||||||
|
IncludeVerInfo=1
|
||||||
|
AutoIncBuild=1
|
||||||
|
MajorVer=1
|
||||||
|
MinorVer=0
|
||||||
|
Release=0
|
||||||
|
Build=5
|
||||||
|
Debug=0
|
||||||
|
PreRelease=0
|
||||||
|
Special=1
|
||||||
|
Private=0
|
||||||
|
DLL=0
|
||||||
|
Locale=1033
|
||||||
|
CodePage=1252
|
||||||
|
[Version Info Keys]
|
||||||
|
CompanyName=riddick
|
||||||
|
FileDescription=SmartPatcher for new versions of cracked software.
|
||||||
|
FileVersion=1.0.0.5
|
||||||
|
InternalName=SmartPatcher
|
||||||
|
LegalCopyright=
|
||||||
|
LegalTrademarks=
|
||||||
|
OriginalFilename=SmartPatcher.exe
|
||||||
|
ProductName=SmartPatcher
|
||||||
|
ProductVersion=1.0.0.0
|
||||||
|
Comments=SmartPatcher for new versions of already cracked software.
|
||||||
|
SpecialBuild=
|
||||||
|
[HistoryLists\hlUnitAliases]
|
||||||
|
Count=1
|
||||||
|
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
|
14
SmartPatcher.dpr
Normal file
14
SmartPatcher.dpr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
program SmartPatcher;
|
||||||
|
|
||||||
|
uses
|
||||||
|
Forms,
|
||||||
|
USmartPatcher in 'USmartPatcher.pas' {FPatcher};
|
||||||
|
|
||||||
|
{$R *.res}
|
||||||
|
|
||||||
|
begin
|
||||||
|
Application.Initialize;
|
||||||
|
Application.Title := 'SmartPatcher';
|
||||||
|
Application.CreateForm(TFPatcher, FPatcher);
|
||||||
|
Application.Run;
|
||||||
|
end.
|
43
SmartPatcher.txt
Normal file
43
SmartPatcher.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
SmartPatcher by riddick
|
||||||
|
=======================
|
||||||
|
|
||||||
|
P U R P O S E
|
||||||
|
|
||||||
|
Let's say, you have downloaded a cracked version of CoolApp 1.0. You have the
|
||||||
|
original program file CoolApp.exe and a cracked one CoolApp.cracked.exe . But
|
||||||
|
now there's version 1.2 out and you don't have a crack for it. What do you do?
|
||||||
|
|
||||||
|
SmartPatcher is the solution! It analyzes the changes made by the cracker to
|
||||||
|
the v1.0 files and tries to apply the same changes to the new file. This works
|
||||||
|
with *almost any* application if the versions don't differ too much.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
U S A G E
|
||||||
|
|
||||||
|
Staying with the previously created example, you would select your original
|
||||||
|
CoolApp.exe of version 1.0 as the "Original file", the cracked one as "Modified
|
||||||
|
file" and the new version 1.2 of CoolApp.exe as "New file". Now click on
|
||||||
|
"SmartPatch!" and take a look at the Messagebox. If you see some error lines
|
||||||
|
about not finding the appropriate location, try to check "Extended Search" on
|
||||||
|
your next try. (Restore the backup first.) Extended Search will do some more
|
||||||
|
searching which could take much longer with huge files.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
L I M I T A T I O N S
|
||||||
|
|
||||||
|
Although it worked in most cases for me, there can be files where it doesn't.
|
||||||
|
Be warned that you use this software on your own risk. If you damage your
|
||||||
|
files, your computer or whatever - don't blame me.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
C O N T A C T
|
||||||
|
|
||||||
|
If you want to contact me, do so through the forum at www.p800stuff.com. My
|
||||||
|
username there is "riddick".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-riddick
|
1469
USmartPatcher.dfm
Normal file
1469
USmartPatcher.dfm
Normal file
File diff suppressed because it is too large
Load Diff
349
USmartPatcher.pas
Normal file
349
USmartPatcher.pas
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
unit USmartPatcher;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Windows, SysUtils, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Classes, Graphics, StrUtils;
|
||||||
|
|
||||||
|
type
|
||||||
|
TFPatcher = class(TForm)
|
||||||
|
Label1: TLabel;
|
||||||
|
Label2: TLabel;
|
||||||
|
GroupOrigFileset: TGroupBox;
|
||||||
|
Label3: TLabel;
|
||||||
|
Label4: TLabel;
|
||||||
|
OpenDialog: TOpenDialog;
|
||||||
|
EditOrigFile: TEdit;
|
||||||
|
EditModFile: TEdit;
|
||||||
|
ButBrowseOrig: TButton;
|
||||||
|
ButBrowseMod: TButton;
|
||||||
|
GroupNewFile: TGroupBox;
|
||||||
|
Label5: TLabel;
|
||||||
|
EditNewFile: TEdit;
|
||||||
|
ButtBrowseNew: TButton;
|
||||||
|
ImgLogoRiddickTop: TImage;
|
||||||
|
ButtSmartPatch: TButton;
|
||||||
|
LogBox: TListBox;
|
||||||
|
Label6: TLabel;
|
||||||
|
CheckBackup: TCheckBox;
|
||||||
|
ButtExit: TButton;
|
||||||
|
ImgLogoRiddickLeft: TImage;
|
||||||
|
CheckExtSearch: TCheckBox;
|
||||||
|
procedure ButBrowseOrigClick(Sender: TObject);
|
||||||
|
procedure ButtExitClick(Sender: TObject);
|
||||||
|
procedure ButBrowseModClick(Sender: TObject);
|
||||||
|
procedure ButtBrowseNewClick(Sender: TObject);
|
||||||
|
procedure ButtSmartPatchClick(Sender: TObject);
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
private
|
||||||
|
{ Private declarations }
|
||||||
|
public
|
||||||
|
{ Public declarations }
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
FPatcher: TFPatcher;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.dfm}
|
||||||
|
|
||||||
|
const
|
||||||
|
PreAftLen: integer = 10;
|
||||||
|
PreAftSrc: integer = $4000;
|
||||||
|
|
||||||
|
type
|
||||||
|
TModRec = record
|
||||||
|
Offset: longint;
|
||||||
|
Length: longint;
|
||||||
|
Orig: AnsiString;
|
||||||
|
New: AnsiString;
|
||||||
|
Pre: AnsiString;
|
||||||
|
Aft: AnsiString;
|
||||||
|
end;
|
||||||
|
TModRecA = array of TModRec;
|
||||||
|
|
||||||
|
var
|
||||||
|
Mods: TModRecA;
|
||||||
|
|
||||||
|
procedure Log(x: string);
|
||||||
|
var i: integer;
|
||||||
|
begin
|
||||||
|
while (FPatcher.LogBox.Count>500) do begin
|
||||||
|
FPatcher.LogBox.Items.Delete(0);
|
||||||
|
end;
|
||||||
|
i := FPatcher.LogBox.Items.Add(x);
|
||||||
|
FPatcher.LogBox.TopIndex := i;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Dec2Hex(d: longint): string;
|
||||||
|
const hexset: string[16] = '0123456789abcdef';
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
while (d>=16) do begin
|
||||||
|
Result := hexset[(d MOD 16)+1] + Result;
|
||||||
|
d := d DIV 16;
|
||||||
|
end;
|
||||||
|
Result := hexset[d+1] + Result;
|
||||||
|
if (Length(Result) MOD 2=1) then Result := '0'+Result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function FindModsInFiles(g1,g2: string): TModRecA;
|
||||||
|
var f1,f2: file of char;
|
||||||
|
Buf1, Buf2: array[1..64] of char;
|
||||||
|
i, i1, i2: integer;
|
||||||
|
o: longint;
|
||||||
|
lastinequal: boolean;
|
||||||
|
resi: longint;
|
||||||
|
Last10, Next10: AnsiString;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
AssignFile(f1,g1);
|
||||||
|
AssignFile(f2,g2);
|
||||||
|
FileMode := fmOpenRead;
|
||||||
|
Reset(f1);
|
||||||
|
Reset(f2);
|
||||||
|
repeat
|
||||||
|
if (FilePos(f1)<>FilePos(f2)) then begin
|
||||||
|
Log('ERROR while reading! File positions are different. Aborting.');
|
||||||
|
CloseFile(f1);
|
||||||
|
CloseFile(f2);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
o := FilePos(f1);
|
||||||
|
BlockRead(f1,Buf1,SizeOf(Buf1),i1);
|
||||||
|
BlockRead(f2,Buf2,SizeOf(Buf2),i2);
|
||||||
|
if (i2<>i1) then begin
|
||||||
|
Log('ERROR while reading! Different sized blocks were read. Aborting.');
|
||||||
|
CloseFile(f1);
|
||||||
|
CloseFile(f2);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
lastinequal := false;
|
||||||
|
for i:=1 to i1 do begin
|
||||||
|
if (Buf1[i]<>Buf2[i]) then begin
|
||||||
|
if (lastinequal) then begin
|
||||||
|
resi := Length(Result)-1;
|
||||||
|
Inc(Result[resi].Length);
|
||||||
|
Result[resi].Orig := Result[resi].Orig + Buf1[i];
|
||||||
|
Result[resi].New := Result[resi].New + Buf2[i];
|
||||||
|
end else begin
|
||||||
|
resi := Length(Result);
|
||||||
|
SetLength(Result, resi+1);
|
||||||
|
Result[resi].Offset := o+i-1;
|
||||||
|
Result[resi].Length := 1;
|
||||||
|
Result[resi].Orig := Buf1[i];
|
||||||
|
Result[resi].New := Buf2[i];
|
||||||
|
Result[resi].Pre := Last10;
|
||||||
|
// Result[resi].Aft := Next10;
|
||||||
|
end;
|
||||||
|
lastinequal := true;
|
||||||
|
end else begin
|
||||||
|
if (lastinequal) then begin
|
||||||
|
Last10 := '';
|
||||||
|
resi := Length(Result)-1;
|
||||||
|
Log('Found '+IntToStr(Result[resi].Length)+' different Byte(s) at Offset 0x'+UpperCase(Dec2Hex(Result[resi].Offset)));
|
||||||
|
end;
|
||||||
|
lastinequal := false;
|
||||||
|
end;
|
||||||
|
if (Length(Last10)<PreAftLen) then Last10 := Last10 + Buf1[i] else Last10 := RightBStr(Last10, PreAftLen - 1) + Buf1[i];
|
||||||
|
end;
|
||||||
|
until (i1=0) OR (i2=0);
|
||||||
|
CloseFile(f1);
|
||||||
|
CloseFile(f2);
|
||||||
|
Log('>>> Found '+IntToStr(Length(Result))+' different areas.');
|
||||||
|
except
|
||||||
|
on e: Exception do Log('Exception: '+e.Message);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ChangeNewFile(g: string; m: TModRecA): boolean;
|
||||||
|
var f: file of char;
|
||||||
|
i,j: integer;
|
||||||
|
o, lo, mo: longint;
|
||||||
|
Last: AnsiString;
|
||||||
|
Buf: char;
|
||||||
|
foundit, missedany: boolean;
|
||||||
|
label NextTurn;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
missedany := false;
|
||||||
|
AssignFile(f, g);
|
||||||
|
FileMode := fmOpenReadWrite;
|
||||||
|
Reset(f);
|
||||||
|
Last := '';
|
||||||
|
o := Mods[0].Offset - PreAftSrc;
|
||||||
|
lo := 0;
|
||||||
|
if (o<0) then o := 0;
|
||||||
|
Seek(f,o);
|
||||||
|
for i:=0 to Length(Mods)-1 do begin
|
||||||
|
foundit := false;
|
||||||
|
NextTurn:
|
||||||
|
if (FPatcher.CheckExtSearch.Checked) then mo := FileSize(f) else mo := Mods[i].Offset+2*PreAftSrc;
|
||||||
|
while (FilePos(f)<mo) AND (NOT EOF(f)) do begin
|
||||||
|
BlockRead(f,Buf,1);
|
||||||
|
if (RightBStr(Last, Length(Mods[i].Pre)) = Mods[i].Pre) then begin
|
||||||
|
if (Buf = Mods[i].Orig[1]) then begin
|
||||||
|
Seek(f,FilePos(f)-1);
|
||||||
|
Log('Found pos at Offset 0x'+Dec2Hex(FilePos(f))+' - changing from '+Dec2Hex(Ord(Buf))+' to '+Dec2Hex(Ord(Mods[i].New[1])));
|
||||||
|
for j:=1 to Length(Mods[i].New) do begin
|
||||||
|
Read(f,Buf);
|
||||||
|
if (Buf=Mods[i].Orig[j]) then begin
|
||||||
|
foundit := true;
|
||||||
|
Seek(f,FilePos(f)-1);
|
||||||
|
Write(f,Mods[i].New[j]);
|
||||||
|
lo := FilePos(f);
|
||||||
|
end else Log('Bytes different at Offset 0x'+Dec2Hex(FilePos(f)));
|
||||||
|
end;
|
||||||
|
Break;
|
||||||
|
end else begin
|
||||||
|
foundit := false;
|
||||||
|
Log('Found pos, but different original first byte. Searching further...');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if (Length(Last)<PreAftLen) then Last := Last + Buf else Last := RightBStr(Last, PreAftLen-1) + Buf;
|
||||||
|
end;
|
||||||
|
if (NOT foundit) AND (Length(Mods[i].Pre)>2) then begin
|
||||||
|
Mods[i].Pre := RightBStr(Mods[i].Pre,Length(Mods[i].Pre)-1);
|
||||||
|
Log('Pre not found. Dropping one byte... (now '+IntToStr(Length(Mods[i].Pre))+' bytes)');
|
||||||
|
if (lo>0) then o := lo else o := Mods[i].Offset - PreAftSrc;
|
||||||
|
if (o<0) then o:=0;
|
||||||
|
Seek(f,o);
|
||||||
|
goto NextTurn;
|
||||||
|
end else if (NOT foundit) then begin
|
||||||
|
Log('Couldn''t find this mod. Trying next one...');
|
||||||
|
missedany := true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
CloseFile(f);
|
||||||
|
if (NOT missedany) then Result := true else Result := false;
|
||||||
|
except
|
||||||
|
on e: Exception do begin
|
||||||
|
Log('Exception: '+e.Message);
|
||||||
|
Result := falsE;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CheckFileSizes(g1,g2: string): boolean;
|
||||||
|
var f1,f2: file of char;
|
||||||
|
s1,s2: longint;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
AssignFile(f1,g1);
|
||||||
|
AssignFile(f2,g2);
|
||||||
|
FileMode := fmOpenRead;
|
||||||
|
Reset(f1);
|
||||||
|
Reset(f2);
|
||||||
|
s1 := FileSize(f1);
|
||||||
|
s2 := FileSize(f2);
|
||||||
|
CloseFile(f1);
|
||||||
|
CloseFile(f2);
|
||||||
|
if (s1=s2) then Result := true else Result := false;
|
||||||
|
except
|
||||||
|
on e: Exception do begin
|
||||||
|
Log('Exception: '+e.Message);
|
||||||
|
Result := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.ButBrowseOrigClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if (Length(ExtractFilePath(EditOrigFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditOrigFile.Text);
|
||||||
|
OpenDialog.Title := 'Select original file from old version';
|
||||||
|
if (OpenDialog.Execute) then begin
|
||||||
|
EditOrigFile.Text := OpenDialog.FileName;
|
||||||
|
Log('Original file: '+ExtractFilename(OpenDialog.FileName));
|
||||||
|
end else Log('Aborted OpenDialog. (Original file)');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.ButtExitClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Application.Terminate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.ButBrowseModClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if (Length(ExtractFilePath(EditModFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditModFile.Text);
|
||||||
|
OpenDialog.Title := 'Select modified file from old version';
|
||||||
|
if (OpenDialog.Execute) then begin
|
||||||
|
EditModFile.Text := OpenDialog.FileName;
|
||||||
|
Log('Original modified file: '+ExtractFilename(OpenDialog.FileName));
|
||||||
|
end else Log('Aborted OpenDialog. (Original mod file)');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.ButtBrowseNewClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if (Length(ExtractFilePath(EditNewFile.Text))>0) then OpenDialog.InitialDir := ExtractFilePath(EditNewFile.Text);
|
||||||
|
OpenDialog.Title := 'Select file with new version';
|
||||||
|
if (OpenDialog.Execute) then begin
|
||||||
|
EditNewFile.Text := OpenDialog.FileName;
|
||||||
|
Log('New version file: '+ExtractFilename(OpenDialog.FileName));
|
||||||
|
end else Log('Aborted OpenDialog. (New ver file)');
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Backup(f: string): boolean;
|
||||||
|
var t: string;
|
||||||
|
begin
|
||||||
|
t := ChangeFileExt(f,'.bak');
|
||||||
|
Log('Backup to: '+t);
|
||||||
|
if (FileExists(t)) then begin
|
||||||
|
Log('File exists! Let''s hope that this is an old backup of this file. Skipping backup.');
|
||||||
|
Result := true;
|
||||||
|
end else Result := CopyFile(PChar(f),PChar(t),true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.ButtSmartPatchClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if (ExtractFileName(EditOrigFile.Text)='') then begin
|
||||||
|
Log('ERROR! Please select the original file of the OLD version!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if (ExtractFileName(EditModFile.Text)='') then begin
|
||||||
|
Log('ERROR! Please select the modified file of the OLD version!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if (ExtractFileName(EditNewFile.Text)='') then begin
|
||||||
|
Log('ERROR! Please select the original file of the NEW version!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if (EditOrigFile.Text = EditModFile.Text) then begin
|
||||||
|
Log('ERROR! Please select different original files!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if (EditOrigFile.Text = EditNewFile.Text) OR (EditModFile.Text = EditNewFile.Text) then begin
|
||||||
|
Log('ERROR! New version file can''t be the same as old version file!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if (NOT CheckFileSizes(EditOrigFile.Text, EditModFile.Text)) then begin
|
||||||
|
Log('ERROR! File sizes of original files differ!');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Log('No errors until here. Start modification parsing...');
|
||||||
|
Mods := FindModsInFiles(EditOrigFile.Text, EditModFile.Text);
|
||||||
|
Log('Done finding differences in original fileset.');
|
||||||
|
if (CheckBackup.Checked) then begin
|
||||||
|
if (Backup(EditNewFile.Text)) then begin
|
||||||
|
Log('Backup done.');
|
||||||
|
end else begin
|
||||||
|
Log('ERROR! Could not backup file. Aborting...');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end else Log('Skipping backup of new file.');
|
||||||
|
if (ChangeNewFile(EditNewFile.Text, Mods)) then begin
|
||||||
|
Log('Done making changes to new file. File should work now!');
|
||||||
|
end else begin
|
||||||
|
Log('ERROR! Could not apply all changes to new file.');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPatcher.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Log('Welcome to SmartPatcher by riddick');
|
||||||
|
Log('');
|
||||||
|
Log('NOTE: You can damage your files - use this app wisely!');
|
||||||
|
Log(DupeString('-',140));
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
Reference in New Issue
Block a user