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, ShellAPI, StrUtils, fSettings, fAI, fNotify, fAutoActions, FMX.ListBox, fLog, uRecords, System.IOUtils, fCommands, uDataBase, FMX.Edit, FMX.Colors, FMX.SpinBox, windows, System.Skia, FMX.Skia, uCreateChat, uCreateNotify, fOBS; type TTTW_Bot = class(TForm) V: TTabControl; TabItem1: TTabItem; TabItem2: TTabItem; TabItem3: TTabItem; TabItem4: TTabItem; frSettings1: 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; frAutoActions1: TfrAutoActions; frOBS1: TfrOBS; frLog1: TfrLog; cbTheme: TComboBox; Label15: TLabel; frCommands1: TfrCommands; SpeedButton1: TSpeedButton; SpeedButton2: TSpeedButton; SpeedButton3: TSpeedButton; btnCreateChat: TButton; procedure cbThemeChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton3Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); procedure frChatOBS1btnCreateChatClick(Sender: TObject); procedure frOBS1btnCreateOBSNotifyClick(Sender: TObject); procedure frOBS1btnCreateOBSKandinskyClick(Sender: TObject); procedure frSettings1btnDAStartClick(Sender: TObject); procedure frCommands1btnRandAddClick(Sender: TObject); private { Private declarations } procedure ReadDB(); public { Public declarations } end; var TTW_Bot: TTTW_Bot; myConst: TConst; db: TSettingsDatabase; appconst: TBotAppCfg; implementation {$R *.fmx} procedure TTTW_Bot.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 TTTW_Bot.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; frCommands1.frsgSounds.ObjectRecord:=frCommands1.listSounds; frCommands1.frsgSounds.TableName:='listSounds'; frCommands1.frsgSounds.UpdateGrid; frCommands1.frsgFiles.ObjectRecord:=frCommands1.listFiles; frCommands1.frsgFiles.TableName:='listFiles'; frCommands1.frsgFiles.UpdateGrid; frCommands1.frsgNeiro.ObjectRecord:=frCommands1.listNeiro; frCommands1.frsgNeiro.TableName:='listNeiro'; frCommands1.frsgNeiro.UpdateGrid; for Path in TDirectory.GetFiles(myConst.stlPath) do cbTheme.Items.Add(ExtractFileName(Path)); cbTheme.ItemIndex := strtoint(db.ReadSetting('cbTheme', '-1')); end; procedure TTTW_Bot.frChatOBS1btnCreateChatClick(Sender: TObject); begin fCreateChat.Show; end; procedure TTTW_Bot.frCommands1btnRandAddClick(Sender: TObject); begin frCommands1.btnRandAddClick(Sender); end; procedure TTTW_Bot.frOBS1btnCreateOBSKandinskyClick(Sender: TObject); var dport:integer; I: Integer; begin dport:=8080; for I := 0 to frOBS1.sgWebChats.RowCount-1 do begin if strtoint(frOBS1.sgWebChats.Cells[0,i]) >= dport then dport:=strtoint(frOBS1.sgWebChats.Cells[0,i])+1; end; frOBS1.sgWebChats.RowCount:=frOBS1.sgWebChats.RowCount+1; frOBS1.sgWebChats.Cells[0,frOBS1.sgWebChats.RowCount-1]:=inttostr(dport); frOBS1.sgWebChats.Cells[1,frOBS1.sgWebChats.RowCount-1]:='Kandinsky'; frOBS1.sgWebChats.Cells[2,frOBS1.sgWebChats.RowCount-1]:='http://127.0.0.1:'+inttostr(dport); end; procedure TTTW_Bot.frOBS1btnCreateOBSNotifyClick(Sender: TObject); begin fCreateNotify.Show; end; procedure TTTW_Bot.frSettings1btnDAStartClick(Sender: TObject); begin frSettings1.btnDAStartClick(Sender); end; procedure TTTW_Bot.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; // Загрузка компонентов настроек (TEdit, TCheckBox) procedure LoadSettingsComponents; var I: Integer; c: TComponent; begin for I := 0 to frSettings1.ComponentCount - 1 do begin c := frSettings1.Components[I]; if c is TEdit then TEdit(c).text := db.ReadSetting(TEdit(c).Name) else if c is TCheckBox then TCheckBox(c).IsChecked := (db.ReadSetting(TCheckBox(c).Name) = 'True'); end; db.FChannel := frSettings1.edtChannel.text; end; // Загрузка данных в гриды команд procedure LoadGridsData; begin DB.LoadRecordArray('RandomCounters', frCommands1.RandomCounters); DB.LoadRecordArray('listSounds', frCommands1.listSounds); DB.LoadRecordArray('listFiles', frCommands1.listFiles); DB.LoadRecordArray('listNeiro', frCommands1.listNeiro); DB.LoadRecordArray('listCommands', frCommands1.listCommands); frCommands1.UpdateGridFromArray; { 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); } end; // Загрузка списка групп procedure LoadGroupNames; begin db.getGroupName(frCommands1.lbRandomGroup.Items); end; // Загрузка зашифрованного конфига procedure LoadEncryptedConfig; var sl: TStringList; I: Integer; begin if not FileExists(myConst.cfg1) then Exit; 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 appconst.TTV_ClientID := Value else if Key = 'k2' then appconst.AI_GigaChat_AC := Value else if Key = 'k3' then appconst.AI_GigaChat_ClientID := Value else if Key = 'k4' then appconst.AI_ChatGPT_Token := Value else if Key = 'k5' then appconst.AI_DeepSeec_Token := Value else if Key = 'k6' then appconst.DA_ClientID := Value else if Key = 'k7' then appconst.DA_Sicret := Value else if Key = 'k8' then appconst.DA_URL := Value; end; end; frSettings1.btnGetClientID.Visible := (appconst.TTV_ClientID <> ''); frAI1.btnGetAIDef.Visible := ((appconst.AI_GigaChat_AC <> '') and (appconst.AI_GigaChat_ClientID <> '')) or (appconst.AI_ChatGPT_Token <> '') or (appconst.AI_DeepSeec_Token <> ''); frSettings1.btnGetDADef.Visible := (appconst.DA_ClientID <> '') and (appconst.DA_Sicret <> '') and (appconst.DA_URL <> ''); finally sl.Free; end; end; // Загрузка настроек уведомлений procedure LoadNotifySettings; var I: Integer; c: TComponent; begin for I := 0 to frNotify1.ComponentCount - 1 do begin c := frNotify1.Components[I]; if c is TEdit then TEdit(c).text := db.ReadSetting(TEdit(c).Name) else if c is TCheckBox then TCheckBox(c).IsChecked := (db.ReadSetting(TCheckBox(c).Name) = 'True') else if c is TSwitch then TSwitch(c).IsChecked := (db.ReadSetting(TSwitch(c).Name) = 'True') else if c is TTrackBar then TTrackBar(c).Value := strtoint(db.ReadSetting(TTrackBar(c).Name, '100')); end; end; // Загрузка настроек ИИ procedure LoadAISettings; var I: Integer; c: TComponent; ii: Integer; // Настройки GigaChat procedure SetupGigaChatSettings; 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.Visible := False; end; // Настройки DeepSeek procedure SetupDeepSeekSettings; begin frAI1.rbDS.IsChecked := True; frAI1.Label45.text := 'API Token'; frAI1.Label47.text := ''; frAI1.Label1.Visible := False; frAI1.edtAIP2.Visible := False; frAI1.edtAIP3.Visible := False; frAI1.cbOllama.Visible := False; end; // Настройки ChatGPT procedure SetupChatGPTSettings; begin frAI1.rbCG.IsChecked := True; frAI1.Label45.text := 'API Token'; frAI1.Label47.text := ''; frAI1.Label1.Visible := False; frAI1.edtAIP2.Visible := False; frAI1.edtAIP3.Visible := False; frAI1.cbOllama.Visible := False; end; // Настройки кастомного ИИ procedure SetupCustomAISettings; 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.Visible := True; frAI1.cbOllama.IsChecked := db.ReadSetting(frAI1.cbOllama.Name) = '1'; end; begin for I := 0 to frAI1.ComponentCount - 1 do begin c := frAI1.Components[I]; if c is TEdit then TEdit(c).text := db.ReadSetting(TEdit(c).Name) else if c is TCheckBox then TCheckBox(c).IsChecked := db.ReadSetting(TCheckBox(c).Name) = '1'; end; ii := strtoint(db.ReadSetting('aiIndex', '0')); case ii of 0: SetupGigaChatSettings; 1: SetupDeepSeekSettings; 2: SetupChatGPTSettings; 3: SetupCustomAISettings; end; frSettings1.init; end; // Загрузка гридов автоматических действий procedure LoadAutoActionsGrids; begin db.LoadGridFromTable('sgTimers', frAutoActions1.sgTimers); db.LoadGridFromTable('sgCounter', frAutoActions1.sgCounter); db.LoadGridFromTable('sgBanWords', frAutoActions1.sgBanWords); end; begin LoadSettingsComponents; LoadGridsData; LoadGroupNames; LoadEncryptedConfig; LoadNotifySettings; LoadAISettings; LoadAutoActionsGrids; end; procedure TTTW_Bot.SpeedButton1Click(Sender: TObject); begin ShellExecute(0, 'open', pwidechar('https://www.twitch.tv/incadence'), nil, nil, 1); end; procedure TTTW_Bot.SpeedButton2Click(Sender: TObject); begin // https://www.twitch.tv/kuznecogr ShellExecute(0, 'open', pwidechar('https://www.twitch.tv/kuznecogr'), nil, nil, 1); end; procedure TTTW_Bot.SpeedButton3Click(Sender: TObject); begin // https://www.flaticon.com/ru/authors/karacis ShellExecute(0, 'open', pwidechar('https://www.flaticon.com/ru/authors/karacis'), nil, nil, 1); end; end.