unit uGeneral; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl, FMX.Controls.Presentation, FMX.StdCtrls, System.ImageList, FMX.ImgList, FMX.Styles, fSettings, fAI, fNotify, fAutoActions, fChatOBS, FMX.ListBox, fLog, uRecords, System.IOUtils, fCommands, uDataBase, FMX.Edit, FMX.Colors, FMX.SpinBox, windows; type TForm1 = class(TForm) V: TTabControl; TabItem1: TTabItem; TabItem2: TTabItem; TabItem3: TTabItem; TabItem4: TTabItem; fSettings: TfrSettings; ImageList1: TImageList; TabItem5: TTabItem; Panel1: TPanel; btnConnecting: TButton; Label2: TLabel; Label3: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; aiConnecting: TAniIndicator; Label9: TLabel; Label10: TLabel; Label11: TLabel; Label12: TLabel; frAI1: TfrAI; TabItem6: TTabItem; TabItem7: TTabItem; TabItem8: TTabItem; TabItem9: TTabItem; frNotify1: TfrNotify; Label1: TLabel; Label4: TLabel; Label13: TLabel; Label14: TLabel; frAutoActions1: TfrAutoActions; frChatOBS1: TfrChatOBS; frLog1: TfrLog; cbTheme: TComboBox; Label15: TLabel; frCommands1: TfrCommands; procedure Label14DblClick(Sender: TObject); procedure Label13DblClick(Sender: TObject); procedure Label4DblClick(Sender: TObject); procedure cbThemeChange(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } procedure ReadDB(); public { Public declarations } end; var Form1: TForm1; myConst: TConst; db: TSettingsDatabase; appconst: TBotAppCfg; implementation {$R *.fmx} procedure TForm1.cbThemeChange(Sender: TObject); begin cbTheme.ItemIndex := cbTheme.Items.IndexOf(cbTheme.text); if cbTheme.ItemIndex <> -1 then TStyleManager.SetStyleFromFile(myConst.stlPath + cbTheme.text); // db.WriteSetting('cbTheme', inttostr(cbTheme.ItemIndex)); end; procedure TForm1.FormCreate(Sender: TObject); var Path: string; SearchRec: TSearchRec; function GetPathToTestExe: string; // вернет папку romaming begin Result := GetEnvironmentVariable('APPDATA'); if Result <> '' then Result := IncludeTrailingPathDelimiter(Result); end; begin myConst.GeneralPath := ExtractFilePath(ParamStr(0)); myConst.AppDataPath := GetPathToTestExe + 'TTW_Bot\'; if not DirectoryExists(myConst.AppDataPath) then CreateDir(myConst.AppDataPath); myConst.DBPath := myConst.AppDataPath + 'settings.db'; if not DirectoryExists(myConst.AppDataPath + 'fonts') then CreateDir(myConst.AppDataPath + 'fonts'); myConst.fontsPath := myConst.AppDataPath + 'fonts\'; if not DirectoryExists(myConst.AppDataPath + 'imgs') then CreateDir(myConst.AppDataPath + 'imgs'); myConst.imgsPath := myConst.AppDataPath + 'imgs\'; if not DirectoryExists(myConst.AppDataPath + 'sounds') then CreateDir(myConst.AppDataPath + 'sounds'); myConst.soundsPath := myConst.AppDataPath + 'sounds\'; if not DirectoryExists(myConst.AppDataPath + 'stl') then CreateDir(myConst.AppDataPath + 'stl'); myConst.stlPath := myConst.AppDataPath + 'stl\'; if not DirectoryExists(myConst.AppDataPath + 'ytSongs') then CreateDir(myConst.AppDataPath + 'ytSongs'); myConst.ytSongsPath := myConst.AppDataPath + 'ytSongs\'; myConst.PublicPlay := myConst.GeneralPath + 'PublicPlay.exe'; myConst.SilentPlay := myConst.GeneralPath + 'SilentPlayer.exe'; myConst.ytPlay := myConst.GeneralPath + 'Player.exe'; myConst.cfg1 := myConst.GeneralPath + 'botapp.cfg'; db := TSettingsDatabase.Create(myConst.DBPath); ReadDB; for Path in TDirectory.GetFiles(myConst.stlPath) do cbTheme.Items.Add(ExtractFileName(Path)); cbTheme.ItemIndex := strtoint(db.ReadSetting('cbTheme', '-1')); end; procedure TForm1.Label13DblClick(Sender: TObject); begin // https://www.twitch.tv/kuznecogr end; procedure TForm1.Label14DblClick(Sender: TObject); begin // https://www.flaticon.com/ru/authors/karacis end; procedure TForm1.Label4DblClick(Sender: TObject); begin // https://www.twitch.tv/incadence end; procedure TForm1.ReadDB; var I: Integer; c: TComponent; sl: TStringList; SavedColor: TAlphaColor; ColorStr: string; function XorDecryptToStrings(const InputFile, Key: string): TStrings; var InStream: TFileStream; MemStream: TMemoryStream; KeyBytes: TBytes; KeyLen, KeyIndex: Integer; B: Byte; begin // Преобразуем ключ в байты с использованием ANSI кодировки KeyBytes := TEncoding.ANSI.GetBytes(Key); KeyLen := Length(KeyBytes); if KeyLen = 0 then raise Exception.Create('Ключ не может быть пустым'); InStream := TFileStream.Create(InputFile, fmOpenRead); try MemStream := TMemoryStream.Create; try KeyIndex := 0; // Расшифровываем данные и записываем в поток в памяти while InStream.Position < InStream.Size do begin InStream.ReadBuffer(B, 1); B := B xor KeyBytes[KeyIndex]; MemStream.WriteBuffer(B, 1); KeyIndex := (KeyIndex + 1) mod KeyLen; end; // Преобразуем данные из потока в TStrings MemStream.Position := 0; // Сбрасываем позицию для чтения Result := TStringList.Create; try // Используем ANSI кодировку для преобразования байтов в строку Result.LoadFromStream(MemStream, TEncoding.ANSI); except // В случае ошибки освобождаем ресурсы и пробрасываем исключение Result.Free; raise; end; finally MemStream.Free; end; finally InStream.Free; end; end; begin for I := 0 to fSettings.ComponentCount - 1 do begin c := fSettings.components[I]; if c is TEdit then begin TEdit(c).text := db.ReadSetting(TEdit(c).Name); end; if c is TCheckBox then begin TCheckBox(c).IsChecked := (db.ReadSetting(TCheckBox(c).Name) = 'True'); end; end; db.FChannel := fSettings.edtChannel.text; db.LoadGridFromTable('sgRandomInt', frCommands1.sgRandomInt); db.LoadGridFromTable('sgCommands', frCommands1.sgCommands); db.LoadGridFromTable('sgSAFiles', frCommands1.sgSAFiles); db.LoadGridFromTable('sgTFiles', frCommands1.sgTFiles); db.LoadGridFromTable('sgAIGen', frCommands1.sgAIGen); db.getGroupName(frCommands1.lbRandomGroup.Items); if FileExists(myConst.cfg1) then begin sl := TStringList.Create; try sl.Assign(XorDecryptToStrings(myConst.cfg1, 'fgvasrgEFAXFAFAS')); for I := 0 to sl.Count - 1 do begin var eqPos := Pos('=', sl[I]); if eqPos > 0 then begin var Key := Trim(Copy(sl[I], 1, eqPos - 1)); var Value := Trim(Copy(sl[I], eqPos + 1, MaxInt)); // Распределяем значения по переменным if Key = 'k1' then begin appconst.TTV_ClientID := Value; end else if Key = 'k2' then begin appconst.AI_GigaChat_AC := Value; end else if Key = 'k3' then begin appconst.AI_GigaChat_ClientID := Value; end else if Key = 'k4' then begin appconst.AI_ChatGPT_Token := Value; end else if Key = 'k5' then begin appconst.AI_DeepSeec_Token := Value; end else if Key = 'k6' then begin appconst.DA_ClientID := Value; end else if Key = 'k7' then begin appconst.DA_Sicret := Value; end else if Key = 'k8' then begin appconst.DA_URL := Value; end end; end; if appconst.TTV_ClientID <> '' then begin fSettings.btnGetClientID.Visible := True; end; if ((appconst.AI_GigaChat_AC <> '') and (appconst.AI_GigaChat_ClientID <> '')) or (appconst.AI_ChatGPT_Token <> '') or (appconst.AI_DeepSeec_Token <> '') then begin frAI1.btnGetAIDef.Visible := True; end; if ((appconst.DA_ClientID <> '') and (appconst.DA_Sicret <> '') and (appconst.DA_URL <> '')) then begin fSettings.btnGetDADef.Visible := True; end; finally sl.Free; end; end; for I := 0 to frChatOBS1.ComponentCount - 1 do begin c := frChatOBS1.components[I]; if c is TComboBox then begin TComboBox(c).ItemIndex := strtoint(db.ReadSetting(TComboBox(c).Name, '0')); end; if c is TColorComboBox then begin TColorComboBox(c).ItemIndex := strtoint(db.ReadSetting(TComboBox(c).Name, '147')); end; if c is TSpinBox then begin if TSpinBox(c).Name = 'sbWebServerPort' then TSpinBox(c).text := db.ReadSetting(TSpinBox(c).Name, '8080'); TSpinBox(c).text := db.ReadSetting(TSpinBox(c).Name, '1'); end; if c is TCheckBox then begin TCheckBox(c).IsChecked := db.ReadSetting(TCheckBox(c).Name, '0') = '1'; end; end; ColorStr := db.ReadSetting('cpStyleBlockColor', 'FF000000'); if TryStrToUInt('$' + ColorStr, Cardinal(SavedColor)) then frChatOBS1.cpStyleBlockColor.Color := SavedColor else frChatOBS1.cpStyleBlockColor.Color := TAlphaColorRec.Black; if not DirectoryExists(myConst.fontsPath) then CreateDirectory(PChar(myConst.fontsPath), 0); var n := 1; var cDir := myConst.fontsPath; // Искать в папке с программой var FileName := '*.*'; // Ищем все файлы ChDir(cDir); // войти в каталог var SearchRec: TSearchRec; if FindFirst(FileName, faArchive, SearchRec) = 0 then repeat if (SearchRec.Attr and faAnyFile) = SearchRec.Attr then begin frChatOBS1.cbFontStyleDefault.Items.Add(SearchRec.Name); Inc(n); end; until FindNext(SearchRec) <> 0; ChDir('..'); for I := 0 to frNotify1.ComponentCount - 1 do begin c := frNotify1.components[I]; if c is TEdit then begin TEdit(c).text := db.ReadSetting(TEdit(c).Name); end; if c is TCheckBox then begin TCheckBox(c).IsChecked := (db.ReadSetting(TCheckBox(c).Name) = 'True'); end; if c is TSwitch then begin TSwitch(c).IsChecked := (db.ReadSetting(TSwitch(c).Name) = 'True'); end; if c is TTrackBar then begin TTrackBar(c).Value := strtoint(db.ReadSetting(TTrackBar(c).Name, '100')); end; end; var ii: Integer; for I := 0 to frAI1.ComponentCount - 1 do begin c := frAI1.components[I]; if c is TEdit then begin TEdit(c).text := db.ReadSetting(TEdit(c).Name); end; if c is TCheckBox then begin TCheckBox(c).IsChecked := db.ReadSetting(TCheckBox(c).Name) = '1'; end; end; ii := strtoint(db.ReadSetting('aiIndex', '0')); case ii of 0: begin frAI1.rbGC.IsChecked := True; frAI1.Label45.text := 'ClientID'; frAI1.Label47.text := 'Autorization Code'; frAI1.Label1.Visible := false; frAI1.edtAIP2.Visible := True; frAI1.edtAIP2.Password := True; frAI1.edtAIP3.Visible := false; frAI1.cbOllama.IsChecked := false; frAI1.cbOllama.Visible := false; end; 1: begin frAI1.rbDS.IsChecked := True; frAI1.Label45.text := 'API Token'; frAI1.Label47.text := ''; frAI1.Label1.Visible := false; frAI1.edtAIP2.Visible := false; frAI1.edtAIP2.Password := false; frAI1.edtAIP3.Visible := false; frAI1.cbOllama.IsChecked := false; frAI1.cbOllama.Visible := false; end; 2: begin frAI1.rbCG.IsChecked := True; frAI1.Label45.text := 'API Token'; frAI1.Label47.text := ''; frAI1.Label1.Visible := false; frAI1.edtAIP2.Visible := false; frAI1.edtAIP2.Password := false; frAI1.edtAIP3.Visible := false; frAI1.cbOllama.IsChecked := false; frAI1.cbOllama.Visible := false; end; 3: begin frAI1.RBCustom.IsChecked := True; frAI1.Label45.text := 'API Token'; frAI1.Label47.text := 'URL'; frAI1.Label1.Visible := True; frAI1.edtAIP2.Visible := True; frAI1.edtAIP2.Password := false; frAI1.edtAIP3.Visible := True; frAI1.cbOllama.IsChecked := db.ReadSetting(frAI1.cbOllama.Name) = '1'; frAI1.cbOllama.Visible := True; end; end; db.LoadGridFromTable('sgTimers', frAutoActions1.sgTimers); db.LoadGridFromTable('sgCounter', frAutoActions1.sgCounter); db.LoadGridFromTable('sgBanWords', frAutoActions1.sgBanWords); end; end.