Added MM:S installer to the CVS [MM:S installer is a modifed copy of the AMX Mod X installer]

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40127
This commit is contained in:
Christian Hammacher 2005-10-07 15:42:18 +00:00
parent a169ec7f61
commit 5d39ea83a9
22 changed files with 8877 additions and 0 deletions

38
installer/Attach.cfg Normal file
View 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:\programme\borland\delphi7\Projects\Bpl"
-LN"c:\programme\borland\delphi7\Projects\Bpl"
-w-UNSAFE_TYPE
-w-UNSAFE_CODE
-w-UNSAFE_CAST

139
installer/Attach.dof Normal file
View File

@ -0,0 +1,139 @@
[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=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=vcl;rtl;vclx;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;VclSmp;dbrtl;dbexpress;vcldb;dsnap;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;vclactnband;vclshlctrls;Rave50CLX;Rave50VCL;dclOffice2k;Indy70;DJcl;FlatStyle_D5;DelphiX_for7;mxFlatPack_D7;tbx_d7;tb2k_d7;mbTBXLibPack;TntUnicodeVcl_R70;SynEdit_R7
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Language]
ActiveLang=
ProjectLang=
RootDir=C:\Programme\Borland\Delphi7\Bin\
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlUnitAliases]
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;

51
installer/Attach.dpr Normal file
View File

@ -0,0 +1,51 @@
program Attach;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, UnitPackSystem;
var eStream: TMemoryStream;
eFiles: TStringList;
begin
WriteLn('// File attacher for the MM:S installer');
WriteLn('// by Basic-Master');
WriteLn('');
WriteLn('// Looking up files...');
{ Check files }
if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server.dll') then
WriteLn('// Found files\server.dll')
else begin
WriteLn('// Error: Couldn''t find files\server.dll!');
ReadLn;
exit;
end;
if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so') then
WriteLn('// Found files\server_i486.so')
else begin
WriteLn('// Error: Couldn''t find files\server_i486.so!');
ReadLn;
exit;
end;
if FileExists(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe') then
WriteLn('// Found MMS_Installer.exe')
else begin
WriteLn('// Error: Couldn''t find MMS_Installer.exe!');
ReadLn;
exit;
end;
{ Compress files }
WriteLn('// Compressing files...');
eFiles := TStringList.Create;
eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server.dll');
eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so');
eStream := TMemoryStream.Create;
CompressFiles(eFiles, ExtractFilePath(ParamStr(0)) + 'temp.zip');
eStream.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'temp.zip');
WriteLn('// Attaching output to MMS_Installer.exe...');
AttachToFile(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe', eStream);
DeleteFile(ExtractFilePath(ParamStr(0)) + 'temp.zip');
eStream.Free;
WriteLn('// Done.');
ReadLn;
end.

BIN
installer/Attach.exe Normal file

Binary file not shown.

View 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:\programme\borland\delphi7\Projects\Bpl"
-LN"c:\programme\borland\delphi7\Projects\Bpl"
-w-UNSAFE_TYPE
-w-UNSAFE_CODE
-w-UNSAFE_CAST

139
installer/MMS_Installer.dof Normal file
View File

@ -0,0 +1,139 @@
[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=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=vcl;rtl;vclx;vclie;xmlrtl;inetdbbde;inet;inetdbxpress;VclSmp;dbrtl;dbexpress;vcldb;dsnap;dbxcds;inetdb;bdertl;vcldbx;adortl;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOffice2k;JvStdCtrlsD7R;JvAppFrmD7R;JvCoreD7R;JvBandsD7R;JvBDED7R;JvDBD7R;JvDlgsD7R;JvCmpD7R;JvCryptD7R;JvCtrlsD7R;JvCustomD7R;JvDockingD7R;JvDotNetCtrlsD7R;JvEDID7R;qrpt;JvGlobusD7R;JvHMID7R;JvInspectorD7R;JvInterpreterD7R;JvJansD7R;JvManagedThreadsD7R;JvMMD7R;JvNetD7R;JvPageCompsD7R;JvPluginD7R;JvPrintPreviewD7R;JvSystemD7R;JvTimeFrameworkD7R;JvUIBD7R;JvValidatorsD7R;JvWizardD7R;JvXPCtrlsD7R;DelphiX_for7;Indy70;DJcl;tb2k_d7;FlatStyle_D5;scited7;mxFlatPack_D7;mbXPLib
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=-logftp
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Language]
ActiveLang=
ProjectLang=
RootDir=
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1031
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[HistoryLists\hlUnitAliases]
Count=1
Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;

View File

@ -0,0 +1,39 @@
program MMS_Installer;
{ Metamod:Source installer ported from the AMX Mod X installer
Used components:
- Indy 9 (www.indyproject.org)
- FlatStyle Components (www.torry.net)
- FlatPack Component Pack (www.torry.net)
- JVCL Lib Pack 3.0 (jvcl.sourceforge.net)
}
uses
Forms,
UnitfrmMain in 'UnitfrmMain.pas' {frmMain},
UnitFunctions in 'UnitFunctions.pas',
UnitfrmProxy in 'UnitfrmProxy.pas' {frmProxy},
UnitInstall in 'UnitInstall.pas',
UnitSelectModPath in 'UnitSelectModPath.pas' {frmSelectModPath},
UnitPackSystem in 'UnitPackSystem.pas';
{$R *.res}
begin
Application.Initialize;
Application.Title := 'Metamod:Source Installer';
Application.CreateForm(TfrmMain, frmMain);
frmMain.lblWelcome.Caption := 'Welcome to the Metamod:Source ' + VERSION + ' Setup Wizard';
frmMain.lblInfo1.Caption := 'This wizard will guide you through the installation of Metamod:Source ' + VERSION + '.';
frmMain.lblSubTitle1.Caption := 'Please review the following license terms before installing Metamod:Source ' + VERSION + '.';
frmMain.lblSelectModInfo.Caption := 'Please select the mod Metamod:Source ' + VERSION + ' shall be installed to.';
frmMain.lblTitle3.Caption := 'Installing Metamod:Source ' + VERSION + ' via FTP';
frmMain.lblTitle5.Caption := 'Installing Metamod:Source ' + VERSION;
frmMain.lblSubTitle5.Caption := 'Please wait while Metamod:Source ' + VERSION + ' is being installed.';
Application.CreateForm(TfrmProxy, frmProxy);
Application.CreateForm(TfrmSelectModPath, frmSelectModPath);
Application.Run;
end.

BIN
installer/MMS_Installer.exe Normal file

Binary file not shown.

BIN
installer/MMS_Installer.res Normal file

Binary file not shown.

126
installer/UnitFunctions.pas Normal file
View File

@ -0,0 +1,126 @@
unit UnitFunctions;
interface
uses SysUtils, Classes, Windows, IdFTPList, Math;
function CalcSpeed(eOld, eNew: Integer): String;
// local
function GetAllFiles(Mask: String; Attr: Integer; Recursive: Boolean; ShowDirs: Boolean; ShowPath: Boolean = True): TStringList;
// ftp
function GetAllDirs: TStringList;
implementation
uses UnitfrmMain;
function CalcSpeed(eOld, eNew: Integer): String;
begin
Result := frmMain.Caption;
if (eOld < eNew) and (eOld <> 0) then begin
eOld := eNew - eOld;
//eOld := eOld *2; // this is only used for faster updates...
Result := 'Metamod:Source - Uploading with ' + FloatToStr(RoundTo(eOld / 1024, -2)) + ' kb/s';
end;
end;
function GetAllFiles(Mask: String; Attr: Integer; Recursive: Boolean; ShowDirs: Boolean; ShowPath: Boolean = True): TStringList;
var eSearch: TSearchRec;
begin
Result := TStringList.Create;
// Find all files
if FindFirst(Mask, Attr, eSearch) = 0 then
begin
repeat
if eSearch.Name[1] <> '.' then begin
if ShowPath then begin
if ((eSearch.Attr and Attr) = eSearch.Attr) and ((eSearch.Attr and faDirectory) <> eSearch.Attr) then
Result.Add(ExtractFilePath(Mask) + eSearch.Name)
else if (ShowDirs) and ((eSearch.Attr and faDirectory) = eSearch.Attr) then
Result.Add(ExtractFilePath(Mask) + eSearch.Name);
end
else begin
if ((eSearch.Attr and Attr) = eSearch.Attr) and ((eSearch.Attr and faDirectory) <> eSearch.Attr) then
Result.Add(eSearch.Name)
else if (ShowDirs) and ((eSearch.Attr and faDirectory) = eSearch.Attr) then
Result.Add(eSearch.Name);
end;
if ((eSearch.Attr and faDirectory) = eSearch.Attr) and (Recursive) then begin
with GetAllFiles(ExtractFilePath(Mask) + eSearch.Name + '\' + ExtractFileName(Mask), Attr, True, ShowDirs, ShowPath) do begin
Result.Text := Result.Text + Text;
Free;
end;
end;
end;
until FindNext(eSearch) <> 0;
end;
end;
function GetAllDirs: TStringList;
var eList: TStringList;
i: integer;
begin
eList := TStringList.Create;
frmMain.IdFTP.List(eList);
frmMain.IdFTP.DirectoryListing.LoadList(eList);
eList.Clear;
for i := 0 to frmMain.IdFTP.DirectoryListing.Count -1 do begin
if frmMain.IdFTP.DirectoryListing.Items[i].ItemType = ditDirectory then
eList.Add(frmMain.IdFTP.DirectoryListing.Items[i].FileName);
end;
Result := eList;
end;
{ This is another possibility I coded because I couldn't find another bug...
function GetAllDirs: TStringList;
var eList: TStringList;
i, eStart: integer;
begin
eList := TStringList.Create;
frmMain.IdFTP.List(eList, '', True);
eStart := 0;
// +----------------------------------------------------------------+
// | drwxr-xr-x 5 web3 ftponly 2048 Jun 25 19:43 files |
// | drwxr-xr-x 2 web3 ftponly 2048 Jun 25 19:57 html |
// | drwxr-xr-x 3 root root 2048 Jun 20 05:03 log |
// | drwxrwxrwx 2 web3 ftponly 2048 Jun 19 2004 phptmp |
// +----------------------------------------------------------------+
// at first remove all non-directories from the list
for i := eList.Count -1 downto 0 do begin
if Pos('d', eList[i]) <> 1 then
eList.Delete(i);
end;
// then we have to find the position where ALL filenames start...
for i := 0 to eList.Count -1 do begin
if (eStart = 0) and (Pos(':', eList[i]) <> 0) then
eStart := Pos(':', eList[i]);
end;
if eStart = 0 then
eList.Clear
else begin
// find the position
for i := 0 to eList.Count -1 do begin
if Pos(':', eList[i]) <> 0 then begin
while (eStart <> Length(eList[i])) and (eList[i][eStart] <> #32) do
Inc(eStart, 1);
end;
end;
// remove the detail stuff...
for i := 0 to eList.Count -1 do
eList[i] := Copy(eList[i], eStart +1, Length(eList[i]));
end;
Result := eList;
end; }
end.

548
installer/UnitInstall.pas Normal file
View File

@ -0,0 +1,548 @@
unit UnitInstall;
interface
uses SysUtils, Classes, Windows, Graphics, Forms, ShellAPI, Controls, Messages,
TlHelp32, IdFTPCommon, ComCtrls;
type TOS = (osWindows, osLinux);
procedure AddStatus(Text: String; Color: TColor; ShowTime: Boolean = True);
procedure AddDone(Additional: String = '');
procedure AddSkipped;
procedure AddNotFound;
procedure DownloadFile(eFile: String; eDestination: String);
procedure BasicInstallation(ePath: String; SteamInstall: Boolean; OS: TOS);
procedure InstallDedicated(eModPath: String; UseSteam: Boolean);
procedure InstallListen(ePath: String);
procedure InstallCustom(ePath: String; eOS: TOS);
procedure InstallFTP(OS: TOS);
var StartTime: TDateTime;
SteamPath: String;
StandaloneServer: String;
Cancel: Boolean = False;
implementation
uses UnitfrmMain, UnitfrmProxy, UnitFunctions, UnitPackSystem;
// useful stuff
function InstallTime: String;
begin
Result := FormatDateTime('HH:MM:SS', Now - StartTime);
end;
procedure AddStatus(Text: String; Color: TColor; ShowTime: Boolean = True);
begin
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
if ShowTime then begin
frmMain.rtfDetails.SelAttributes.Color := clBlack;
if frmMain.rtfDetails.Text = '' then
frmMain.rtfDetails.SelText := '[' + InstallTime + '] '
else
frmMain.rtfDetails.SelText := #13#10 + '[' + InstallTime + '] ';
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
end
else
frmMain.rtfDetails.SelText := #13#10;
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
frmMain.rtfDetails.SelAttributes.Color := Color;
frmMain.rtfDetails.SelText := Text;
frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0);
frmMain.Repaint;
Application.ProcessMessages;
end;
procedure AddDone(Additional: String = '');
begin
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
frmMain.rtfDetails.SelAttributes.Color := clGreen;
if Additional = '' then
frmMain.rtfDetails.SelText := ' Done.'
else
frmMain.rtfDetails.SelText := ' Done, ' + Additional + '.';
frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0);
frmMain.Repaint;
Application.ProcessMessages;
end;
procedure AddSkipped;
begin
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
frmMain.rtfDetails.SelAttributes.Color := $004080FF; // orange
frmMain.rtfDetails.SelText := ' Skipped.';
frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0);
frmMain.Repaint;
Application.ProcessMessages;
end;
procedure AddNotFound;
begin
frmMain.rtfDetails.SelStart := Length(frmMain.rtfDetails.Text);
frmMain.rtfDetails.SelAttributes.Color := clRed;
frmMain.rtfDetails.SelText := ' Not found.';
frmMain.rtfDetails.Perform(WM_VSCROLL, SB_BOTTOM, 0);
frmMain.Repaint;
Application.ProcessMessages;
end;
procedure FileCopy(Source, Destination: String; CopyConfig: Boolean; AddStatus: Boolean = True);
begin
if (not CopyConfig) and (Pos('config', Source) <> 0) then begin
if AddStatus then
AddSkipped;
exit;
end;
if not FileExists(Source) then begin
if AddStatus then
AddNotFound;
exit;
end;
try
if FileExists(Destination) then
DeleteFile(PChar(Destination));
CopyFile(PChar(Source), PChar(Destination), False);
except
Application.ProcessMessages;
end;
if AddStatus then
AddDone;
end;
procedure DownloadFile(eFile: String; eDestination: String);
var TransferType: TIdFTPTransferType;
begin
// There's only one file to download and it's ASCII :]
TransferType := ftASCII;
if frmMain.IdFTP.TransferType <> TransferType then
frmMain.IdFTP.TransferType := TransferType;
// download the file
frmMain.IdFTP.Get(eFile, eDestination, True);
end;
procedure UploadFile(eFile: String; eDestination: String; CopyConfig: Boolean = True);
var TransferType: TIdFTPTransferType;
begin
if (Pos('config', eFile) > 0) and (not CopyConfig) then begin
AddSkipped;
exit;
end;
eDestination := StringReplace(eDestination, '\', '/', [rfReplaceAll]);
// the same as in DownloadFile()
TransferType := ftBinary;
if ExtractFileExt(LowerCase(eFile)) = '.txt' then TransferType := ftASCII;
if frmMain.IdFTP.TransferType <> TransferType then
frmMain.IdFTP.TransferType := TransferType;
// upload the file
frmMain.IdFTP.Put(eFile, eDestination);
AddDone;
end;
procedure FTPMakeDir(eDir: String);
begin
eDir := StringReplace(eDir, '\', '/', [rfReplaceAll]);
try
frmMain.IdFTP.MakeDir(eDir);
except
Application.ProcessMessages;
end;
end;
function FSize(eFile: String): Cardinal;
var eRec: TSearchRec;
begin
if FindFirst(eFile, faAnyFile, eRec) = 0 then
Result := eRec.Size
else
Result := 0;
end;
// stuff for killing processes
function GetProcessID(sProcName: String): Integer;
var
hProcSnap: THandle;
pe32: TProcessEntry32;
begin
result := -1;
hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
if hProcSnap = INVALID_HANDLE_VALUE then
exit;
pe32.dwSize := SizeOf(ProcessEntry32);
if Process32First(hProcSnap, pe32) = true then begin
while Process32Next(hProcSnap, pe32) = true do begin
if pos(sProcName, pe32.szExeFile) <> 0then
result := pe32.th32ProcessID;
end;
end;
CloseHandle(hProcSnap);
end;
procedure KillProcess(dwProcID: DWORD);
var
hProcess : Cardinal;
dw : DWORD;
begin
hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID);
TerminateProcess(hProcess, 0);
dw := WaitForSingleObject(hProcess, 5000);
case dw of
WAIT_TIMEOUT: begin
CloseHandle(hProcess);
exit;
end;
WAIT_FAILED: begin
RaiseLastOSError;
CloseHandle(hProcess);
exit;
end;
end;
CloseHandle(hProcess);
end;
// Installation here
{ Basic Installation }
procedure BasicInstallation(ePath: String; SteamInstall: Boolean; OS: TOS);
var eStr: TStringList;
i: integer;
CopyConfig: Boolean;
eFound: Boolean;
begin
frmMain.ggeAll.MaxValue := 7;
frmMain.ggeAll.Progress := 0;
frmMain.ggeItem.MaxValue := 1;
frmMain.ggeItem.Progress := 0;
if (GetProcessID('Steam.exe') <> -1) and (SteamInstall) then begin
if MessageBox(frmMain.Handle, 'Steam is still running. It is necersarry to shut it down before you install Metamod:Source. Shut it down now?', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNO) = mrYes then begin
AddStatus('Shutting down Steam...', clBlack, False);
if GetProcessID('Steam.exe') = -1 then
AddDone
else
KillProcess(GetProcessID('Steam.exe'));
while GetProcessID('Steam.exe') <> -1 do begin // sure is sure...
Sleep(50);
Application.ProcessMessages;
end;
AddDone;
end
else begin
Application.Terminate;
exit;
end;
end;
frmMain.ggeAll.Progress := 1;
frmMain.ggeItem.Progress := 1;
{ Unpack }
frmMain.ggeItem.Progress := 0;
AddStatus('Unpacking files...', clBlack);
Unpack;
AddDone;
frmMain.ggeAll.Progress := 2;
frmMain.ggeItem.Progress := 1;
{ Check for installation }
CopyConfig := True;
if DirectoryExists(ePath + 'addons\metamod\bin') then begin
case MessageBox(frmMain.Handle, 'A Metamod:Source installation was already detected. If you choose to reinstall, your configuration files will be erased. Click Yes to continue, No to Upgrade, or Cancel to abort the install.', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNOCANCEL) of
mrNo: CopyConfig := False;
mrCancel: begin
Application.Terminate;
exit;
end;
end;
end;
AddStatus('Creating directories...', clBlack);
if not eFound then begin
{ Create directories }
frmMain.ggeItem.Progress := 0;
ForceDirectories(ePath + 'addons\metamod\bin');
AddDone;
end
else
AddSkipped;
frmMain.ggeItem.Progress := 1;
frmMain.ggeAll.Progress := 3;
{ gameinfo.txt }
if not FileExists(ePath + 'gameinfo.txt') then begin
if MessageBox(frmMain.Handle, 'The file "gameinfo.txt" couldn''t be found. Continue installation?', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNO) = mrNo then begin
AddStatus('Installation canceled by user!', clRed, False);
Screen.Cursor := crDefault;
Cancel := True;
exit;
end;
end
else begin
eStr := TStringList.Create;
{ Metaplugins.ini }
frmMain.ggeItem.Progress := 0;
AddStatus('Creating metaplugins.ini...', clBlack);
if CopyConfig then begin
eStr.SaveToFile(ePath + 'addons\metamod\metaplugins.ini');
AddDone;
end
else
AddSkipped;
frmMain.ggeItem.Progress := 1;
frmMain.ggeAll.Progress := 4;
{ Gameinfo.txt }
frmMain.ggeItem.Progress := 0;
eFound := False;
AddStatus('Editing gameinfo.txt...', clBlack);
eStr.LoadFromFile(ePath + 'gameinfo.txt');
for i := 0 to eStr.Count -1 do begin
if Trim(LowerCase(eStr[i])) = 'gamebin |gameinfo_path|addons/metamod/bin' then begin
eFound := True;
break;
end;
end;
if not eFound then begin
for i := 0 to eStr.Count -1 do begin
if Trim(eStr[i]) = 'SearchPaths' then begin
eStr.Insert(i +2, ' GameBin |gameinfo_path|addons/metamod/bin');
AddDone;
break;
end;
end;
FileSetAttr(ePath + 'gameinfo.txt', 0);
eStr.SaveToFile(ePath + 'gameinfo.txt');
FileSetAttr(ePath + 'gameinfo.txt', faReadOnly); // important for listen servers
AddDone;
end
else
AddSkipped;
eStr.Free;
frmMain.ggeItem.Progress := 1;
frmMain.ggeAll.Progress := 5;
end;
{ Copy files }
frmMain.ggeItem.Progress := 0;
AddStatus('Copying server.dll...', clBlack);
CopyFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll'), PChar(ePath + 'addons\metamod\bin\server.dll'), False);
AddDone;
frmMain.ggeItem.Progress := 1;
frmMain.ggeAll.Progress := 6;
{ Remove files }
frmMain.ggeItem.Progress := 0;
AddStatus('Removing temporary files...', clBlack);
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll'));
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server_i486.so'));
AddDone;
frmMain.ggeItem.Progress := 1;
frmMain.ggeAll.Progress := 7;
{ Finish }
AddStatus('', clBlack, False);
AddStatus('Finished installation!', clBlack, False);
frmMain.cmdNext.Enabled := True;
frmMain.cmdCancel.Hide;
Screen.Cursor := crDefault;
end;
{ Dedicated Server }
procedure InstallDedicated(eModPath: String; UseSteam: Boolean);
begin
StartTime := Now;
Screen.Cursor := crHourGlass;
AddStatus('Starting Metamod:Source installation on dedicated server...', clBlack, False);
BasicInstallation(eModPath, UseSteam, osWindows);
end;
{ Listen Server }
procedure InstallListen(ePath: String);
begin
StartTime := Now;
Screen.Cursor := crHourGlass;
AddStatus('Starting Metamod:Source installation on the listen server...', clBlack);
BasicInstallation(ePath, True, osWindows);
end;
{ Custom mod }
procedure InstallCustom(ePath: String; eOS: TOS);
begin
StartTime := Now;
Screen.Cursor := crHourGlass;
AddStatus('Starting Metamod:Source installation...', clBlack);
BasicInstallation(ePath, False, eOS);
end;
{ FTP }
procedure InstallFTP(OS: TOS);
function DoReconnect: Boolean;
begin
Result := False;
if MessageBox(frmMain.Handle, 'You have been disconnected due to an error. Try to reconnect?', PChar(Application.Title), MB_ICONQUESTION + MB_YESNO) = mrYes then begin
try
frmMain.IdFTP.Connect;
Result := True;
except
MessageBox(frmMain.Handle, 'Failed to reconnect. Installation aborted.', PChar(Application.Title), MB_ICONSTOP);
end;
end;
end;
label CreateAgain;
label UploadAgain;
var eStr: TStringList;
i: integer;
ePath: String;
CurNode: TTreeNode;
CopyConfig, eFound: Boolean;
eGoBack: Boolean;
begin
frmMain.cmdCancel.Show;
frmMain.cmdNext.Hide;
Screen.Cursor := crHourGlass;
frmMain.ggeAll.MaxValue := 6;
frmMain.ggeAll.Progress := 0;
frmMain.ggeItem.MaxValue := 1;
frmMain.ggeItem.Progress := 0;
{ Unpack }
frmMain.ggeItem.Progress := 0;
AddStatus('Unpacking files...', clBlack);
Unpack;
AddDone;
frmMain.ggeAll.Progress := 2;
frmMain.ggeItem.Progress := 1;
{ Check for installation }
AddStatus('Editing gameinfo.txt...', clBlack);
eStr := TStringList.Create;
DownloadFile('gameinfo.txt', ExtractFilePath(ParamStr(0)) + 'gameinfo.txt');
eStr.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt');
CopyConfig := True;
eFound := False;
for i := 0 to eStr.Count -1 do begin
if Trim(LowerCase(eStr[i])) = 'gamebin |gameinfo_path|addons/metamod/bin' then begin
eFound := True;
case MessageBox(frmMain.Handle, 'A Metamod:Source installation was already detected. If you choose to reinstall, your configuration files will be erased. Click Yes to continue, No to Upgrade, or Cancel to abort the install.', PChar(frmMain.Caption), MB_ICONQUESTION + MB_YESNOCANCEL) of
mrNo: CopyConfig := False;
mrCancel: begin
Application.Terminate;
eStr.Free;
exit;
end;
end;
break;
end;
end;
if not eFound then begin
for i := 0 to eStr.Count -1 do begin
if Trim(eStr[i]) = 'SearchPaths' then begin
eStr.Insert(i +2, ' GameBin |gameinfo_path|addons/metamod/bin');
AddDone;
break;
end;
end;
eStr.SaveToFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt');
UploadFile(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt', 'gameinfo.txt');
try
AddStatus('Trying to set gameinfo.txt to read-only...', clBlack);
frmMain.IdFTP.Site('CHMOD 744 gameinfo.txt');
AddDone;
except
AddStatus('Warning: CHMOD not supported.', clMaroon);
end;
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'gameinfo.txt'));
end
else
AddSkipped;
frmMain.ggeAll.Progress := 3;
frmMain.ggeItem.Progress := 1;
{ Create directories }
frmMain.ggeItem.Progress := 0;
frmMain.ggeItem.MaxValue := 3;
AddStatus('Creating directories...', clBlack);
if not eFound then begin
FTPMakeDir('addons');
frmMain.IdFTP.ChangeDir('addons');
frmMain.ggeItem.Progress := 1;
FTPMakeDir('metamod');
frmMain.IdFTP.ChangeDir('metamod');
frmMain.ggeItem.Progress := 2;
FTPMakeDir('bin');
frmMain.ggeItem.Progress := 3;
AddDone;
end
else
AddSkipped;
frmMain.ggeAll.Progress := 4;
frmMain.ggeItem.Progress := 3;
{ Upload metaplugins.ini }
frmMain.ggeAll.Progress := 4;
frmMain.ggeItem.MaxValue := 1;
frmMain.ggeItem.Progress := 0;
AddStatus('Uploading metaplugins.ini...', clBlack);
if CopyConfig then begin
eStr.Clear;
eStr.SaveToFile(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini');
UploadFile(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini', 'metaplugins.ini');
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'metaplugins.ini'));
end
else
AddSkipped;
frmMain.ggeAll.Progress := 5;
frmMain.ggeItem.Progress := 1;
{ Upload server.dll / server_i486.so }
frmMain.tmrSpeed.Enabled := True;
frmMain.ggeItem.Progress := 0;
frmMain.IdFTP.ChangeDir('bin');
if OS = osWindows then begin
AddStatus('Uploading server.dll...', clBlack);
frmMain.ggeItem.MaxValue := FSize(ExtractFilePath(ParamStr(0)) + 'server.dll');
UploadFile(ExtractFilePath(ParamStr(0)) + 'server.dll', 'server.dll');
end
else begin
AddStatus('Uploading server_i486.so...', clBlack);
frmMain.ggeItem.MaxValue := FSize(ExtractFilePath(ParamStr(0)) + 'server_i486.so');
UploadFile(ExtractFilePath(ParamStr(0)) + 'server_i486.so', 'server_i486.so');
end;
{ Remove created files }
AddStatus('Removing temporary files...', clBlack);
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server.dll'));
DeleteFile(PChar(ExtractFilePath(ParamStr(0)) + 'server_i486.so'));
AddDone;
{ End }
frmMain.IdFTP.Disconnect;
frmMain.ggeAll.Progress := frmMain.ggeAll.MaxValue;
frmMain.ggeItem.Progress := frmMain.ggeItem.MaxValue;
AddStatus('', clBlack, False);
AddStatus('Finished installation!', clBlack, False);
frmMain.tmrSpeed.Enabled := False;
eStr.Free;
Screen.Cursor := crDefault;
frmMain.cmdNext.Enabled := True;
frmMain.cmdCancel.Hide;
frmMain.cmdNext.Show;
frmMain.tmrSpeed.Enabled := False;
frmMain.Caption := Application.Title;
end;
end.

View File

@ -0,0 +1,180 @@
unit UnitPackSystem;
interface
uses SysUtils, Classes, Zlib;
procedure CompressFiles(Files : TStrings; const Filename : String);
function DecompressStream(Stream : TMemoryStream; DestDirectory : String): Boolean;
function AttachToFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean;
function LoadFromFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean;
procedure Unpack;
implementation
procedure CompressFiles(Files : TStrings; const Filename : String);
var
infile, outfile, tmpFile : TFileStream;
compr : TCompressionStream;
i,l : Integer;
s : String;
begin
if Files.Count > 0 then
begin
outFile := TFileStream.Create(Filename,fmCreate);
try
{ the number of files }
l := Files.Count;
outfile.Write(l,SizeOf(l));
for i := 0 to Files.Count-1 do
begin
infile := TFileStream.Create(Files[i],fmOpenRead);
try
{ the original filename }
s := ExtractFilename(Files[i]);
l := Length(s);
outfile.Write(l,SizeOf(l));
outfile.Write(s[1],l);
{ the original filesize }
l := infile.Size;
outfile.Write(l,SizeOf(l));
{ compress and store the file temporary}
tmpFile := TFileStream.Create('tmp',fmCreate);
compr := TCompressionStream.Create(clMax,tmpfile);
try
compr.CopyFrom(infile,l);
finally
compr.Free;
tmpFile.Free;
end;
{ append the compressed file to the destination file }
tmpFile := TFileStream.Create('tmp',fmOpenRead);
try
outfile.CopyFrom(tmpFile,0);
finally
tmpFile.Free;
end;
finally
infile.Free;
end;
end;
finally
outfile.Free;
end;
DeleteFile('tmp');
end;
end;
function DecompressStream(Stream : TMemoryStream; DestDirectory : String): Boolean;
var
dest,s : String;
decompr : TDecompressionStream;
outfile : TFilestream;
i,l,c : Integer;
begin
// IncludeTrailingPathDelimiter (D6/D7 only)
dest := IncludeTrailingPathDelimiter(DestDirectory);
Result := False;
try
{ number of files }
Stream.Read(c,SizeOf(c));
for i := 1 to c do
begin
{ read filename }
Stream.Read(l,SizeOf(l));
SetLength(s,l);
Stream.Read(s[1],l);
{ read filesize }
Stream.Read(l,SizeOf(l));
{ decompress the files and store it }
s := dest+s; //include the path
outfile := TFileStream.Create(s,fmCreate);
decompr := TDecompressionStream.Create(Stream);
try
outfile.CopyFrom(decompr,l);
finally
outfile.Free;
decompr.Free;
end;
end;
finally
Result := True;
end;
end;
function AttachToFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean;
var
aStream: TFileStream;
iSize: Integer;
begin
Result := False;
if not FileExists(AFileName) then
Exit;
try
aStream := TFileStream.Create(AFileName, fmOpenWrite or fmShareDenyWrite);
MemoryStream.Seek(0, soFromBeginning);
// seek to end of File
// ans Ende der Datei Seeken
aStream.Seek(0, soFromEnd);
// copy data from MemoryStream
// Daten vom MemoryStream kopieren
aStream.CopyFrom(MemoryStream, 0);
// save Stream-Size
// die Streamgröße speichern
iSize := MemoryStream.Size + SizeOf(Integer);
aStream.Write(iSize, SizeOf(iSize));
finally
aStream.Free;
end;
Result := True;
end;
function LoadFromFile(const AFileName: string; MemoryStream: TMemoryStream): Boolean;
var
aStream: TFileStream;
iSize: Integer;
begin
Result := False;
if not FileExists(AFileName) then
Exit;
try
aStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
// seek to position where Stream-Size is saved
// zur Position seeken wo Streamgröße gespeichert
aStream.Seek(-SizeOf(Integer), soFromEnd);
aStream.Read(iSize, SizeOf(iSize));
if iSize > aStream.Size then
begin
aStream.Free;
Exit;
end;
// seek to position where data is saved
// zur Position seeken an der die Daten abgelegt sind
aStream.Seek(-iSize, soFromEnd);
MemoryStream.SetSize(iSize - SizeOf(Integer));
MemoryStream.CopyFrom(aStream, iSize - SizeOf(iSize));
MemoryStream.Seek(0, soFromBeginning);
finally
aStream.Free;
end;
Result := True;
end;
{ Unpack function }
procedure Unpack;
var eStream: TMemoryStream;
begin
eStream := TMemoryStream.Create;
try
LoadFromFile(ParamStr(0), eStream); // Get ZIP
DecompressStream(eStream, ExtractFilePath(ParamStr(0))); // Unpack files
except
raise Exception.Create('No files attached!');
end;
eStream.Free;
end;
end.

Binary file not shown.

View File

@ -0,0 +1,26 @@
unit UnitSelectModPath;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, FileCtrl, ComCtrls, ShellCtrls,
TFlatComboBoxUnit, TFlatButtonUnit;
type
TfrmSelectModPath = class(TForm)
pnlDesign: TPanel;
lblInfo: TLabel;
trvDirectory: TShellTreeView;
cmdOK: TFlatButton;
cmdCancel: TFlatButton;
end;
var
frmSelectModPath: TfrmSelectModPath;
implementation
{$R *.DFM}
end.

6810
installer/UnitfrmMain.dfm Normal file

File diff suppressed because it is too large Load Diff

651
installer/UnitfrmMain.pas Normal file
View File

@ -0,0 +1,651 @@
unit UnitfrmMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TFlatRadioButtonUnit, 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;
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;
lblInstallMethod: TLabel;
pnlInstallMethod: TPanel;
frbDedicatedServer: TFlatRadioButton;
frbListenServer: TFlatRadioButton;
frbSelectMod: TFlatRadioButton;
frbFTP: TFlatRadioButton;
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;
lblStep4: TLabel;
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;
lstMods: TmxFlatListBox;
chkPassive: TFlatCheckBox;
lblStep3: TLabel;
pnlOS: TPanel;
optWindows: TFlatRadioButton;
optLinux: TFlatRadioButton;
IdFTP: TIdFTP;
cmdProxySettings: TFlatButton;
IdAntiFreeze: TIdAntiFreeze;
frbStandaloneServer: TFlatRadioButton;
tmrSpeed: TTimer;
IdLogFile: TIdLogFile;
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 lstModsClick(Sender: TObject);
procedure cmdProxySettingsClick(Sender: TObject);
procedure txtPortChange(Sender: TObject);
procedure trvDirectoriesExpanded(Sender: TObject; Node: TTreeNode);
procedure trvDirectoriesChange(Sender: TObject; Node: TTreeNode);
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);
private
OldProgress: Integer;
CurrProgress: Integer;
public
procedure ExceptionHandler(Sender: TObject; E: Exception);
end;
var
frmMain: TfrmMain;
const VERSION = '1.01';
implementation
uses UnitFunctions, UnitfrmProxy, UnitInstall, UnitSelectModPath;
{$R *.dfm}
procedure TfrmMain.jvwStepsCancelButtonClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.cmdCancelClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.cmdNextClick(Sender: TObject);
var ePath: String;
eRegistry: TRegistry;
eStr: TStringList;
CurNode: TTreeNode;
eOS: TOS;
begin
{ FTP }
if jplWizard.ActivePage = jspFTP then begin
if not IdFTP.Connected then
IdFTP.Connect;
eStr := TStringList.Create;
ePath := '/';
CurNode := trvDirectories.Selected;
repeat
ePath := '/' + CurNode.Text + ePath;
CurNode := CurNode.Parent;
until (not Assigned(CurNode));
IdFTP.ChangeDir(ePath);
IdFTP.List(eStr, '', False);
if eStr.IndexOf('gameinfo.txt') = -1 then begin
MessageBox(Handle, 'Invalid directory. Please select your mod directory and try again.', PChar(Application.Title), MB_ICONWARNING);
eStr.Free;
exit;
end
else
eStr.Free;
// design stuff
trvDirectories.Enabled := False;
cmdConnect.Enabled := False;
optWindows.Enabled := False;
optLinux.Enabled := False;
Screen.Cursor := crHourGlass;
if optWindows.Checked then
eOS := osWindows
else if optLinux.Checked then
eOS := osLinux;
jspInstallProgress.Show;
// installation
Screen.Cursor := crAppStart;
InstallFTP(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;
ePath := lstMods.Items[lstMods.ItemIndex];
if ePath = 'Counter-Strike:Source' then
ePath := 'cstrike'
else if ePath = 'Day of Defeat:Source' then
ePath := 'dod'
else
ePath := 'hl2mp';
// install it
if frbDedicatedServer.Checked then begin
if DirectoryExists(SteamPath + ePath) then
InstallDedicated(IncludeTrailingPathDelimiter(SteamPath + ePath), 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(IncludeTrailingPathDelimiter(StandaloneServer + ePath), 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
ePath := lstMods.Items[lstMods.ItemIndex];
if ePath = 'Counter-Strike:Source' then
ePath := SteamPath + 'counter-strike source\cstrike'
else if ePath = 'Half-Life 2 Deathmatch' then
ePath := SteamPath + 'half-life 2 deathmatch\hl2mp'
else
ePath := SteamPath + 'Day Of Defeat source\dod';
if Pos(SteamPath, ePath) = 0 then
MessageBox(Handle, 'An error occured. Please report this bug to the Metamod:Source team and post a new thread on the forums of www.amxmodx.org.', PChar(Application.Title), MB_ICONSTOP)
else begin
if not FileExists(ePath + '\gameinfo.txt') then begin
MessageBox(Handle, 'You have to play this game once before installing Metamod:Source. Do this and try again.', PChar(Application.Title), MB_ICONWARNING);
exit;
end;
jspInstallProgress.Show;
ePath := IncludeTrailingPathDelimiter(ePath);
InstallListen(ePath);
end;
end;
{ Custom mod below }
end
else if jplWizard.ActivePage <> jspInstallMethod then
jplWizard.NextPage
else begin
if frbDedicatedServer.Checked then begin // Dedicated Server
eRegistry := TRegistry.Create(KEY_READ);
try
eRegistry.RootKey := HKEY_CURRENT_USER;
if eRegistry.OpenKey('Software\Valve\Steam', False) then begin
ePath := eRegistry.ReadString('ModInstallPath');
ePath := Copy(ePath, 1, Length(ePath) -10) + '\source dedicated server\';
if DirectoryExists(ePath) then begin
SteamPath := ePath;
lstMods.Clear;
// Check Mods
if DirectoryExists(SteamPath + 'cstrike') then
lstMods.Items.Add('Counter-Strike:Source');
if DirectoryExists(SteamPath + 'dod') then
lstMods.Items.Add('Day of Defeat:Source');
if DirectoryExists(SteamPath + 'hl2mp') then
lstMods.Items.Add('Half-Life 2 Deatmatch');
// Misc
jspSelectMod.Show;
lstMods.ItemIndex := -1;
cmdNext.Enabled := False;
end
else
MessageBox(Handle, 'You have to run Dedicated Server once before installing Metamod:Source!', 'Error', MB_ICONWARNING);
end
else
MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING);
finally
eRegistry.Free;
end;
end
else if frbListenServer.Checked then begin // Listen Server
eRegistry := TRegistry.Create(KEY_READ);
try
eRegistry.RootKey := HKEY_CURRENT_USER;
if eRegistry.OpenKey('Software\Valve\Steam', False) then begin
ePath := eRegistry.ReadString('ModInstallPath') + '\';
lstMods.Clear;
ePath := Copy(ePath, 1, Length(ePath) -10);
if DirectoryExists(ePath) then begin
SteamPath := ePath;
// Check Mods
if DirectoryExists(SteamPath + 'counter-strike source') then
lstMods.Items.Add('Counter-Strike:Source');
if DirectoryExists(SteamPath + 'half-life 2 deathmatch') then
lstMods.Items.Add('Half-Life 2 Deathmatch');
if DirectoryExists(SteamPath + 'Day Of Defeat source') then
lstMods.Items.Add('Day of Defeat: Source');
// Misc
jspSelectMod.Show;
lstMods.ItemIndex := -1;
cmdNext.Enabled := False;
end
else
MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING);
end
else
MessageBox(Handle, 'You haven''t installed Steam yet! Download it at www.steampowered.com, install Dedicated Server and try again.', 'Error', MB_ICONWARNING);
finally
eRegistry.Free;
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 + 'cstrike') then
lstMods.Items.Add('Counter-Strike:Source');
if DirectoryExists(StandaloneServer + 'dod') then
lstMods.Items.Add('Day of Defeat:Source');
if DirectoryExists(StandaloneServer + 'hl2mp') then
lstMods.Items.Add('Half-Life 2 Deatmatch');
jspSelectMod.Show;
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;
InstallCustom(IncludeTrailingPathDelimiter(frmSelectModPath.trvDirectory.SelectedFolder.PathName), osWindows);
end;
end
else if frbFTP.Checked then // FTP
jspFTP.Show;
end;
end;
procedure TfrmMain.CheckNext(Sender: TObject);
begin
cmdNext.Enabled := frbAgree.Checked;
end;
procedure TfrmMain.cmdBackClick(Sender: TObject);
begin
if jplWizard.ActivePage = jspFTP then
jspInstallMethod.Show
else begin
jplWizard.PrevPage;
cmdBack.Visible := jplWizard.ActivePageIndex <> 0;
end;
end;
procedure TfrmMain.cmdConnectClick(Sender: TObject);
var i: integer;
eStr: TStringList;
CurNode: TTreeNode;
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...';
// ... 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);
// ... scan for initial directory ...
eStr := TStringList.Create;
eStr.Text := StringReplace(IdFTP.RetrieveCurrentDir, '/', #13, [rfReplaceAll]);
for i := eStr.Count -1 downto 0 do begin
if eStr[i] = '' then
eStr.Delete(i);
end;
// ... connect successful, change captions ...
trvDirectories.Enabled := True;
cmdConnect.Enabled := True;
cmdConnect.Caption := 'Disconnect';
CurNode := nil;
if eStr.Count <> 0 then begin
for i := 0 to eStr.Count -1 do
CurNode := trvDirectories.Items.AddChild(CurNode, eStr[i]);
end;
if trvDirectories.Items.Count <> 0 then
trvDirectories.Items.Item[0].Expand(True);
eStr.Free;
// ... scan for directories ...
with GetAllDirs do begin
for i := 0 to Count -1 do
trvDirectories.Items.AddChild(trvDirectories.Items.AddChild(CurNode, Strings[i]), 'Scanning...');
Free;
end;
if Assigned(CurNode) then
CurNode.Expand(False);
except
on E: Exception do begin
// 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';
// 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 ...
Screen.Cursor := crDefault;
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';
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(ParamStr(0)) + 'FTP.log';
IdLogFile.Active := True;
end;
rtfDetails.Clear;
end;
procedure TfrmMain.lstModsClick(Sender: TObject);
begin
cmdNext.Enabled := lstMods.ItemIndex <> -1;
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);
var ePath: String;
CurNode: TTreeNode;
i: integer;
begin
if Node.Item[0].Text = 'Scanning...' then begin // no directories added yet
Screen.Cursor := crHourGlass;
// get complete path
ePath := '/';
CurNode := Node;
repeat
ePath := '/' + CurNode.Text + ePath;
CurNode := CurNode.Parent;
until (not Assigned(CurNode));
// change dir and add directories in it
try
Repaint;
IdFTP.ChangeDir(ePath);
with GetAllDirs do begin
Node.Item[0].Free;
for i := 0 to Count -1 do begin
trvDirectories.Items.AddChild(trvDirectories.Items.AddChild(Node, Strings[i]), 'Scanning...');
end;
Free;
end;
finally
Application.ProcessMessages;
end;
Screen.Cursor := crDefault;
end;
end;
procedure TfrmMain.trvDirectoriesChange(Sender: TObject; Node: TTreeNode);
begin
cmdNext.Enabled := Assigned(trvDirectories.Selected);
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
Action := caNone;
end;
end;
procedure TfrmMain.ExceptionHandler(Sender: TObject; E: Exception);
begin
// IF any exceptions were raised after close, nobody would want them 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;
end.

BIN
installer/UnitfrmProxy.dfm Normal file

Binary file not shown.

View File

@ -0,0 +1,72 @@
unit UnitfrmProxy;
interface
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, TFlatButtonUnit, TFlatComboBoxUnit,
TFlatEditUnit;
type
TfrmProxy = class(TForm)
cmdClose: TFlatButton;
lblProxy: TLabel;
txtHost: TFlatEdit;
cboProxy: TFlatComboBox;
lblHost: TLabel;
txtPort: TFlatEdit;
lblPort: TLabel;
lblUsername: TLabel;
txtUsername: TFlatEdit;
txtPassword: TFlatEdit;
lblPassword: TLabel;
procedure cboProxyChange(Sender: TObject);
procedure txtPortChange(Sender: TObject);
public
procedure EnableControls(Enable: Boolean);
end;
var
frmProxy: TfrmProxy;
implementation
{$R *.DFM}
{ TfrmProxy }
procedure TfrmProxy.EnableControls(Enable: Boolean);
begin
lblHost.Enabled := Enable;
lblPassword.Enabled := Enable;
lblPort.Enabled := Enable;
lblUsername.Enabled := Enable;
txtHost.Enabled := Enable;
txtPassword.Enabled := Enable;
txtPort.Enabled := Enable;
txtUsername.Enabled := Enable;
end;
procedure TfrmProxy.cboProxyChange(Sender: TObject);
begin
EnableControls(cboProxy.ItemIndex <> 0); // 0 = None
end;
procedure TfrmProxy.txtPortChange(Sender: TObject);
var i: integer;
begin
if txtPort.Text = '' then
txtPort.Text := '8080'
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 := '8080';
txtPort.SelStart := 4;
exit;
end;
end;
end;
end;
end.

13
installer/del.bat Normal file
View File

@ -0,0 +1,13 @@
del .\*.~pas
del .\*.dcu
del .\*.~ddp
del .\*.ddp
del .\*.~dpr
del .\*.~dfm
del .\*.~dpr
del .\*.map
del .\*.drc
del .\*.~xfm
del .\*.log
upx MMS_Installer.exe
upx Attach.exe

View File

@ -0,0 +1,7 @@
In this folder should be server.dll and server_i486.so.
How you prepare a release:
1) Copy the lastest server.dll and server_i486.so in this folder
2) Run Attach.exe
3) Test MMS_Installer.exe once (should work but nobody wants bug releases, especially not in the installer)
4) If everything worked fine, release it, otherwise pm me (Basic-Master)

BIN
installer/install.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
installer/upx.exe Normal file

Binary file not shown.