From 2518f9326eead135f8ac1d417e668cc608228bcd Mon Sep 17 00:00:00 2001 From: "PC1\\PTyTb" Date: Fri, 12 Sep 2025 14:01:38 +0300 Subject: [PATCH] =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=89=D0=B8=D0=BA=20=D1=83=D0=BC=D0=B5=D0=B5=D1=82=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B3=D1=80=D1=83=D0=B6=D0=B0=D1=82=D1=8C=20=D0=BD=D1=83?= =?UTF-8?q?=D0=B6=D0=BD=D1=8B=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- forms/install_Script.iss | 259 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 246 insertions(+), 13 deletions(-) diff --git a/forms/install_Script.iss b/forms/install_Script.iss index 3f595d0..797f852 100644 --- a/forms/install_Script.iss +++ b/forms/install_Script.iss @@ -1,6 +1,6 @@ -; Script generated by the Inno Setup Script Wizard. +; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - + #define MyAppName "TTW_Bot" #define MyAppExeName "TTW_Bot_app.exe" #define MyAppDir "C:\Delphi\d12\ttw_fmx_v10" @@ -12,16 +12,12 @@ #define MyAppAssocExt ".myp" #define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt - [Setup] -; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. -; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) LicenseFile={#MyAppDir}\license.rtf DisableWelcomePage=no -AppId={{81A4FB77-4AE5-4FAC-A889-CA3CA7B8C687} +AppId={{81A4FB77-4AE5-4FAC-A889-CA3CA7B8C687}} AppName={#MyAppName} AppVersion={#MyAppVersion} -;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} @@ -30,8 +26,6 @@ DefaultDirName={autopf}\{#MyAppName} ChangesAssociations=yes DisableDirPage=auto DisableProgramGroupPage=auto -; Uncomment the following line to run in non administrative install mode (install for current user only.) -;PrivilegesRequired=lowest OutputDir={#MyAppDir}\Win32\installer OutputBaseFilename=TTW_Bot_setup SetupIconFile={#MyAppDir}\install.ico @@ -43,26 +37,51 @@ WizardStyle=modern Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"; LicenseFile: "{#MyAppDir}\license.rtf" [Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" + +Name: "install_ytdlp"; Description: "Установить yt-dlp"; GroupDescription: "Компоненты для воспроизведения музыки по ссылке" +Name: "install_ffmpeg"; Description: "Установить ffmpeg"; GroupDescription: "Компоненты для воспроизведения музыки по ссылке" + +Name: "install_ru_irina"; Description: "Скачать Ру голос Ирина"; GroupDescription: "Модели голосов для озвучки" +Name: "install_ru_denis"; Description: "Скачать Ру голос Денис"; GroupDescription: "Модели голосов для озвучки" +Name: "install_ru_dmitri"; Description: "Скачать Ру голос Дмитрий"; GroupDescription: "Модели голосов для озвучки" +Name: "install_ru_ruslan"; Description: "Скачать Ру голос Руслан"; GroupDescription: "Модели голосов для озвучки" [Files] Source: "{#MyAppDir}\Win32\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\bass.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\botapp.cfg"; DestDir: "{app}"; Flags: ignoreversion -;Source: "{#MyAppDir}\Win32\Release\ffmpeg.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\libcrypto-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\libeay32.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\libssl-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\libssl32.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\SilentPlayer.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "{#MyAppDir}\Win32\Release\yt-dlp.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}\Win32\Release\stl\*"; DestDir: "{userappdata}\TTW_Bot\stl"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyAppDir}\Win32\Release\piper\*"; DestDir: "{app}\piper"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyAppDir}\Win32\Release\games\*"; DestDir: "{app}\games"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyAppDir}\license.rtf"; DestDir: "{app}"; Flags: ignoreversion -; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +Source: "{#MyAppDir}\unzip.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall dontcopy +Source: "{tmp}\yt-dlp.exe"; DestDir: "{app}"; Flags: external deleteafterinstall; Tasks: install_ytdlp +Source: "{tmp}\ffmpeg.zip"; DestDir: "{app}"; Flags: external deleteafterinstall; Tasks: install_ffmpeg + +; Голос Ирины +Source: "{tmp}\ru_RU-irina-medium.onnx"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_irina +Source: "{tmp}\ru_RU-irina-medium.onnx.json"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_irina + +; Голос Дениса +Source: "{tmp}\ru_RU-denis-medium.onnx"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_denis +Source: "{tmp}\ru_RU-denis-medium.onnx.json"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_denis + +; Голос Дмитрия +Source: "{tmp}\ru_RU-dmitri-medium.onnx"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_dmitri +Source: "{tmp}\ru_RU-dmitri-medium.onnx.json"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_dmitri + +; Голос Руслана +Source: "{tmp}\ru_RU-ruslan-medium.onnx"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_ruslan +Source: "{tmp}\ru_RU-ruslan-medium.onnx.json"; DestDir: "{userappdata}\TTW_Bot\Voices"; Flags: external; Tasks: install_ru_ruslan [Registry] Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue @@ -79,7 +98,24 @@ Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: de Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent [Code] +var + DownloadPage: TDownloadWizardPage; + +function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean; +begin + if Progress = ProgressMax then + Log(Format('Успешно загружено: %s', [FileName])); + Result := True; +end; + +procedure InitializeWizard; +begin + DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress); +end; + function NextButtonClick(CurPageID: Integer): Boolean; +var + HasDownloads: Boolean; begin if CurPageID = wpLicense then begin @@ -87,6 +123,203 @@ begin if not Result then MsgBox('Вы должны принять условия лицензионного соглашения!', mbError, MB_OK); end + else if CurPageID = wpReady then + begin + HasDownloads := False; + DownloadPage.Clear; + + if WizardIsTaskSelected('install_ytdlp') then + begin + DownloadPage.Add('https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe', 'yt-dlp.exe', ''); + HasDownloads := True; + end; + + if WizardIsTaskSelected('install_ffmpeg') then + begin + DownloadPage.Add('https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip', 'ffmpeg.zip', ''); + HasDownloads := True; + end; + + // Добавляем загрузку голосов + if WizardIsTaskSelected('install_ru_irina') then + begin + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx?download=true', 'ru_RU-irina-medium.onnx', ''); + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx.json?download=true', 'ru_RU-irina-medium.onnx.json', ''); + HasDownloads := True; + end; + + if WizardIsTaskSelected('install_ru_denis') then + begin + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx?download=true', 'ru_RU-denis-medium.onnx', ''); + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx.json?download=true', 'ru_RU-denis-medium.onnx.json', ''); + HasDownloads := True; + end; + + if WizardIsTaskSelected('install_ru_dmitri') then + begin + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/dmitri/medium/ru_RU-dmitri-medium.onnx?download=true', 'ru_RU-dmitri-medium.onnx', ''); + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/dmitri/medium/ru_RU-dmitri-medium.onnx.json?download=true', 'ru_RU-dmitri-medium.onnx.json', ''); + HasDownloads := True; + end; + + if WizardIsTaskSelected('install_ru_ruslan') then + begin + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/ruslan/medium/ru_RU-ruslan-medium.onnx?download=true', 'ru_RU-ruslan-medium.onnx', ''); + DownloadPage.Add('https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/ruslan/medium/ru_RU-ruslan-medium.onnx.json?download=true', 'ru_RU-ruslan-medium.onnx.json', ''); + HasDownloads := True; + end; + + if HasDownloads then + begin + DownloadPage.Show; + try + DownloadPage.Download; + DownloadPage.Hide; + Result := True; + except + SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK); + Result := False; + end; + end + else + Result := True; + end else Result := True; +end; + +procedure InstallFiles; +var + ResultCode: Integer; + UnzipTool: string; + VoicesPath: string; + TempPath: string; + FindRec: TFindRec; + Found: Boolean; +begin + VoicesPath := ExpandConstant('{userappdata}\TTW_Bot\Voices'); + if not DirExists(VoicesPath) then + ForceDirectories(VoicesPath); + + + if WizardIsTaskSelected('install_ytdlp') then + begin + if FileExists(ExpandConstant('{tmp}\yt-dlp.exe')) then + begin + FileCopy(ExpandConstant('{tmp}\yt-dlp.exe'), ExpandConstant('{app}\yt-dlp.exe'), False); + Log('yt-dlp установлен'); + end + else + Log('Ошибка: yt-dlp.exe не найден во временной папке'); + end; + + if WizardIsTaskSelected('install_ffmpeg') then + begin + if FileExists(ExpandConstant('{tmp}\ffmpeg.zip')) then + begin + UnzipTool := ExpandConstant('{tmp}\unzip.exe'); + if not FileExists(UnzipTool) then + begin + ExtractTemporaryFile('unzip.exe'); + end; + + // Создаем временную папку для распаковки + TempPath := ExpandConstant('{tmp}\ffmpeg_temp'); + ForceDirectories(TempPath); + + // Распаковываем архив во временную папку + Exec(UnzipTool, '-o "' + ExpandConstant('{tmp}\ffmpeg.zip') + '" -d "' + TempPath + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + + // Ищем ffmpeg.exe в подпапках + Found := False; + if FindFirst(TempPath + '\*', FindRec) then + begin + try + repeat + if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and + (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + // Проверяем наличие ffmpeg.exe в папке bin + if FileExists(TempPath + '\' + FindRec.Name + '\bin\ffmpeg.exe') then + begin + FileCopy(TempPath + '\' + FindRec.Name + '\bin\ffmpeg.exe', + ExpandConstant('{app}\ffmpeg.exe'), False); + Log('ffmpeg.exe найден и скопирован из папки: ' + FindRec.Name); + Found := True; + Break; + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; + + if not Found then + Log('Ошибка: ffmpeg.exe не найден в распакованных файлах'); + + // Удаляем временную папку + DelTree(TempPath, True, True, True); + end + else + Log('Ошибка: ffmpeg.zip не найден во временной папке'); + end; + + if WizardIsTaskSelected('install_ru_irina') then + begin + if FileExists(ExpandConstant('{tmp}\ru_RU-irina-medium.onnx')) then + begin + FileCopy(ExpandConstant('{tmp}\ru_RU-irina-medium.onnx'), VoicesPath + '\ru_RU-irina-medium.onnx', False); + FileCopy(ExpandConstant('{tmp}\ru_RU-irina-medium.onnx.json'), VoicesPath + '\ru_RU-irina-medium.onnx.json', False); + Log('Голос Ирина установлен'); + end + else + Log('Ошибка: Голос Ирина не найден во временной папке'); + end; + + if WizardIsTaskSelected('install_ru_denis') then + begin + if FileExists(ExpandConstant('{tmp}\ru_RU-denis-medium.onnx')) then + begin + FileCopy(ExpandConstant('{tmp}\ru_RU-denis-medium.onnx'), VoicesPath + '\ru_RU-denis-medium.onnx', False); + FileCopy(ExpandConstant('{tmp}\ru_RU-denis-medium.onnx.json'), VoicesPath + '\ru_RU-denis-medium.onnx.json', False); + Log('Голос Денис установлен'); + end + else + Log('Ошибка: Голос Денис не найден во временной папке'); + end; + + if WizardIsTaskSelected('install_ru_dmitri') then + begin + if FileExists(ExpandConstant('{tmp}\ru_RU-dmitri-medium.onnx')) then + begin + FileCopy(ExpandConstant('{tmp}\ru_RU-dmitri-medium.onnx'), VoicesPath + '\ru_RU-dmitri-medium.onnx', False); + FileCopy(ExpandConstant('{tmp}\ru_RU-dmitri-medium.onnx.json'), VoicesPath + '\ru_RU-dmitri-medium.onnx.json', False); + Log('Голос Дмитрий установлен'); + end + else + Log('Ошибка: Голос Дмитрий не найден во временной папке'); + end; + + + + if WizardIsTaskSelected('install_ru_ruslan') then + begin + if FileExists(ExpandConstant('{tmp}\ru_RU-ruslan-medium.onnx')) then + begin + FileCopy(ExpandConstant('{tmp}\ru_RU-ruslan-medium.onnx'), VoicesPath + '\ru_RU-ruslan-medium.onnx', False); + FileCopy(ExpandConstant('{tmp}\ru_RU-ruslan-medium.onnx.json'), VoicesPath + '\ru_RU-ruslan-medium.onnx.json', False); + Log('Голос Руслан установлен'); + end + else + Log('Ошибка: Голос Руслан не найден во временной папке'); + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssPostInstall then + begin + InstallFiles; + end; end; \ No newline at end of file