ttw_fmx_v10/uGeneral.pas

507 lines
14 KiB
Plaintext
Raw Blame History

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, uMyTimer, uRecords,
System.Generics.Collections,
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 frSettings1btnDAStartClick(Sender: TObject);
procedure frCommands1btnRandAddClick(Sender: TObject);
procedure frOBS1btnDeleteeChatClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
procedure ReadDB();
public
{ Public declarations }
procedure toLog(aModule, aMethod, aMessage: string; aCode: integer);
procedure GlobalExceptionHandler(Sender: TObject; E: Exception);
end;
var
TTW_Bot: TTTW_Bot;
myConst: TConst;
db: TSettingsDatabase;
appconst: TBotAppCfg;
implementation
{$R *.fmx}
procedure TTTW_Bot.GlobalExceptionHandler(Sender: TObject; E: Exception);
begin
try
TTW_Bot.toLog('GlobalException', E.ClassName, E.Message, 2);
except
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
end;
end;
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;
function GetPathToTestExe: string; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> 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);
frAutoActions1.FTimerList := TObjectList<TMyTimerThread>.Create(false);
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'));
frLog1.FLogList := TList<TRLog>.Create;
end;
procedure TTTW_Bot.FormDestroy(Sender: TObject);
begin
FreeAndNil(db);
FreeAndNil(frAutoActions1.FTimerList);
FreeAndNil(frLog1.FLogList);
inherited;
end;
procedure TTTW_Bot.frCommands1btnRandAddClick(Sender: TObject);
begin
frCommands1.btnRandAddClick(Sender);
end;
procedure TTTW_Bot.frOBS1btnDeleteeChatClick(Sender: TObject);
begin
frOBS1.btnDeleteeChatClick(Sender);
end;
procedure TTTW_Bot.frSettings1btnDAStartClick(Sender: TObject);
begin
frSettings1.btnDAStartClick(Sender);
end;
procedure TTTW_Bot.ReadDB;
function XorDecryptToStrings(const InputFile, Key: string): TStrings;
var
InStream: TFileStream;
MemStream: TMemoryStream;
KeyBytes: TBytes;
KeyLen, KeyIndex: integer;
B: Byte;
begin
KeyBytes := TEncoding.ANSI.GetBytes(Key);
KeyLen := Length(KeyBytes);
if KeyLen = 0 then
raise Exception.Create('<27><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>');
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;
MemStream.Position := 0;
Result := TStringList.Create;
try
Result.LoadFromStream(MemStream, TEncoding.ANSI);
except
Result.Free; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
raise;
end;
finally
MemStream.Free;
end;
finally
InStream.Free;
end;
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
procedure LoadGridsData;
begin
db.LoadRecordArray<TRandomCounters>('RandomCounters',
frCommands1.RandomCounters);
db.LoadRecordArray<TListCommands>('listSounds', frCommands1.listSounds);
db.LoadRecordArray<TListCommands>('listFiles', frCommands1.listFiles);
db.LoadRecordArray<TListCommands>('listNeiro', frCommands1.listNeiro);
db.LoadRecordArray<TListCommands>('listCommands', frCommands1.listCommands);
frCommands1.UpdateGridFromArray;
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
procedure LoadGroupNames;
begin
db.getGroupName(frCommands1.frGroupsRequest1.lbRandomGroup.Items);
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
procedure LoadEncryptedConfig;
var
tempList: TStrings; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
I: integer;
begin
if not FileExists(myConst.cfg1) then
Exit;
tempList := nil; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
try
tempList := XorDecryptToStrings(myConst.cfg1, 'fgvasrgEFAXFAFAS');
for I := 0 to tempList.Count - 1 do
begin
var eqPos := Pos('=', tempList[I]);
if eqPos > 0 then
begin
var Key := Trim(Copy(tempList[I], 1, eqPos - 1));
var Value := Trim(Copy(tempList[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
tempList.Free; // <20><><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
end;
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
procedure LoadAISettings;
var
I: integer;
c: TComponent;
ii: integer;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
procedure LoadAutoActionsGrids;
begin
db.LoadRecordArray<TListTimer>('listTimer', frAutoActions1.listTimer);
db.LoadRecordArray<TBanWord>('listBanWords', frAutoActions1.listBanWords);
db.LoadRecordArray<TCounter>('listCounters', frAutoActions1.listCounters);
frAutoActions1.initTimers;
frAutoActions1.UpdateGridFromArray;
end;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD>
procedure LoadOBSGrids;
begin
db.LoadRecordArray<TOBSChat>('listChats', frOBS1.listChats);
db.LoadRecordArray<TOBSNotify>('listNotify', frOBS1.listNotify);
db.LoadRecordArray<TOBSKandinsky>('listKandinsky', frOBS1.listKandinsky);
frOBS1.UpdateGridFromArray;
end;
begin
LoadSettingsComponents;
LoadGridsData;
LoadGroupNames;
LoadEncryptedConfig;
LoadNotifySettings;
LoadAISettings;
LoadOBSGrids;
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;
procedure TTTW_Bot.toLog(aModule, aMethod, aMessage: string; aCode: integer);
begin
TThread.Synchronize(nil,
procedure
var
ml: TRLog;
begin
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ml.rTime := Now;
case aCode of
0:
ml.rType := 'INFO';
1:
ml.rType := 'WARNING';
2:
ml.rType := 'ERROR';
3:
ml.rType := 'DEBUG';
else
ml.rType := 'UNKNOWN';
end;
ml.rModule := aModule; // string
ml.rMethod := aMethod; // string
ml.rMessage := aMessage; // string
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
frLog1.FLogList.Add(ml);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
frLog1.UpdateGridFilters;
end);
end;
end.