cheat-engine/Cheat Engine/frmExeTrainerGeneratorUnit.pas
2012-01-14 07:18:53 +00:00

547 lines
14 KiB
ObjectPascal

unit frmExeTrainerGeneratorUnit;
{$mode delphi}
interface
uses
windows, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, ExtCtrls,
dialogs, StdCtrls, ComCtrls, Menus, cefuncproc, IconStuff, zstream, registry;
type
TFileData=class
filepath: string;
filename: string;
folder: string;
end;
{ TfrmExeTrainerGenerator }
TfrmExeTrainerGenerator = class(TForm)
Button1: TButton;
btnGenerateTrainer: TButton;
btnAddFile: TButton;
btnRemoveFile: TButton;
Button3: TButton;
cbKernelDebug: TCheckBox;
cbSpeedhack: TCheckBox;
cbVEHDebug: TCheckBox;
cbXMPlayer: TCheckBox;
comboCompression: TComboBox;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
GroupBox3: TGroupBox;
GroupBox4: TGroupBox;
Image1: TImage;
Label1: TLabel;
ListView1: TListView;
miEditFolder: TMenuItem;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
pmFiles: TPopupMenu;
cbTiny: TRadioButton;
cbGigantic: TRadioButton;
rb32: TRadioButton;
rb64: TRadioButton;
SelectDirectoryDialog1: TSelectDirectoryDialog;
procedure btnAddFileClick(Sender: TObject);
procedure btnRemoveFileClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure btnGenerateTrainerClick(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure cbTrainersizeChange(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormCreate(Sender: TObject);
procedure ListView1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
procedure ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
procedure miEditFolderClick(Sender: TObject);
procedure pmFilesPopup(Sender: TObject);
private
{ private declarations }
saving: boolean;
archive: Tcompressionstream;
_archive: TMemoryStream;
updatehandle: thandle;
procedure addFile(filename: string; folder: string='');
public
{ public declarations }
filename: string;
procedure addFiletoList(fn: string);
procedure addDirToList(dir: string);
end;
var
frmExeTrainerGenerator: TfrmExeTrainerGenerator;
implementation
{ TfrmExeTrainerGenerator }
uses MainUnit,ceguicomponents, opensave;
resourcestring
rsSaving = 'Saving...';
rsGenerate = 'Generate';
rsFailureOnWriting = 'failure on writing';
rsIconUpdateError = 'icon update error';
rsFailureOpeningTheTrainerForResourceUpdates = 'Failure opening the trainer '
+'for resource updates. Make sure you do not watch the creation';
rsTheTrainerHasBeenSuccessfullyGenerated = 'The trainer has been '
+'successfully generated';
rsNone = 'None';
rsFastest = 'Fastest';
rsDefault = 'Default';
rsMax = 'Max';
rsNewFoldername = 'New foldername';
rsCETrainerMaker = 'CE trainer maker';
procedure TfrmExeTrainerGenerator.FormActivate(Sender: TObject);
begin
end;
var roti: integer;
function rot: string;
begin
roti:=(roti+1) mod 8;
case roti of
0: result:='-';
1: result:='\';
2: result:='|';
3: result:='/';
4: result:='-';
5: result:='\';
6: result:='|';
7: result:='/';
end;
end;
procedure TfrmExeTrainerGenerator.addFile(filename: string; folder: string='');
var
f: tmemorystream;
currentfile: string;
size: dword;
i: qword;
block: integer;
begin
f:=TMemoryStream.create;
try
f.LoadFromFile(filename);
f.position:=0;
size:=f.size;
//write the filename
currentfile:=extractfilename(filename);
size:=length(currentfile);
archive.write(size, sizeof(size));
archive.write(currentfile[1], size);
//write the relative folder
size:=length(folder);
archive.write(size, sizeof(size));
archive.write(folder[1], size);
//write the size, and the file itself
size:=f.size;
archive.Write(size, sizeof(size));
i:=f.size;
while i>0 do
begin
block:=min(256*1024, i);
archive.CopyFrom(f, block);
dec(i,block);
btnGenerateTrainer.caption:=rsSaving+rot;
application.ProcessMessages;
end;
finally
f.free;
btnGenerateTrainer.caption:=rsGenerate;
end;
end;
procedure TfrmExeTrainerGenerator.btnGenerateTrainerClick(Sender: TObject);
var DECOMPRESSOR: TMemorystream;
CETRAINER: string;
icon: tmemorystream;
z: ticon;
ii: PICONDIR;
gii: PGRPICONDIR absolute ii;
compression: Tcompressionlevel;
i: integer;
tiny: boolean;
basefile: string;
begin
tiny:=cbTiny.Checked;
CETRAINER:=ExtractFilePath(filename)+'CET_TRAINER.CETRAINER';
SaveTable(CETRAINER, true);
btnGenerateTrainer.caption:=rsSaving+rot;
btnGenerateTrainer.enabled:=false;
saving:=true;
application.ProcessMessages;
try
if tiny then basefile:='tiny' else basefile:='standalonephase1';
if CopyFile(cheatenginedir+basefile+'.dat', filename) then
begin
updatehandle:=BeginUpdateResourceA(pchar(filename), false);
if updatehandle<>0 then
begin
_archive:=TMemorystream.create; //create the archive
if not tiny then
begin
//all files go into a compressed archive
case comboCompression.itemindex of
0: compression:=clnone;
1: compression:=clfastest;
2: compression:=cldefault;
3: compression:=clmax;
end;
archive:=Tcompressionstream.create(compression, _archive, true);
decompressor:=TMemorystream.create;
decompressor.LoadFromFile(cheatenginedir+'standalonephase2.dat');
addfile(CETRAINER);
deletefile(cetrainer);
for i:=0 to listview1.Items.Count-1 do
addfile(TFileData(listview1.items[i].data).filepath, TFileData(listview1.items[i].data).folder);
addfile(cheatenginedir+'defines.lua');
if rb32.checked then
begin
addfile(cheatenginedir+'cheatengine-i386.exe');
addfile(cheatenginedir+'lua5.1-32.dll');
addfile(cheatenginedir+'win32\dbghelp.dll','win32');
if cbSpeedhack.checked then
addfile(cheatenginedir+'speedhack-i386.dll');
if cbvehdebug.checked then
addfile(cheatenginedir+'vehdebug-i386.dll');
if cbKernelDebug.checked then
addfile(cheatenginedir+'dbk32.sys');
end
else
begin
addfile(cheatenginedir+'cheatengine-x86_64.exe');
addfile(cheatenginedir+'lua5.1-64.dll');
if cbSpeedhack.checked then
addfile(cheatenginedir+'speedhack-x86_64.dll');
if cbvehdebug.checked then
addfile(cheatenginedir+'vehdebug-x86_64.dll');
if cbKernelDebug.checked then
addfile(cheatenginedir+'dbk64.sys');
end;
if cbXMPlayer.checked then
addfile(cheatenginedir+'xmplayer.exe');
archive.free;
end
else
_archive.LoadFromFile(CETRAINER); //tiny version has the .cetrainer only
if not UpdateResourceA(updatehandle, RT_RCDATA, 'ARCHIVE', 0, _archive.memory, _archive.size) then
raise exception.create(rsFailureOnWriting+' ARCHIVE:'+inttostr(
getlasterror()));
if not tiny then
begin
//tiny has no decompressor
if not UpdateResourceA(updatehandle, RT_RCDATA, 'DECOMPRESSOR', 0, decompressor.memory, decompressor.size) then
raise exception.create(rsFailureOnWriting+' DECOMPRESSOR:'+inttostr(
getlasterror()));
end;
icon:=tmemorystream.create;
try
image1.picture.icon.SaveToStream(icon);
// sizeof(TBitmapInfoHeader)
//GetIconInfo();
z:=TIcon.create;
// z.LoadFromFile('F:\svn\favicon.ico');
//z.SaveToStream(icon);
ii:=icon.memory;
if ii.idType=1 then
begin
if ii.idCount>0 then
begin
//update the icon
if not updateResourceA(updatehandle,pchar(RT_ICON),MAKEINTRESOURCE(1),1033, pointer(ptruint(icon.Memory)+ii.icondirentry[0].dwImageOffset), ii.icondirentry[0].dwBytesInRes) then
raise exception.create(rsIconUpdateError+' 2');
//update the group
gii.idCount:=1;
gii.icondirentry[0].id:=1;
if not updateResourceA(updatehandle,pchar(RT_GROUP_ICON),MAKEINTRESOURCE(101),1033, gii, sizeof(TGRPICONDIR)+sizeof(TGRPICONDIRENTRY)) then
raise exception.create(rsIconUpdateError+' 3');
end;
end;
finally
icon.free;
end;
EndUpdateResource(updatehandle, false);
end else raise exception.create(
rsFailureOpeningTheTrainerForResourceUpdates);
end;
showmessage(rsTheTrainerHasBeenSuccessfullyGenerated);
finally
if _archive<>nil then
freeandnil(_archive);
saving:=false;
btnGenerateTrainer.enabled:=true;
end;
end;
procedure TfrmExeTrainerGenerator.addDirToList(dir: string);
var dirinfo: TSearchRec;
r: integer;
begin
ZeroMemory(@DirInfo,sizeof(TSearchRec));
while dir[length(dir)]=pathdelim do //cut of \
dir:=copy(dir,1,length(dir)-1);
r := FindFirst(dir + pathdelim+'*.*', FaAnyfile, DirInfo);
while (r = 0) do
begin
if (DirInfo.Attr and FaVolumeId <> FaVolumeID) then
begin
if ((DirInfo.Attr and FaDirectory) <> FaDirectory) then
addFiletoList(dir + pathdelim + DirInfo.Name)
else
begin
if (DirInfo.Name[1]<>'.') then
addDirToList(dir + pathdelim + DirInfo.Name);
end;
end;
r := FindNext(DirInfo);
end;
FindClose(DirInfo);
end;
procedure TfrmExeTrainerGenerator.addFiletoList(fn: string);
var f: TFiledata;
d: string;
li: TListItem;
begin
f:=tfiledata.create;
f.filepath:=fn;
f.filename:=extractfilename(fn);
d:=ExtractFilePath(fn);
d:=ExtractRelativepath(cheatenginedir, d);
if (pos(':', d)>0) or (pos('..', d)>0) then
d:='';
f.folder:=d;
li:=listview1.Items.Add;
li.caption:=f.filename;
li.SubItems.Add(d);
li.Data:=f;
end;
procedure TfrmExeTrainerGenerator.Button3Click(Sender: TObject);
begin
if SelectDirectoryDialog1.Execute then
addDirToList(SelectDirectoryDialog1.FileName);
end;
procedure TfrmExeTrainerGenerator.cbTrainersizeChange(Sender: TObject);
begin
groupbox1.enabled:=cbGigantic.checked;
GroupBox2.enabled:=cbGigantic.checked;
rb32.enabled:=cbGigantic.Checked;
rb64.enabled:=cbGigantic.checked;
cbSpeedhack.enabled:=cbGigantic.Checked;
cbVEHDebug.enabled:=cbGigantic.checked;
cbXMPlayer.Enabled:=cbGigantic.checked;
cbKernelDebug.enabled:=cbGigantic.Checked;
label1.enabled:=cbGigantic.checked;
comboCompression.enabled:=cbGigantic.checked;
GroupBox3.enabled:=cbGigantic.checked;
ListView1.enabled:=cbGigantic.checked;
Button3.enabled:=cbGigantic.checked;
btnAddFile.enabled:=cbGigantic.checked;
btnRemoveFile.enabled:=listview1.Selected<>nil;
end;
procedure TfrmExeTrainerGenerator.Button1Click(Sender: TObject);
begin
image1.picture.icon:=pickIcon;
end;
procedure TfrmExeTrainerGenerator.btnAddFileClick(Sender: TObject);
var i: integer;
begin
if opendialog1.execute then
begin
for i:=0 to opendialog1.Files.count-1 do
addFileToList(opendialog1.Files[i]);
end;
end;
procedure TfrmExeTrainerGenerator.btnRemoveFileClick(Sender: TObject);
var i: integer;
begin
i:=0;
while i<listview1.items.count do
begin
if listview1.Items[i].Selected then
begin
TFileData(listview1.items[i].data).free;
listview1.items.Delete(i);
end
else
inc(i);
end;
end;
procedure TfrmExeTrainerGenerator.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var i: integer;
begin
closeaction:=cafree;
frmExeTrainerGenerator:=nil;
for i:=0 to ListView1.Items.Count-1 do
TFiledata(listview1.items[i].Data).free;
end;
procedure TfrmExeTrainerGenerator.FormCloseQuery(Sender: TObject;
var CanClose: boolean);
begin
canclose:=not saving;
end;
procedure TfrmExeTrainerGenerator.FormCreate(Sender: TObject);
var s: string;
i: integer;
begin
comboCompression.Items.Clear;
with comboCompression.Items do
begin
add(rsNone);
add(rsFastest);
add(rsDefault);
add(rsMax);
end;
comboCompression.itemindex:=3;
OpenDialog1.InitialDir:=CheatEngineDir;
SelectDirectoryDialog1.InitialDir:=CheatEngineDir;
//scan the current script for markers that might indicate a used feature
s:=lowercase(mainform.frmLuaTableScript.assemblescreen.Text);
cbSpeedhack.checked:=pos('speedhack_',s)>0;
cbXMPlayer.checked:=pos('xmplayer_',s)>0;
cbKernelDebug.checked:=pos('dbk_',s)>0;
if mainform.LuaForms.count=1 then //if there is only one form use that icon as default
image1.Picture.Icon:=TCEForm(mainform.LuaForms[0]).icon
else //else check if there is a TRAINERFORM
for i:=0 to mainform.LuaForms.count-1 do
if TCEForm(mainform.LuaForms[i]).Name='TRAINERFORM' then
begin
//use the icon from this form
image1.Picture.Icon:=TCEForm(mainform.LuaForms[i]).icon;
break;
end;
end;
procedure TfrmExeTrainerGenerator.ListView1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
begin
end;
procedure TfrmExeTrainerGenerator.ListView1SelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
begin
btnRemoveFile.enabled:=listview1.Selected<>nil;
end;
procedure TfrmExeTrainerGenerator.miEditFolderClick(Sender: TObject);
var z: TFiledata;
begin
if listview1.Selected<>nil then
begin
z:=TFiledata(listview1.Selected.data);
InputQuery(rsNewFoldername, rsCETrainerMaker, z.folder);
listview1.Selected.SubItems[0]:=z.folder;
end;
end;
procedure TfrmExeTrainerGenerator.pmFilesPopup(Sender: TObject);
begin
miEditFolder.enabled:=ListView1.Selected<>nil;
end;
initialization
{$I frmExeTrainerGeneratorUnit.lrs}
end.