From bad576dd4da54bf740ef5a5788ce690aface776a Mon Sep 17 00:00:00 2001 From: "PC1\\PTyTb" Date: Thu, 14 Aug 2025 19:58:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D1=82=D1=80=D0=B5=D0=BC=D0=BE=D0=BD?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=B8=20=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D0=BC=D0=B0=D0=B9=D0=BB=D0=B8=D0=BA=D0=B8=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=B2=D0=B5=D0=B1=D1=87=D0=B0=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/uTTWAPI.pas | 63 +++++++++- forms/__recovery/__recovery.ini | 5 - forms/__recovery/uCreateChat.fmx | 189 ---------------------------- forms/__recovery/uCreateChat.pas | 207 ------------------------------ forms/uCreateChat.fmx | 11 +- forms/uCreateChat.pas | 16 +++ forms/uGeneral.fmx | 9 +- forms/uGeneral.pas | 74 ++++++----- frames/fOBS.pas | 209 +++++++++++++------------------ utils/uRecords.pas | 1 + 10 files changed, 217 insertions(+), 567 deletions(-) delete mode 100644 forms/__recovery/__recovery.ini delete mode 100644 forms/__recovery/uCreateChat.fmx delete mode 100644 forms/__recovery/uCreateChat.pas diff --git a/Services/uTTWAPI.pas b/Services/uTTWAPI.pas index 692f1e8..e53660e 100644 --- a/Services/uTTWAPI.pas +++ b/Services/uTTWAPI.pas @@ -1041,7 +1041,11 @@ var EmoteObj: TJSONObject; ImagesObj: TJSONObject; Emote: TEmotes; - I: Integer; + I, J: Integer; + chosenFormat, chosenTheme, chosenScale: string; + foundAnimated, foundNonStatic, foundDark: Boolean; + scaleVal, maxScale: Double; + s: string; begin if JSONString = '' then Exit; @@ -1069,11 +1073,68 @@ begin Emote.format := GetStringArray(EmoteObj, 'format'); Emote.scale := GetStringArray(EmoteObj, 'scale'); Emote.theme_mode := GetStringArray(EmoteObj, 'theme_mode'); + + // (format) + foundAnimated := False; + foundNonStatic := False; + chosenFormat := 'static'; // + + // "animated" + for s in Emote.format do + if s = 'animated' then + begin + chosenFormat := 'animated'; + foundAnimated := True; + Break; + end; + + // "animated", -"static" + if not foundAnimated then + for s in Emote.format do + if s <> 'static' then + begin + chosenFormat := s; + foundNonStatic := True; + Break; + end; + + // (theme_mode) + foundDark := False; + for s in Emote.theme_mode do + if s = 'dark' then + begin + chosenTheme := 'dark'; + foundDark := True; + Break; + end; + if not foundDark then + chosenTheme := 'light'; + + // (scale) + maxScale := 0; + for s in Emote.scale do + begin + if TryStrToFloat(s, scaleVal, TFormatSettings.Invariant) then + if scaleVal > maxScale then + maxScale := scaleVal; + end; + // , 1.0 + if maxScale = 0 then maxScale := 1.0; + chosenScale := Format('%.1f', [maxScale], TFormatSettings.Invariant); + + // + Emote.topImage := 'https://static-cdn.jtvnw.net/emoticons/v2/' + + Emote.id + '/' + + chosenFormat + '/' + + chosenTheme + '/' + + chosenScale; + EmotesList.Add(Emote); end; finally RootObj.Free; end; + end; procedure TTTW_API.GetChannelEmotes(var ce: TList); diff --git a/forms/__recovery/__recovery.ini b/forms/__recovery/__recovery.ini deleted file mode 100644 index e847a62..0000000 --- a/forms/__recovery/__recovery.ini +++ /dev/null @@ -1,5 +0,0 @@ -[uCreateChat.pas] -SaveTime=14.08.2025 10:44:31 -FileCount=2 -File0=C:\Users\PTyTb\Documents\Embarcadero\Studio\Projects\ttw_fmx_v10\forms\uCreateChat.pas -File1=C:\Users\PTyTb\Documents\Embarcadero\Studio\Projects\ttw_fmx_v10\forms\uCreateChat.fmx diff --git a/forms/__recovery/uCreateChat.fmx b/forms/__recovery/uCreateChat.fmx deleted file mode 100644 index 0cd5ea8..0000000 --- a/forms/__recovery/uCreateChat.fmx +++ /dev/null @@ -1,189 +0,0 @@ -object fCreateChat: TfCreateChat - Left = 0 - Top = 0 - Caption = #1056#1077#1076#1072#1082#1090#1086#1088' '#1095#1072#1090#1086#1074 - ClientHeight = 287 - ClientWidth = 810 - FormFactor.Width = 320 - FormFactor.Height = 480 - FormFactor.Devices = [Desktop] - OnCreate = FormCreate - OnShow = FormShow - DesignerMasterStyle = 0 - object GroupBox1: TGroupBox - Position.X = 8.000000000000000000 - Position.Y = 8.000000000000000000 - Size.Width = 305.000000000000000000 - Size.Height = 271.000000000000000000 - Size.PlatformDefault = False - Text = #1041#1083#1086#1082' '#1089#1086#1086#1073#1097#1077#1085#1080#1103 - TabOrder = 1 - inline frChatSettings1: TfrColorSettings - Align = Client - Margins.Top = 20.000000000000000000 - Size.Width = 305.000000000000000000 - Size.Height = 251.000000000000000000 - Size.PlatformDefault = False - inherited ccbStyleBorderColor: TColorComboBox - TabOrder = 30 - end - inherited Label40: TLabel - TabOrder = 8 - end - inherited Label42: TLabel - TabOrder = 35 - end - inherited Label44: TLabel - TabOrder = 38 - end - inherited Label48: TLabel - TabOrder = 40 - end - inherited sbStyleBlockBorderSize: TSpinBox - TabOrder = 37 - end - inherited sbStyleBlockPadding: TSpinBox - TabOrder = 41 - end - inherited Label1: TLabel - TabOrder = 34 - end - inherited ccbBColor: TColorComboBox - TabOrder = 36 - end - inherited btnChangeBGColor: TButton - TabOrder = 39 - end - end - end - object GroupBox2: TGroupBox - Position.X = 321.000000000000000000 - Position.Y = 8.000000000000000000 - Size.Width = 240.000000000000000000 - Size.Height = 145.000000000000000000 - Size.PlatformDefault = False - Text = #1064#1088#1080#1092#1090 - TabOrder = 2 - inline frFontSettings1: TfrFontSettings - Align = Client - Margins.Top = 20.000000000000000000 - Size.Width = 240.000000000000000000 - Size.Height = 125.000000000000000000 - Size.PlatformDefault = False - inherited ccbFontColor: TColorComboBox - TabOrder = 36 - end - inherited Label49: TLabel - TabOrder = 35 - end - inherited Label46: TLabel - TabOrder = 39 - end - end - end - object GroupBox10: TGroupBox - Position.X = 569.000000000000000000 - Position.Y = 8.000000000000000000 - Size.Width = 232.000000000000000000 - Size.Height = 203.000000000000000000 - Size.PlatformDefault = False - Text = #1053#1072#1089#1090#1088#1086#1081#1082#1080 - TabOrder = 0 - object Label27: TLabel - Position.X = 8.000000000000000000 - Position.Y = 22.000000000000000000 - Size.Width = 249.000000000000000000 - Size.Height = 17.000000000000000000 - Size.PlatformDefault = False - TextSettings.Trimming = None - Text = #1052#1072#1082#1089#1080#1084#1072#1083#1100#1085#1086#1077' '#1082#1086#1083#1080#1095#1077#1089#1090#1074#1086' '#1089#1086#1086#1073#1097#1077#1085#1080#1081 - TabOrder = 3 - end - object Label38: TLabel - Position.X = 8.000000000000000000 - Position.Y = 77.000000000000000000 - Size.Width = 249.000000000000000000 - Size.Height = 17.000000000000000000 - Size.PlatformDefault = False - TextSettings.Trimming = None - Text = #1042#1088#1077#1084#1103' '#1086#1090#1086#1073#1088#1072#1078#1077#1085#1080#1103' '#1089#1086#1086#1073#1097#1077#1085#1080#1103 - TabOrder = 0 - end - object sbMaxMsg: TSpinBox - Touch.InteractiveGestures = [LongTap, DoubleTap] - TabOrder = 5 - Cursor = crIBeam - Value = 5.000000000000000000 - Position.X = 8.000000000000000000 - Position.Y = 47.000000000000000000 - end - object sbTimeMsg: TSpinBox - Touch.InteractiveGestures = [LongTap, DoubleTap] - TabOrder = 2 - Cursor = crIBeam - Value = 10.000000000000000000 - Position.X = 8.000000000000000000 - Position.Y = 102.000000000000000000 - end - object Label39: TLabel - Position.X = 8.000000000000000000 - Position.Y = 132.000000000000000000 - Size.Width = 193.000000000000000000 - Size.Height = 17.000000000000000000 - Size.PlatformDefault = False - TextSettings.Trimming = None - Text = #1055#1086#1088#1090' '#1042#1077#1073' '#1057#1077#1088#1074#1077#1088#1072 - TabOrder = 6 - end - object cbFreez: TCheckBox - Position.X = 112.000000000000000000 - Position.Y = 105.000000000000000000 - Size.Width = 112.000000000000000000 - Size.Height = 19.000000000000000000 - Size.PlatformDefault = False - TabOrder = 38 - Text = #1042#1077#1095#1085#1086 - end - object sbWebServerPort: TSpinBox - Touch.InteractiveGestures = [LongTap, DoubleTap] - TabOrder = 4 - Cursor = crIBeam - Min = 8080.000000000000000000 - Max = 65000.000000000000000000 - Value = 8085.000000000000000000 - Position.X = 8.000000000000000000 - Position.Y = 157.000000000000000000 - end - end - object edtWebChatTest: TEdit - Touch.InteractiveGestures = [LongTap, DoubleTap] - TabOrder = 5 - Position.X = 321.000000000000000000 - Position.Y = 161.000000000000000000 - Size.Width = 240.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - end - object btnWebChatTest: TButton - Position.X = 321.000000000000000000 - Position.Y = 191.000000000000000000 - Size.Width = 152.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - TabOrder = 3 - Text = #1058#1077#1089#1090#1086#1074#1086#1077' '#1089#1086#1086#1073#1097#1077#1085#1080#1077 - TextSettings.Trimming = None - OnClick = btnWebChatTestClick - end - object btnCreateWebChat: TButton - Position.X = 704.000000000000000000 - Position.Y = 257.000000000000000000 - Size.Width = 97.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - TabOrder = 4 - Text = #1057#1086#1079#1076#1072#1090#1100' '#1095#1072#1090 - TextSettings.Trimming = None - OnClick = btnCreateWebChatClick - end -end diff --git a/forms/__recovery/uCreateChat.pas b/forms/__recovery/uCreateChat.pas deleted file mode 100644 index ae29b88..0000000 --- a/forms/__recovery/uCreateChat.pas +++ /dev/null @@ -1,207 +0,0 @@ -unit uCreateChat; - -interface - -uses - System.SysUtils, System.Types, System.UITypes, System.Classes, - System.Variants, FMX.ListBox, FMX.Colors, FMX.SpinBox, - FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, - fColorSettings, fFontSettings, FMX.Controls.Presentation, FMX.StdCtrls, - FMX.Edit, FMX.EditBox, StrUtils, uRecords; - -type - TfCreateChat = class(TForm) - frChatSettings1: TfrColorSettings; - GroupBox1: TGroupBox; - GroupBox2: TGroupBox; - frFontSettings1: TfrFontSettings; - GroupBox10: TGroupBox; - Label27: TLabel; - Label38: TLabel; - sbMaxMsg: TSpinBox; - sbTimeMsg: TSpinBox; - Label39: TLabel; - cbFreez: TCheckBox; - sbWebServerPort: TSpinBox; - edtWebChatTest: TEdit; - btnWebChatTest: TButton; - btnCreateWebChat: TButton; - procedure FormCreate(Sender: TObject); - procedure btnCreateWebChatClick(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure btnWebChatTestClick(Sender: TObject); - private - { Private declarations } - function GetColorFromColorPanel(aColor: TAlphaColor): string; - public - { Public declarations } - isEdit: boolean; - oldPort: integer; - procedure setRecord(aRec: TOBSChat); - end; - -var - fCreateChat: TfCreateChat; - -implementation - -uses uGeneral; - -{$R *.fmx} - -function TfCreateChat.GetColorFromColorPanel(aColor: TAlphaColor): string; -var - Color: TAlphaColor; - r, G, B: Byte; - A: Real; - FS: TFormatSettings; -begin - Color := aColor; - r := TAlphaColorRec(Color).r; - G := TAlphaColorRec(Color).G; - B := TAlphaColorRec(Color).B; - A := TAlphaColorRec(Color).A / 255; // Преобразуем альфа-канал в диапазон 0..1 - - // Устанавливаем точку в качестве десятичного разделителя - FS := TFormatSettings.Create; - FS.DecimalSeparator := '.'; - - result := Format('rgba(%d, %d, %d, %.2f)', [r, G, B, A], FS); -end; - -procedure TfCreateChat.setRecord(aRec: TOBSChat); -var - SavedColor: TAlphaColor; -begin - if TryStrToUInt('$' + aRec.ColorBlock, Cardinal(SavedColor)) then - fCreateChat.frChatSettings1.cpStyleBlockColor.Color := SavedColor - else - fCreateChat.frChatSettings1.cpStyleBlockColor.Color := TAlphaColorRec.Black; - fCreateChat.frChatSettings1.ccbStyleBorderColor.ItemIndex := aRec.ColorBorder; - fCreateChat.frChatSettings1.ccbBColor.ItemIndex := aRec.ColorBackground; - fCreateChat.frChatSettings1.sbStyleBlockBorderSize.Value := aRec.SolidBorder; - fCreateChat.frChatSettings1.sbStyleBlockPadding.Value := aRec.Paddings; - - fCreateChat.frFontSettings1.ccbFontColor.ItemIndex := aRec.ColorFont; - fCreateChat.frFontSettings1.sbFontSize.Value := aRec.SizeFont; - fCreateChat.frFontSettings1.cbFontStyleDefault.ItemIndex := aRec.StyleFont; - - fCreateChat.sbTimeMsg.Value := aRec.TimeMess; - fCreateChat.sbMaxMsg.Value := aRec.MaxCountMess; - fCreateChat.sbWebServerPort.Value := aRec.port; - oldPort := aRec.port; -end; - -procedure TfCreateChat.btnCreateWebChatClick(Sender: TObject); -var - OBSChat: TOBSChat; -begin - OBSChat.ColorBlock := GetColorFromColorPanel - (frChatSettings1.cpStyleBlockColor.Color); - OBSChat.ColorBorder := frChatSettings1.ccbStyleBorderColor.ItemIndex; - OBSChat.ColorBackground := frChatSettings1.ccbBColor.ItemIndex; - OBSChat.SolidBorder := round(frChatSettings1.sbStyleBlockBorderSize.Value); - OBSChat.Paddings := round(frChatSettings1.sbStyleBlockPadding.Value); - - OBSChat.ColorFont := frFontSettings1.ccbFontColor.ItemIndex; - OBSChat.SizeFont := round(frFontSettings1.sbFontSize.Value); - OBSChat.StyleFont := frFontSettings1.cbFontStyleDefault.ItemIndex; - - OBSChat.MaxCountMess := round(sbMaxMsg.Value); - OBSChat.TimeMess := round(sbTimeMsg.Value); - OBSChat.port := round(sbWebServerPort.Value); - - if isEdit then - TTW_Bot.frOBS1.EdtChat(OBSChat, oldPort) - else - TTW_Bot.frOBS1.AddChat(OBSChat); - close; -end; - -procedure TfCreateChat.btnWebChatTestClick(Sender: TObject); -var j:integer; aRecord: TTwitchChatMessage; -begin -aRecord.Username:='Test'; -aRecord.DisplayName:='Test'; -aRecord.Message:=edtWebChatTest.Text; - for j := 0 to TTW_Bot.frOBS1.ChatWebServers.Count - 1 do - begin - if TTW_Bot.frOBS1.ChatWebServers[j].port = round(sbWebServerPort.Value) then - begin - TTW_Bot.frOBS1.MsgToWebServer(aRecord); - end; - end; -end; - -procedure TfCreateChat.FormCreate(Sender: TObject); - procedure LoadFontList; - var - SearchRec: TSearchRec; - n: integer; - begin - if not DirectoryExists(myConst.fontsPath) then - CreateDir(myConst.fontsPath); - - n := 1; - if FindFirst(IncludeTrailingPathDelimiter(myConst.fontsPath) + '*.*', - faArchive, SearchRec) = 0 then - try - repeat - if (SearchRec.Attr and faAnyFile) = SearchRec.Attr then - begin - fCreateChat.frFontSettings1.cbFontStyleDefault.Items.Add - (SearchRec.Name); - Inc(n); - end; - until FindNext(SearchRec) <> 0; - finally - System.SysUtils.FindClose(SearchRec); - end; - end; - - procedure LoadChatOBSSettings; - var - I: integer; - c: TComponent; - ColorStr: string; - SavedColor: TAlphaColor; - begin - for I := 0 to frChatSettings1.ComponentCount - 1 do - begin - c := frChatSettings1.Components[I]; - if c is TComboBox then - TComboBox(c).ItemIndex := - strtoint(db.ReadSetting(TComboBox(c).Name, '0')) - else if c is TColorComboBox then - TColorComboBox(c).ItemIndex := - strtoint(db.ReadSetting(TComboBox(c).Name, '147')) - else if c is TSpinBox then - TSpinBox(c).text := db.ReadSetting(TSpinBox(c).Name, - IfThen(TSpinBox(c).Name = 'sbWebServerPort', '8080', '1')) - else if c is TCheckBox then - TCheckBox(c).IsChecked := db.ReadSetting(TCheckBox(c).Name, '0') = '1'; - end; - - ColorStr := db.ReadSetting('cpStyleBlockColor', 'FF000000'); - if TryStrToUInt('$' + ColorStr, Cardinal(SavedColor)) then - frChatSettings1.cpStyleBlockColor.Color := SavedColor - else - frChatSettings1.cpStyleBlockColor.Color := TAlphaColorRec.Black; - end; - -begin - isEdit := false; - LoadChatOBSSettings; - LoadFontList; - -end; - -procedure TfCreateChat.FormShow(Sender: TObject); -begin - if isEdit then - btnCreateWebChat.text := 'Изменить чат' - else - btnCreateWebChat.text := 'Создать чат'; -end; - -end. diff --git a/forms/uCreateChat.fmx b/forms/uCreateChat.fmx index 10e2f44..0cd5ea8 100644 --- a/forms/uCreateChat.fmx +++ b/forms/uCreateChat.fmx @@ -25,7 +25,7 @@ object fCreateChat: TfCreateChat Size.Height = 251.000000000000000000 Size.PlatformDefault = False inherited ccbStyleBorderColor: TColorComboBox - TabOrder = 31 + TabOrder = 30 end inherited Label40: TLabel TabOrder = 8 @@ -42,6 +42,9 @@ object fCreateChat: TfCreateChat inherited sbStyleBlockBorderSize: TSpinBox TabOrder = 37 end + inherited sbStyleBlockPadding: TSpinBox + TabOrder = 41 + end inherited Label1: TLabel TabOrder = 34 end @@ -67,9 +70,6 @@ object fCreateChat: TfCreateChat Size.Width = 240.000000000000000000 Size.Height = 125.000000000000000000 Size.PlatformDefault = False - inherited Label41: TLabel - TabOrder = 6 - end inherited ccbFontColor: TColorComboBox TabOrder = 36 end @@ -141,7 +141,7 @@ object fCreateChat: TfCreateChat Size.Width = 112.000000000000000000 Size.Height = 19.000000000000000000 Size.PlatformDefault = False - TabOrder = 37 + TabOrder = 38 Text = #1042#1077#1095#1085#1086 end object sbWebServerPort: TSpinBox @@ -173,6 +173,7 @@ object fCreateChat: TfCreateChat TabOrder = 3 Text = #1058#1077#1089#1090#1086#1074#1086#1077' '#1089#1086#1086#1073#1097#1077#1085#1080#1077 TextSettings.Trimming = None + OnClick = btnWebChatTestClick end object btnCreateWebChat: TButton Position.X = 704.000000000000000000 diff --git a/forms/uCreateChat.pas b/forms/uCreateChat.pas index 5222cda..5242335 100644 --- a/forms/uCreateChat.pas +++ b/forms/uCreateChat.pas @@ -29,6 +29,7 @@ type procedure FormCreate(Sender: TObject); procedure btnCreateWebChatClick(Sender: TObject); procedure FormShow(Sender: TObject); + procedure btnWebChatTestClick(Sender: TObject); private { Private declarations } function GetColorFromColorPanel(aColor: TAlphaColor): string; @@ -117,6 +118,21 @@ begin close; end; +procedure TfCreateChat.btnWebChatTestClick(Sender: TObject); +var j:integer; aRecord: TTwitchChatMessage; +begin +aRecord.Username:='Test'; +aRecord.DisplayName:='Test'; +aRecord.Message:=edtWebChatTest.Text; + for j := 0 to TTW_Bot.frOBS1.ChatWebServers.Count - 1 do + begin + if TTW_Bot.frOBS1.ChatWebServers[j].port = round(sbWebServerPort.Value) then + begin + TTW_Bot.frOBS1.MsgToWebServer(aRecord); + end; + end; +end; + procedure TfCreateChat.FormCreate(Sender: TObject); procedure LoadFontList; var diff --git a/forms/uGeneral.fmx b/forms/uGeneral.fmx index 36f44d5..c7b2209 100644 --- a/forms/uGeneral.fmx +++ b/forms/uGeneral.fmx @@ -88,6 +88,7 @@ object TTW_Bot: TTTW_Bot inherited btnDAGetCode: TButton Images = ImageList1 ImageIndex = 10 + TabOrder = 38 end inherited edtDAClientID: TEdit TabOrder = 33 @@ -102,23 +103,19 @@ object TTW_Bot: TTTW_Bot TabOrder = 35 end inherited edtDARedirectURL: TEdit - TabOrder = 42 + TabOrder = 43 end inherited edtDACode: TEdit TabOrder = 36 end - inherited Label66: TLabel - TabOrder = 39 - end inherited btnDAStart: TButton Images = ImageList1 ImageIndex = 18 - TabOrder = 41 OnClick = frSettings1btnDAStartClick end inherited btnGetDADef: TButton Images = ImageList1 - TabOrder = 43 + TabOrder = 44 end end inherited btnOpenRomaning: TButton diff --git a/forms/uGeneral.pas b/forms/uGeneral.pas index 49fc374..321729f 100644 --- a/forms/uGeneral.pas +++ b/forms/uGeneral.pas @@ -12,7 +12,7 @@ uses System.Generics.Collections, utts, uGigaChat, uChatAPI, System.IOUtils, fCommands, uDataBase, FMX.Edit, FMX.Colors, FMX.SpinBox, windows, System.Skia, FMX.Skia, uCreateChat, uCreateNotify, fOBS, fTTS, - fPlayerWeb, uWebServerKandinsky; + fPlayerWeb, uWebServerKandinsky, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo; type TTTW_Bot = class(TForm) @@ -211,27 +211,27 @@ begin raise Exception.Create('Не удалось получить Room ID'); // Загрузка эмодзи и бейджей - { try - fChatFrame.ChatBadges.Clear; - ttw_API.getCustomChatBadges(fChatFrame.ChatBadges); - ttw_API.getGlobalChatBadges(fChatFrame.ChatBadges); + try + frOBS1.ChatBadges.Clear; + ttw_API.getCustomChatBadges(frOBS1.ChatBadges); + ttw_API.getGlobalChatBadges(frOBS1.ChatBadges); - fChatFrame.ChatEmotes.Clear; - ttw_API.GetChannelEmotes(fChatFrame.ChatEmotes); - ttw_API.GetGlobalEmotes(fChatFrame.ChatEmotes); + frOBS1.ChatEmotes.Clear; + ttw_API.GetChannelEmotes(frOBS1.ChatEmotes); + ttw_API.GetGlobalEmotes(frOBS1.ChatEmotes); - fChatFrame.BTTV.getGlobal; - fChatFrame.BTTV.getCustom(rid); + frOBS1.BTTV.getGlobal; + frOBS1.BTTV.getCustom(rid); - fChatFrame.m7tv.getGlobal; - fChatFrame.m7tv.getCustom(rid); - except + frOBS1.m7tv.getGlobal; + frOBS1.m7tv.getCustom(rid); + except on E: Exception do begin - fLog.toLog(2, 'uGeneral', 'ConnectProcedure.Emotes', E.Message); - raise; + toLog('uGeneral', 'ConnectProcedure.Emotes', E.Message, 2); + raise; end; - end; } + end; // Инициализация EventSub @@ -396,7 +396,7 @@ 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)); + db.WriteSetting('cbTheme', inttostr(cbTheme.ItemIndex)); end; procedure TTTW_Bot.FormCreate(Sender: TObject); @@ -493,15 +493,20 @@ end; procedure TTTW_Bot.FormDestroy(Sender: TObject); begin +frOBS1.ChatBadges.Free; +frOBS1.ChatEmotes.Free; +frOBS1.ChatWebServers.Free; + + DisconnectProcedure; - if Assigned(ttw_IRS) then + if Assigned(ttw_IRS) then ttw_IRS.Free; if Assigned(ttw_ES) then - ttw_ES.free; + ttw_ES.Free; if Assigned(Kandinsky) then - Kandinsky.Free; - if Assigned(ttw_API ) then - ttw_API.Free; + Kandinsky.Free; + if Assigned(ttw_API) then + ttw_API.Free; frSettings1.Destroy; FreeAndNil(db); FreeAndNil(frAutoActions1.FTimerList); @@ -710,11 +715,11 @@ begin responseText := ProcessCommand(firstWord); decodeResponseSendToTTW(responseText, commandText, aRecord.DisplayName); end; - TThread.Queue(nil, - procedure - begin - frOBS1.MsgToWebServer(aRecord); - end); + TThread.Queue(nil, + procedure + begin + frOBS1.MsgToWebServer(aRecord); + end); PlayNotifySound((aRecord.Moder = 1), (aRecord.Vip = 1), (aRecord.Subscriber = 1)); end; @@ -1041,20 +1046,21 @@ procedure TTTW_Bot.ReadDB; // Загрузка интеграций с ОБС procedure LoadOBSGrids; - var i:integer; + var + I: Integer; begin db.LoadRecordArray('listChats', frOBS1.listChats); frOBS1.BTTV := TBTTV.Create; frOBS1.m7tv := t7tv.Create; - frOBS1.ChatBadges := Tlist.Create; - frOBS1.ChatEmotes := Tlist.Create; - frOBS1.ChatWebServers := Tlist.Create; + frOBS1.ChatBadges := TList.Create; + frOBS1.ChatEmotes := TList.Create; + frOBS1.ChatWebServers := TList.Create; for I := 0 to High(frOBS1.listChats) do - begin - frOBS1.CreateWebChat(frOBS1.listChats[i]); - end; + begin + frOBS1.CreateWebChat(frOBS1.listChats[I]); + end; db.LoadRecordArray('listNotify', frOBS1.listNotify); db.LoadRecordArray('listKandinsky', frOBS1.listKandinsky); diff --git a/frames/fOBS.pas b/frames/fOBS.pas index 982fb65..1a9f6f7 100644 --- a/frames/fOBS.pas +++ b/frames/fOBS.pas @@ -8,7 +8,7 @@ uses FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, System.Rtti, FMX.Grid.Style, FMX.Grid, FMX.ScrollBox, FMX.Edit, FMX.Colors, FMX.ListBox, FMX.EditBox, FMX.SpinBox, FMX.Controls.Presentation, uRecords, - System.Generics.Defaults, fFontSettings; + System.Generics.Defaults, fFontSettings, System.Character; type TChatWebServers = record @@ -117,125 +117,6 @@ begin end; end; -function TfrOBS.FindEmoteByID(const ID: string): TEmotes; -var - i: integer; -begin - result.ID := ''; - if not Assigned(ChatEmotes) then - exit; - - for i := 0 to ChatEmotes.Count - 1 do - if ChatEmotes[i].ID = ID then - begin - result := ChatEmotes[i]; - Break; - end; -end; - -function TfrOBS.ReplaceEmotesInMessage(const MessageText, - EmotesString: string): string; -type - TEmotePosition = record - StartPos: integer; - EndPos: integer; - ImageURL: string; - end; -var - Positions: Tlist; - i, ColonPos: integer; - Parts, EmoteData, Ranges: tstringlist; - EmoteID, RangeStr: string; - StartPos, EndPos: integer; - Emote: TEmotes; -begin - result := MessageText; - if EmotesString.IsEmpty then - exit; - - Parts := tstringlist.Create; - EmoteData := tstringlist.Create; - Ranges := tstringlist.Create; - Positions := Tlist.Create; - try - Parts.Delimiter := '/'; - Parts.StrictDelimiter := True; - Parts.DelimitedText := EmotesString; - - for i := 0 to Parts.Count - 1 do - begin - ColonPos := Pos(':', Parts[i]); - if ColonPos = 0 then - Continue; - - EmoteID := Copy(Parts[i], 1, ColonPos - 1); - RangeStr := Copy(Parts[i], ColonPos + 1, MaxInt); - - Ranges.Clear; - Ranges.Delimiter := ','; - Ranges.StrictDelimiter := True; - Ranges.DelimitedText := RangeStr; - - Emote := FindEmoteByID(EmoteID); - if Emote.ID = '' then - Continue; - - for var j := 0 to Ranges.Count - 1 do - begin - EmoteData.Clear; - EmoteData.Delimiter := '-'; - EmoteData.StrictDelimiter := True; - EmoteData.DelimitedText := Ranges[j]; - if EmoteData.Count <> 2 then - Continue; - - if TryStrToInt(EmoteData[0], StartPos) and - TryStrToInt(EmoteData[1], EndPos) then - begin - var - EmotePosition: TEmotePosition; - EmotePosition.StartPos := StartPos; - EmotePosition.EndPos := EndPos; - EmotePosition.ImageURL := Emote.images.Url1x; - - Positions.Add(EmotePosition); - end; - end; - end; - - Positions.Sort(TComparer.Construct( - function(const Left, Right: TEmotePosition): integer - begin - result := Right.StartPos - Left.StartPos; - end)); - - var - SB := TStringBuilder.Create(MessageText); - try - for var Pos in Positions do - begin - if (Pos.StartPos < 0) or (Pos.EndPos >= SB.Length) or - (Pos.StartPos > Pos.EndPos) then - Continue; - - var - Replacement := Format('', - [Pos.ImageURL]); - - SB.Remove(Pos.StartPos, Pos.EndPos - Pos.StartPos + 1); - SB.Insert(Pos.StartPos, Replacement); - end; - result := SB.ToString; - finally - SB.Free; - end; - finally - Parts.Free; - EmoteData.Free; - Ranges.Free; - Positions.Free; - end; -end; function TfrOBS.GetBadgesHTML(Badges: string): string; var @@ -320,6 +201,78 @@ begin end; end; + +function TfrOBS.ReplaceEmotesInMessage(const MessageText, EmotesString: string): string; +var + ProcessedEmotes: TDictionary; + Parts: TStringList; + i, ColonPos: Integer; + EmoteID: string; + Emote: TEmotes; + ResultText: string; +begin + Result := MessageText; + if EmotesString.Trim = '' then + Exit; + + // + ProcessedEmotes := TDictionary.Create; + Parts := TStringList.Create; + try + // '/' + Parts.StrictDelimiter := True; + Parts.Delimiter := '/'; + Parts.DelimitedText := EmotesString; + + ResultText := MessageText; + + // + for i := 0 to Parts.Count - 1 do + begin + ColonPos := Pos(':', Parts[i]); + if ColonPos = 0 then + Continue; + + // ID + EmoteID := Copy(Parts[i], 1, ColonPos - 1); + + // + if ProcessedEmotes.ContainsKey(EmoteID) then + Continue; + + // + Emote := FindEmoteByID(EmoteID); + if Emote.ID = '' then + Continue; + + var imgUrl: string; + if Emote.topImage <> '' then + imgUrl := Emote.topImage + else if Emote.images.Url4x <> '' then + imgUrl := Emote.images.Url4x + else + Continue; // URL + + // + ResultText := StringReplace( + ResultText, + Emote.name, + Format('', [imgUrl]), + [rfReplaceAll] + ); + + // + ProcessedEmotes.Add(EmoteID, ''); + end; + + Result := ResultText; + finally + ProcessedEmotes.Free; + Parts.Free; + end; +end; + + procedure TfrOBS.AddChat(newRecord: TOBSChat); begin SetLength(listChats, Length(listChats) + 1); @@ -613,6 +566,22 @@ begin end; end; +function TfrOBS.FindEmoteByID(const ID: string): TEmotes; +var + i: integer; +begin + result.ID := ''; + if not Assigned(ChatEmotes) then + exit; + + for i := 0 to ChatEmotes.Count - 1 do + if ChatEmotes[i].ID = ID then + begin + result := ChatEmotes[i]; + Break; + end; +end; + procedure TfrOBS.sgWebChatsCellDblClick(const Column: TColumn; const Row: integer); var diff --git a/utils/uRecords.pas b/utils/uRecords.pas index 48ab346..527ee96 100644 --- a/utils/uRecords.pas +++ b/utils/uRecords.pas @@ -264,6 +264,7 @@ type format: TArray; scale: TArray; theme_mode: TArray; + topImage:string; end; TStyleChat = record