amxmodx/installer/installer/UnitfrmMain.pas

1027 lines
34 KiB
ObjectPascal
Executable File

unit UnitfrmMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, mxFlatControls, JvPageList,
ExtCtrls, JvExControls, JvComponent, TFlatButtonUnit, jpeg, TFlatEditUnit,
TFlatGaugeUnit, ImgList, FileCtrl, Registry, CheckLst, TFlatComboBoxUnit,
TFlatCheckBoxUnit, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdFTP, IdException, IdAntiFreezeBase, IdAntiFreeze,
IdIntercept, IdLogBase, IdLogFile, JclFileUtils, TFlatRadioButtonUnit;
type
TfrmMain = class(TForm)
jplWizard: TJvPageList;
jspWelcome: TJvStandardPage;
pnlButtons: TPanel;
bvlSpace: TBevel;
cmdNext: TFlatButton;
cmdCancel: TFlatButton;
imgInstall: TImage;
lblWelcome: TLabel;
lblInfo1: TLabel;
lblInfo2: TLabel;
lblInfo3: TLabel;
jspLicense: TJvStandardPage;
pnlLicense: TPanel;
imgIcon1: TImage;
lblTitle1: TLabel;
lblSubTitle1: TLabel;
freLicense: TmxFlatRichEdit;
frbAgree: TFlatRadioButton;
ftbDontAgree: TFlatRadioButton;
jspInstallMethod: TJvStandardPage;
pnlHeader2: TPanel;
imgIcon2: TImage;
lblTitle2: TLabel;
lblSubTitle2: TLabel;
cmdBack: TFlatButton;
jspFTP: TJvStandardPage;
pnlHeader3: TPanel;
imgIcon3: TImage;
lblTitle3: TLabel;
lblSubTitle3: TLabel;
lblStep1: TLabel;
pnlFTPData: TPanel;
lblHost: TLabel;
txtHost: TFlatEdit;
lblUserName: TLabel;
txtUserName: TFlatEdit;
txtPassword: TFlatEdit;
lblPassword: TLabel;
txtPort: TFlatEdit;
lblPort: TLabel;
lblStep2: TLabel;
cmdConnect: TFlatButton;
pnlDirectory: TPanel;
trvDirectories: TTreeView;
jspInstallProgress: TJvStandardPage;
pnlHeader5: TPanel;
imgIcon5: TImage;
lblTitle5: TLabel;
lblSubTitle5: TLabel;
ggeAll: TFlatGauge;
lblProgress: TLabel;
ggeItem: TFlatGauge;
rtfDetails: TmxFlatRichEdit;
lblDetails: TLabel;
bvlSpace2: TBevel;
ilImages: TImageList;
bvlSpacer1: TBevel;
bvlSpacer2: TBevel;
bvlSpacer3: TBevel;
bvlSpacer5: TBevel;
jspSelectMod: TJvStandardPage;
pnlSelectMod: TPanel;
imgIcon6: TImage;
lblSelectMod: TLabel;
lblSelectModInfo: TLabel;
bvlSelectMod: TBevel;
lblInfo: TLabel;
chkPassive: TFlatCheckBox;
IdFTP: TIdFTP;
cmdProxySettings: TFlatButton;
IdAntiFreeze: TIdAntiFreeze;
lblStep4: TLabel;
cboGameAddon: TFlatComboBox;
tmrSpeed: TTimer;
IdLogFile: TIdLogFile;
lblInfo4: TLabel;
trvMods: TTreeView;
lblRemoteInstallation: TLabel;
lblRemoteHint: TLabel;
pnlRemote: TPanel;
frbFTP: TFlatRadioButton;
lblLocalHint: TLabel;
lblLocalInstallation: TLabel;
lblLocalHintItalic: TLabel;
pnlLocal: TPanel;
frbDedicatedServer: TFlatRadioButton;
frbListenServer: TFlatRadioButton;
frbStandaloneServer: TFlatRadioButton;
frbSelectMod: TFlatRadioButton;
shpMods: TShape;
lblSelectModNote: TLabel;
lblStep3: TLabel;
pnlOS: TPanel;
optWindows: TFlatRadioButton;
optLinux: TFlatRadioButton;
lblStep5: TLabel;
lblFTP: TLabel;
optMac: TFlatRadioButton;
procedure jvwStepsCancelButtonClick(Sender: TObject);
procedure cmdCancelClick(Sender: TObject);
procedure cmdNextClick(Sender: TObject);
procedure CheckNext(Sender: TObject);
procedure cmdBackClick(Sender: TObject);
procedure cmdConnectClick(Sender: TObject);
procedure jplWizardChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure cmdProxySettingsClick(Sender: TObject);
procedure txtPortChange(Sender: TObject);
procedure trvDirectoriesExpanded(Sender: TObject; Node: TTreeNode);
procedure FormDestroy(Sender: TObject);
procedure IdFTPWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure tmrSpeedTimer(Sender: TObject);
procedure trvDirectoriesExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
procedure trvDirectoriesCollapsing(Sender: TObject; Node: TTreeNode;
var AllowCollapse: Boolean);
procedure jspFTPShow(Sender: TObject);
procedure frbFTPClick(Sender: TObject);
procedure frbLocalClick(Sender: TObject);
procedure trvModsClick(Sender: TObject);
procedure trvDirectoriesMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure trvDirectoriesChange(Sender: TObject; Node: TTreeNode);
private
OldProgress: Integer;
CurrProgress: Integer;
public
procedure ExceptionHandler(Sender: TObject; E: Exception);
end;
var
frmMain: TfrmMain;
gMultiAccount: Boolean;
const VERSION = '1.8.2';
implementation
uses UnitFunctions, UnitScanMods, UnitfrmProxy, UnitInstall,
UnitSelectModPath;
{$R *.dfm}
procedure TfrmMain.jvwStepsCancelButtonClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.cmdCancelClick(Sender: TObject);
begin
if (jplWizard.ActivePage = jspFTP) and (cmdConnect.Caption = 'Connecting...') then begin
Screen.Cursor := crDefault;
Cancel := True;
try
IdFTP.Disconnect;
except
// oh, hello BAILOPAN!
end;
cmdCancel.Caption := 'Close';
end
else if (jplWizard.ActivePage = jspInstallProgress) then begin
if Cancel then
Close
else if MessageBox(Handle, 'Do you really want to cancel the installation?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then begin
Screen.Cursor := crDefault;
Application.OnException := ExceptionHandler;
Cancel := True;
if IdFTP.Connected then
IdFTP.Quit;
end;
cmdCancel.Caption := 'Close';
end
else
Close;
end;
procedure TfrmMain.cmdNextClick(Sender: TObject);
var ePath: String;
eRegistry: TRegistry;
ChosenMod: TMod;
eStr: TStringList;
CurNode: TTreeNode;
eOS: TOS;
i, k: integer;
begin
if jplWizard.ActivePage = jspFTP then begin
Screen.Cursor := crHourGlass;
try
if not IdFTP.Connected then
IdFTP.Connect;
except
MessageBox(Handle, 'Cannot connect to server. Please check your connection and try again.', 'Error', MB_ICONWARNING);
Screen.Cursor := crDefault;
exit;
end;
{ FTP }
eStr := TStringList.Create;
ePath := '/';
CurNode := trvDirectories.Selected;
if (Assigned(CurNode)) then begin
repeat
ePath := '/' + CurNode.Text + ePath;
CurNode := CurNode.Parent;
until (not Assigned(CurNode));
end;
try
IdFTP.ChangeDir(ePath);
except
MessageBox(Handle, PChar('Cannot change directory to "' + ePath + '". Please check your settings and try again.'), 'Error', MB_ICONWARNING);
Screen.Cursor := crDefault;
exit;
end;
try
IdFTP.List(eStr, '', False);
except
// worst "exception" ever. bad indy!
end;
if eStr.IndexOf('liblist.gam') = -1 then begin
MessageBox(Handle, 'Invalid directory. Please select your mod directory and try again.', PChar(Application.Title), MB_ICONWARNING);
eStr.Free;
Screen.Cursor := crDefault;
exit;
end
else
eStr.Free;
// design stuff
trvDirectories.Enabled := False;
cmdConnect.Enabled := False;
optWindows.Enabled := False;
optLinux.Enabled := False;
optMac.Enabled := False;
cboGameAddon.Enabled := False;
// preinstall...
MakeDir(ExtractFilePath(Application.ExeName) + 'temp');
DownloadFile('liblist.gam', ExtractFilePath(Application.ExeName) + 'temp\liblist.gam');
try
IdFTP.ChangeDir(ePath + 'addons/metamod/');
ForceDirectories(ExtractFilePath(Application.ExeName) + 'temp\addons\metamod\');
DownloadFile('plugins.ini', ExtractFilePath(Application.ExeName) + 'temp\addons\metamod\plugins.ini');
except
try
IdFTP.ChangeDir(ePath);
except
MessageBox(Handle, PChar('Cannot change directory to "' + ePath + '". Please check your settings and try again.'), 'Error', MB_ICONWARNING);
Screen.Cursor := crDefault;
exit;
end;
end;
ChosenMod := modNone;
case cboGameAddon.ItemIndex of
1: ChosenMod := modCS;
2: ChosenMod := modDoD;
3: ChosenMod := modNS;
4: ChosenMod := modTFC;
5: ChosenMod := modTS;
6: ChosenMod := modCS;
7: ChosenMod := modESF;
end;
if optWindows.Checked then
eOS := osWindows
else if optLinux.Checked then
eOS := osLinux
else
eOS := osMac;
jspInstallProgress.Show;
frmMain.Height := 382;
rtfDetails.Lines.Text := 'Starting Pre-Installation, this may take a few minutes...';
rtfDetails.Lines.Add('');
Sleep(1500);
ggeAll.Progress := 0;
ggeItem.Progress := 0;
cmdNext.Hide;
InstallCustom(ExtractFilePath(Application.ExeName) + 'temp\', ChosenMod, eOS);
if Cancel then
exit;
AddStatus('', clBlack, False);
AddStatus('', clBlack, False);
AddStatus('- - - - -', clBlack, False);
AddStatus('Uploading all files...', clBlack, False);
AddStatus('', clBlack, False);
Sleep(1500);
// ... then upload ...
ggeAll.Progress := 0;
ggeItem.Progress := 0;
InstallFTP(ChosenMod, eOS);
end
else if jplWizard.ActivePage = jspInstallProgress then
Close
else if jplWizard.ActivePage = jspSelectMod then begin
{ Dedicated Server }
if (frbDedicatedServer.Checked) or (frbStandaloneServer.Checked) then begin
jspInstallProgress.Show;
ChosenMod := modNone;
ePath := LowerCase(GetModPathName(trvMods.Selected.Text));
if gMultiAccount then
SteamPath := GetSteamAppsDir + trvMods.Selected.Parent.Text + '\dedicated server\'; // setting this path for a user with only one account is not necessary
// ask for additional mods...
if (ePath = 'cstrike') or (ePath = 'czero') then begin
if MessageBox(Handle, 'Install Counter-Strike addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modCS;
end;
if ePath = 'dod' then begin
if MessageBox(Handle, 'Install Day of Defeat addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modDoD;
end;
if ePath = 'ns' then begin
if MessageBox(Handle, 'Install Natural Selection addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modNS;
end;
if ePath = 'tfc' then begin
if MessageBox(Handle, 'Install Team Fortress Classic addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modTFC;
end;
if ePath = 'ts' then begin
if MessageBox(Handle, 'Install The Specialists addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modTS;
end;
if ePath = 'esf' then begin
if MessageBox(Handle, 'Install Earth''s Special Forces addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modESF;
end;
// install it
if frbDedicatedServer.Checked then begin
if DirectoryExists(SteamPath + ePath) then
InstallDedicated(SteamPath + ePath + '\', ChosenMod, True)
else begin
MessageBox(Handle, 'Error: The directory of the mod you selected doesn''t exist any more. Run Dedicated Server with the chosen mod and try again.', PChar(Application.Title), MB_ICONERROR);
Application.Terminate;
exit;
end;
end
else begin
if DirectoryExists(StandaloneServer + ePath) then
InstallDedicated(StandaloneServer + ePath + '\', ChosenMod, False)
else begin
MessageBox(Handle, 'Error: The directory of the mod you selected doesn''t exist (any more). Run Half-Life Dedicated Server with the chosen mod again and restart.', PChar(Application.Title), MB_ICONERROR);
Application.Terminate;
exit;
end;
end;
end;
{ Listen Server }
if frbListenServer.Checked then begin
ChosenMod := modNone;
if gMultiAccount then
SteamPath := GetSteamAppsDir + trvMods.Selected.Parent.Text + '\'; // setting this path for a user with only one account is not necessary
ePath := trvMods.Selected.Text;
if DirectoryExists(SteamPath + ePath + '\' + GetModPathName(ePath)) then
ePath := SteamPath + ePath + '\' + GetModPathName(ePath)
else if DirectoryExists(SteamPath + 'half-life\' + ePath) then
ePath := SteamPath + 'half-life\' + ePath
else if DirectoryExists(SteamPath + 'half-life\' + GetModPathName(ePath)) then
ePath := SteamPath + 'half-life\' + GetModPathName(ePath)
else if DirectoryExists(SteamPath + GetModPathName(ePath)) then
ePath := SteamPath + GetModPathName(ePath);
if Pos(SteamPath, ePath) = 0 then
MessageBox(Handle, 'An error occured. Please report this bug to the AMX Mod X team and post a new thread on the forums of www.amxmodx.org.', PChar(Application.Title), MB_ICONSTOP)
else begin
ePath := LowerCase(ePath); // fixes case-sensivity bug
if not FileExists(ePath + '\liblist.gam') then begin
// added for HLDM
if FileExists(ExtractFilePath(ePath) + 'liblist.gam') then
ePath := ExtractFilePath(ePath)
else begin
MessageBox(Handle, 'You have to play this game once before installing AMX Mod X. Do that and try again.', PChar(Application.Title), MB_ICONWARNING);
exit;
end;
end;
jspInstallProgress.Show;
if (Pos('\cstrike', ePath) <> Pos('\counter-strike', ePath)) or (Pos('\condition zero', ePath) <> Pos('czero', ePath)) then begin // Counter-Strike & Condition Zero
if MessageBox(Handle, 'Install Counter-Strike addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modCS;
end
else if Pos('\day of defeat', ePath) <> Pos('\dod', ePath) then begin // Day of Defeat
if MessageBox(Handle, 'Install Day of Defeat addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modDoD;
end
else if Pos('\team fortress classic', ePath) <> Pos('\tfc', ePath) then begin // Team Fortress Classic
if MessageBox(Handle, 'Install Team Fortress Classic addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modTFC;
end
else if Pos('half-life\ts', ePath) <> 0 then begin // The Specialists
if MessageBox(Handle, 'Install The Specialists addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modTS;
end
else if Pos('half-life\ns', ePath) <> 0 then begin // Natural Selection
if MessageBox(Handle, 'Install Natural Selection addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modNS;
end
else if Pos('half-life\esf', ePath) <> 0 then begin // Natural Selection
if MessageBox(Handle, 'Install Earth''s Special Forces addon?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then
ChosenMod := modESF;
end;
ePath := ePath + '\';
InstallListen(ePath, ChosenMod);
end;
end;
{ Custom mod below }
end
else if jplWizard.ActivePage <> jspInstallMethod then
jplWizard.NextPage
else begin
if frbDedicatedServer.Checked then begin // Dedicated Server
ePath := GetSteamAppsDir;
if ePath = '' then
MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING)
else begin
trvMods.Items.Clear;
with GetSteamAccounts do begin
if Count = 1 then begin
gMultiAccount := False;
SteamPath := ePath + Strings[0] + '\dedicated server\';
eStr := GetAllMods(SteamPath, False);
for i := 0 to eStr.Count -1 do
trvMods.Items.Add(nil, eStr[i]);
eStr.Free;
end
else begin
gMultiAccount := True;
for i := 0 to Count -1 do begin
SteamPath := ePath + Strings[i] + '\dedicated server\';
if DirectoryExists(SteamPath) then begin
eStr := GetAllMods(SteamPath, False);
if eStr.Count <> 0 then begin
CurNode := trvMods.Items.Add(nil, Strings[i]);
for k := 0 to eStr.Count -1 do
trvMods.Items.AddChild(CurNode, eStr[k]);
eStr.Free;
CurNode.Expand(False);
end;
end;
end;
end;
Free;
end;
if trvMods.Items.Count = 0 then
MessageBox(Handle, 'You haven''t used dedicated server yet. Please start it once before installing AMX Mod X.', 'Error', MB_ICONERROR)
else begin
jspSelectMod.Show;
trvMods.Selected := nil;
cmdNext.Enabled := False;
end;
end;
end
else if frbListenServer.Checked then begin // Listen Server
ePath := GetSteamAppsDir;
if ePath = '' then
MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING)
else begin
trvMods.Items.Clear;
with GetSteamAccounts do begin
if Count = 1 then begin
gMultiAccount := False;
SteamPath := ePath + Strings[0] + '\';
eStr := GetAllMods(SteamPath, True);
for i := 0 to eStr.Count -1 do
trvMods.Items.Add(nil, eStr[i]);
eStr.Free;
if DirectoryExists(SteamPath + 'half-life') then begin
eStr := GetAllMods(SteamPath + 'half-life\', False);
for i := 0 to eStr.Count -1 do
trvMods.Items.Add(nil, eStr[i]);
eStr.Free;
end;
end
else begin
gMultiAccount := True;
for i := 0 to Count -1 do begin
SteamPath := ePath + Strings[i] + '\';
if DirectoryExists(SteamPath) then begin
eStr := GetAllMods(SteamPath, False);
CurNode := trvMods.Items.Add(nil, Strings[i]);
for k := 0 to eStr.Count -1 do
trvMods.Items.AddChild(CurNode, eStr[k]);
eStr.Free;
CurNode.Expand(False);
if DirectoryExists(SteamPath + 'half-life') then begin
eStr := GetAllMods(SteamPath + 'half-life', False);
for k := 0 to eStr.Count -1 do
trvMods.Items.AddChild(CurNode, eStr[k]);
eStr.Free;
end;
if CurNode.Count = 0 then
CurNode.Free;
end;
end;
end;
Free;
end;
if trvMods.Items.Count = 0 then
MessageBox(Handle, 'You haven''t installed any Steam games yet. It is necessary to do that if you want to install AMX Mod X on a listen server.', 'Error', MB_ICONERROR)
else begin
jspSelectMod.Show;
trvMods.Selected := nil;
cmdNext.Enabled := False;
end;
end;
end
else if frbStandaloneServer.Checked then begin // Standalone Server
eRegistry := TRegistry.Create;
try
eRegistry.RootKey := HKEY_CURRENT_USER;
if eRegistry.OpenKey('Software\Valve\HLServer', False) then begin
StandaloneServer := IncludeTrailingPathDelimiter(eRegistry.ReadString('InstallPath'));
if DirectoryExists(StandaloneServer) then begin
with GetAllMods(StandaloneServer, False) do begin
gMultiAccount := False;
for i := 0 to Count -1 do
trvMods.Items.Add(nil, Strings[i]);
end;
jspSelectMod.Show;
end
else
MessageBox(Handle, 'You haven''t installed Half-Life Dedicated Server yet!', 'Error', MB_ICONWARNING);
end
else
MessageBox(Handle, 'You haven''t installed Half-Life Dedicated Server yet!', 'Error', MB_ICONWARNING);
finally
eRegistry.Free;
end;
end
else if frbSelectMod.Checked then begin
{ Custom mod }
if frmSelectModPath.ShowModal = mrOk then begin
jspInstallProgress.Show;
ChosenMod := modNone;
case frmSelectModPath.cboGameAddon.ItemIndex of
1: ChosenMod := modCS;
2: ChosenMod := modDoD;
3: ChosenMod := modNS;
4: ChosenMod := modTFC;
5: ChosenMod := modTS;
6: ChosenMod := modCS;
7: ChosenMod := modESF;
end;
InstallCustom(frmSelectModPath.trvDirectory.SelectedFolder.PathName + '\', ChosenMod, osWindows);
end;
end
else if frbFTP.Checked then begin // FTP
frmMain.Height := 421;
jspFTP.Show;
end;
end;
end;
procedure TfrmMain.CheckNext(Sender: TObject);
begin
cmdNext.Enabled := frbAgree.Checked;
end;
procedure TfrmMain.cmdBackClick(Sender: TObject);
begin
if jplWizard.ActivePage = jspFTP then begin
frmMain.Height := 382;
jspInstallMethod.Show;
end
else begin
jplWizard.PrevPage;
cmdBack.Visible := jplWizard.ActivePageIndex <> 0;
end;
end;
procedure TfrmMain.cmdConnectClick(Sender: TObject);
var i: integer;
eStr: TStringList;
CurNode, HomeNode, OldNode: TTreeNode;
Path: String;
begin
if (Trim(txtHost.Text) = '') or (Trim(txtUsername.Text) = '') then
MessageBox(Handle, 'Please fill in each field!', PChar(Application.Title), MB_ICONWARNING)
else if cmdConnect.Caption = 'Connect' then begin
// ... design stuff ...
Screen.Cursor := crHourGlass;
cmdConnect.Enabled := False;
cmdProxySettings.Enabled := False;
txtHost.Enabled := False;
txtPort.Enabled := False;
txtUsername.Enabled := False;
txtPassword.Enabled := False;
chkPassive.Enabled := False;
cmdConnect.Caption := 'Connecting...';
cmdCancel.Caption := '&Cancel';
// ... set values ...
IdFTP.Host := txtHost.Text;
IdFTP.Port := StrToInt(txtPort.Text);
IdFTP.Username := txtUsername.Text;
IdFTP.Passive := chkPassive.Checked;
IdFTP.Password := txtPassword.Text;
// ... connect and check values etc ...
try
IdFTP.Connect(True, 15000);
// ... get initial directory ...
Path := IdFTP.RetrieveCurrentDir;
// ... "fix" path ...
eStr := TStringList.Create;
eStr.Text := StringReplace(Path, '/', #13, [rfReplaceAll]);
for i := eStr.Count -1 downto 0 do begin
if eStr[i] = '' then
eStr.Delete(i);
end;
if (Copy(Path, Length(Path) -1, 1) <> '/') then
Path := Path + '/';
// ... connect successful, change captions ...
trvDirectories.Enabled := True;
cmdConnect.Enabled := True;
cmdConnect.Caption := 'Disconnect';
cmdCancel.Caption := '&Close';
cmdNext.Enabled := True;
// ... change to / and create all the directories ...
HomeNode := nil;
try
if (Path <> '/') then
IdFTP.ChangeDir('/');
trvDirectories.Items.BeginUpdate;
with GetAllDirs do begin
for i := 0 to Count -1 do begin
CurNode := trvDirectories.Items.Add(nil, Strings[i]);
if (Pos('/' + CurNode.Text + '/', Path) = 0) then begin
trvDirectories.Items.AddChild(CurNode, 'Scanning...');
CurNode.Data := Pointer(2);
end
else begin
HomeNode := CurNode;
CurNode.Data := Pointer(1);
Repaint;
end;
end;
Free;
end;
trvDirectories.Items.EndUpdate;
trvDirectories.TopItem := HomeNode;
IdFTP.ChangeDir(Path);
except
trvDirectories.Items.EndUpdate;
if (IdFTP.Connected) then
IdFTP.ChangeDir(Path)
else
IdFTP.Connect;
end;
// ... find directories in start path ...
CurNode := HomeNode;
OldNode := nil;
for i := 1 to eStr.Count -1 do begin
if (Assigned(CurNode)) then begin
CurNode := trvDirectories.Items.AddChild(CurNode, eStr[i]);
if (Assigned(OldNode)) then
OldNode.Expand(False);
CurNode.Data := Pointer(1);
OldNode := CurNode;
end;
end;
if (Assigned(CurNode)) then begin
trvDirectories.Items.AddChild(CurNode, 'Scanning...');
CurNode.Data := Pointer(2);
end;
// ... expand home node ...
if (Assigned(HomeNode)) and (HomeNode <> CurNode) then begin
HomeNode.Data := Pointer(0);
trvDirectories.TopItem := HomeNode;
HomeNode.Expand(False);
HomeNode.Data := Pointer(1);
end;
eStr.Free;
// ... scan for directories in home dir ...
if Assigned(CurNode) then
CurNode.Expand(False);
trvDirectories.TopItem := HomeNode;
except
on E: Exception do begin
Screen.Cursor := crDefault;
// reset button properties
cmdConnect.Enabled := True;
txtHost.Enabled := True;
txtPort.Enabled := True;
txtUsername.Enabled := True;
txtPassword.Enabled := True;
chkPassive.Enabled := True;
cmdProxySettings.Enabled := True;
cmdNext.Enabled := False;
cmdConnect.Caption := 'Connect';
cmdCancel.Caption := '&Cancel';
if Cancel then begin
Cancel := False;
exit;
end;
// analyze messages
if Pos('Login incorrect.', E.Message) <> 0 then begin // login failed
MessageBox(Handle, 'Login incorrect. Check your FTP settings and try again.', PChar(Application.Title), MB_ICONWARNING);
txtUsername.SetFocus;
txtUsername.SelectAll;
end
else if Pos('Host not found.', E.Message) <> 0 then begin // host not found
MessageBox(Handle, 'The entered host couldn''t be found. Check your settings and try again.', PChar(Application.Title), MB_ICONWARNING);
txtHost.SetFocus;
txtHost.SelectAll;
end
else if Pos('Connection refused.', E.Message) <> 0 then begin // wrong port (?)
MessageBox(Handle, 'The host refused the connection. Check your port and try again.', PChar(Application.Title), MB_ICONWARNING);
txtPort.SetFocus;
txtPort.SelectAll;
end
else if E is EIdProtocolReplyError then begin // wrong port
MessageBox(Handle, 'The port you entered is definitely wrong. Check it and try again.', PChar(Application.Title), MB_ICONWARNING);
txtPort.SetFocus;
txtPort.SelectAll;
end
else
MessageBox(Handle, PChar(E.Message), PChar(Application.Title), MB_ICONWARNING); // unknown error
// ... connect failed, leave procedure ...
exit;
end;
end;
Screen.Cursor := crDefault;
end
else begin
Screen.Cursor := crHourGlass;
IdFTP.Quit;
trvDirectories.Items.Clear;
trvDirectories.Enabled := False;
cmdConnect.Enabled := True;
cmdProxySettings.Enabled := True;
txtHost.Enabled := True;
txtPort.Enabled := True;
txtUsername.Enabled := True;
txtPassword.Enabled := True;
chkPassive.Enabled := True;
cmdConnect.Caption := 'Connect';
cmdCancel.Caption := '&Close';
cmdNext.Enabled := False;
Screen.Cursor := crDefault;
end;
end;
procedure TfrmMain.jplWizardChange(Sender: TObject);
begin
if (jplWizard.ActivePage = jspInstallProgress) then begin
cmdNext.Caption := '&Finish';
cmdNext.Enabled := False;
cmdBack.Visible := False;
end
else begin
cmdNext.Caption := '&Next >';
cmdNext.Enabled := True;
cmdBack.Visible := jplWizard.ActivePageIndex <> 0;
end;
if (jplWizard.ActivePage = jspLicense) then
cmdNext.Enabled := frbAgree.Checked;
if (jplWizard.ActivePage = jspFTP) then
cmdNext.Enabled := False;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
if LowerCase(ParamStr(1)) = '-logftp' then begin
MessageBox(Handle, 'FTP installation will be logged to FTP.log!', PChar(Application.Title), MB_ICONINFORMATION);
IdLogFile.Filename := ExtractFilePath(Application.ExeName) + 'FTP.log';
IdLogFile.Active := True;
end;
if not DirectoryExists(ExtractFilePath(Application.ExeName) + 'files\base') then begin
MessageBox(Handle, 'You cannot copy this program and then run it to install AMX Mod X. Please download and install the full AMX Mod X package and start this installer again from the start menu.', 'Error', MB_ICONERROR);
Application.Terminate;
end
else begin
FileList := TStringList.Create;
DirList := TStringList.Create;
rtfDetails.Clear;
end;
// delete files, then directories
if (DirectoryExists(ExtractFilePath(Application.ExeName) + 'temp')) then
DelTree(ExtractFilePath(Application.ExeName) + 'temp');
end;
procedure TfrmMain.cmdProxySettingsClick(Sender: TObject);
begin
frmProxy.ShowModal;
// Apply Proxy Settings
case frmProxy.cboProxy.ItemIndex of
0: IdFTP.ProxySettings.ProxyType := fpcmNone; // none
1: IdFTP.ProxySettings.ProxyType := fpcmHttpProxyWithFtp; // HTTP Proxy with FTP
2: IdFTP.ProxySettings.ProxyType := fpcmOpen; // Open
3: IdFTP.ProxySettings.ProxyType := fpcmSite; // Site
4: IdFTP.ProxySettings.ProxyType := fpcmTransparent; // Transparent
5: IdFTP.ProxySettings.ProxyType := fpcmUserPass; // User (Password)
6: IdFTP.ProxySettings.ProxyType := fpcmUserSite; // User (Site)
end;
IdFTP.ProxySettings.Host := frmProxy.txtHost.Text;
IdFTP.ProxySettings.UserName := frmProxy.txtPort.Text;
IdFTP.ProxySettings.Password := frmProxy.txtPassword.Text;
IdFTP.ProxySettings.Port := StrToInt(frmProxy.txtPort.Text);
end;
procedure TfrmMain.txtPortChange(Sender: TObject);
var i: integer;
begin
if txtPort.Text = '' then
txtPort.Text := '21'
else begin
// check if value is numeric...
for i := Length(txtPort.Text) downto 1 do begin
if Pos(txtPort.Text[i], '0123456789') = 0 then begin
txtPort.Text := '21';
txtPort.SelStart := 4;
exit;
end;
end;
end;
end;
procedure TfrmMain.trvDirectoriesExpanded(Sender: TObject;
Node: TTreeNode);
function NodeExists(const SNode: TTreeNode; const Text: String): Boolean;
var i: integer;
begin
Result := False;
for i := 0 to SNode.Count -1 do begin
if (SNode.Item[i].Text = Text) then begin
Result := True;
break;
end;
end;
end;
var ePath: String;
CurNode: TTreeNode;
i: integer;
begin
if (Integer(Node.Data) <> 0) then begin // no directories added yet
Screen.Cursor := crHourGlass;
// get complete path
ePath := '/';
CurNode := Node;
if (Assigned(CurNode)) then begin
repeat
ePath := '/' + CurNode.Text + ePath;
CurNode := CurNode.Parent;
until (not Assigned(CurNode));
end;
// change dir and add directories in it
try
Repaint;
IdFTP.ChangeDir(ePath);
with GetAllDirs do begin
if (Integer(Node.Data) = 2) and (Node.Count > 0) then
Node.Item[0].Free;
for i := 0 to Count -1 do begin
if (not NodeExists(Node, Strings[i])) then begin
CurNode := trvDirectories.Items.AddChild(Node, Strings[i]);
trvDirectories.Items.AddChild(CurNode, 'Scanning...');
CurNode.Data := Pointer(2);
end;
end;
Free;
end;
except
if (Integer(Node.Data) = 2) and (Node.Count > 0) then
Node.Item[0].Free;
Application.ProcessMessages;
end;
Node.Data := Pointer(0); // scan done
Screen.Cursor := crDefault;
end;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
FileList.Free;
DirList.Free;
end;
procedure TfrmMain.IdFTPWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
if AWorkCount > 15 then begin
ggeItem.Progress := AWorkCount;
CurrProgress := AWorkCount;
end;
if Cancel then
IdFTP.Abort;
Application.ProcessMessages;
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (jplWizard.ActivePage = jspFTP) and (IdFTP.Connected) then
IdFTP.Quit;
if (jplWizard.ActivePage = jspInstallProgress) and (ggeAll.Progress <> ggeAll.MaxValue) and (not Cancel) then begin
if MessageBox(Handle, 'Do you really want to cancel the installation?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then begin
Screen.Cursor := crDefault;
Application.OnException := ExceptionHandler;
Cancel := True;
if IdFTP.Connected then
IdFTP.Quit;
end
else begin
Action := caNone;
exit;
end;
end;
if (DirectoryExists(ExtractFilePath(Application.ExeName) + 'temp')) then
DelTree(ExtractFilePath(Application.ExeName) + 'temp');
end;
procedure TfrmMain.ExceptionHandler(Sender: TObject; E: Exception);
begin
// we don't want any exceptions after close, so leave this empty
end;
procedure TfrmMain.tmrSpeedTimer(Sender: TObject);
begin
Caption := CalcSpeed(OldProgress, CurrProgress);
OldProgress := CurrProgress;
end;
procedure TfrmMain.trvDirectoriesExpanding(Sender: TObject;
Node: TTreeNode; var AllowExpansion: Boolean);
begin
Node.ImageIndex := 1;
Node.SelectedIndex := 1;
end;
procedure TfrmMain.trvDirectoriesCollapsing(Sender: TObject;
Node: TTreeNode; var AllowCollapse: Boolean);
begin
Node.ImageIndex := 0;
Node.SelectedIndex := 0;
end;
procedure TfrmMain.jspFTPShow(Sender: TObject);
begin
Cancel := False;
end;
procedure TfrmMain.frbFTPClick(Sender: TObject);
begin
frbDedicatedServer.Checked := False;
frbListenServer.Checked := False;
frbStandaloneServer.Checked := False;
frbSelectMod.Checked := False;
end;
procedure TfrmMain.frbLocalClick(Sender: TObject);
begin
frbFTP.Checked := False;
end;
procedure TfrmMain.trvModsClick(Sender: TObject);
begin
if gMultiAccount then
cmdNext.Enabled := (Assigned(trvMods.Selected)) and (Assigned(trvMods.Selected.Parent))
else
cmdNext.Enabled := (Assigned(trvMods.Selected));
end;
procedure TfrmMain.trvDirectoriesMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var Node: TTreeNode;
begin
Node := trvDirectories.GetNodeAt(X, Y);
if (Assigned(Node)) then begin
if (Node.DisplayRect(True).Right < X) then
trvDirectories.Selected := nil;
end;
end;
procedure TfrmMain.trvDirectoriesChange(Sender: TObject; Node: TTreeNode);
begin
if (Screen.Cursor <> crHourGlass) and (Assigned(Node)) and (Integer(Node.Data) = 1) then
Node.Expand(False);
end;
end.