исправил оповещения, теперь работают четко
This commit is contained in:
+52
-53
@@ -3,29 +3,11 @@ unit uRecords;
|
||||
interface
|
||||
|
||||
type
|
||||
TEventGlobal = record
|
||||
Event:integer;
|
||||
Condition:string;
|
||||
Action:integer;
|
||||
Param:string;
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
TRLog = record
|
||||
rTime: ttime;
|
||||
rType: string;
|
||||
rModule: string;
|
||||
rMethod: string;
|
||||
rMessage: string;
|
||||
end;
|
||||
|
||||
type
|
||||
TCounter = record
|
||||
counterName: string;
|
||||
trigger: string;
|
||||
count: integer;
|
||||
auto: integer;
|
||||
TEventGlobal = record
|
||||
Event: integer;
|
||||
Condition: string;
|
||||
Action: integer;
|
||||
Param: string;
|
||||
end;
|
||||
|
||||
type
|
||||
@@ -33,19 +15,6 @@ type
|
||||
regexp: string;
|
||||
end;
|
||||
|
||||
type
|
||||
TListTimer = record
|
||||
Enable: integer;
|
||||
interval: integer;
|
||||
o: integer;
|
||||
mess: string;
|
||||
end;
|
||||
|
||||
type
|
||||
TOBSKandinsky = record
|
||||
port: integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TOBSNotify = record
|
||||
Picture: string;
|
||||
@@ -54,18 +23,18 @@ type
|
||||
ColorBlock: string;
|
||||
SolidBorder: integer;
|
||||
Paddings: integer;
|
||||
ColorBorder: integer;
|
||||
ColorBackground: integer;
|
||||
ColorBorder: string;
|
||||
ColorBackground: string;
|
||||
|
||||
HeaderText: string;
|
||||
HeaderColorFont: integer;
|
||||
HeaderColorFont: string;
|
||||
HeaderSizeFont: integer;
|
||||
HeaderStyleFont: integer;
|
||||
HeaderStyleFont: string;
|
||||
|
||||
MessText: string;
|
||||
MessColorFont: integer;
|
||||
MessColorFont: string;
|
||||
MessSizeFont: integer;
|
||||
MessStyleFont: integer;
|
||||
MessStyleFont: string;
|
||||
|
||||
TimeMess: integer;
|
||||
TypeEvent: integer;
|
||||
@@ -86,10 +55,37 @@ type
|
||||
MaxCountMess: integer;
|
||||
TimeMess: integer;
|
||||
port: integer;
|
||||
freez:integer;
|
||||
freez: integer;
|
||||
StyleFont: integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TListCommands = record
|
||||
R1: string;
|
||||
R2: string;
|
||||
end;
|
||||
|
||||
type
|
||||
TCounter = record
|
||||
counterName: string;
|
||||
trigger: string;
|
||||
count: integer;
|
||||
auto: integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TListTimer = record
|
||||
Enable: integer;
|
||||
interval: integer;
|
||||
o: integer;
|
||||
mess: string;
|
||||
end;
|
||||
|
||||
type
|
||||
TOBSKandinsky = record
|
||||
port: integer;
|
||||
end;
|
||||
|
||||
type
|
||||
TRandomCounters = record
|
||||
rndName: string;
|
||||
@@ -98,9 +94,12 @@ type
|
||||
end;
|
||||
|
||||
type
|
||||
TListCommands = record
|
||||
R1: string;
|
||||
R2: string;
|
||||
TRLog = record
|
||||
rTime: ttime;
|
||||
rType: string;
|
||||
rModule: string;
|
||||
rMethod: string;
|
||||
rMessage: string;
|
||||
end;
|
||||
|
||||
type
|
||||
@@ -270,7 +269,7 @@ type
|
||||
format: TArray<string>;
|
||||
scale: TArray<string>;
|
||||
theme_mode: TArray<string>;
|
||||
topImage:string;
|
||||
topImage: string;
|
||||
end;
|
||||
|
||||
TStyleChat = record
|
||||
@@ -342,7 +341,7 @@ type
|
||||
version: string;
|
||||
status: string;
|
||||
cost: integer;
|
||||
condition: TCondition;
|
||||
Condition: TCondition;
|
||||
transport: TTransport;
|
||||
created_at: string;
|
||||
end;
|
||||
@@ -383,7 +382,7 @@ type
|
||||
|
||||
TCustomRewardEvent = record
|
||||
subscription: TSubscriptionPoints;
|
||||
event: TEventReward;
|
||||
Event: TEventReward;
|
||||
end;
|
||||
|
||||
TMetadata = record
|
||||
@@ -455,22 +454,22 @@ type
|
||||
|
||||
TFollowEvent = record
|
||||
subscription: TSubscriptionPoints;
|
||||
event: TEventFollow;
|
||||
Event: TEventFollow;
|
||||
end;
|
||||
|
||||
TSubEvent = record
|
||||
subscription: TSubscriptionPoints;
|
||||
event: TEventSub;
|
||||
Event: TEventSub;
|
||||
end;
|
||||
|
||||
TGiftEvent = record
|
||||
subscription: TSubscriptionPoints;
|
||||
event: TEventGift;
|
||||
Event: TEventGift;
|
||||
end;
|
||||
|
||||
TRaidEvent = record
|
||||
subscription: TSubscriptionPoints;
|
||||
event: TEventRaid;
|
||||
Event: TEventRaid;
|
||||
end;
|
||||
|
||||
TBotAppCfg = record
|
||||
|
||||
+87
-143
@@ -17,13 +17,14 @@ type
|
||||
FCriticalSection: TCriticalSection;
|
||||
procedure IdHTTPServer1CommandGet(AContext: TIdContext;
|
||||
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
|
||||
procedure ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
|
||||
procedure ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo;
|
||||
AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
|
||||
function GenerateHTML: string;
|
||||
function GenerateJSON: string;
|
||||
procedure CleanupOldMessages;
|
||||
public
|
||||
IdHTTPServer1: TIdHTTPServer;
|
||||
constructor Create(FontList: TStrings; aPort:integer);
|
||||
constructor Create(FontList: TStrings; aPort: integer);
|
||||
destructor Destroy; override;
|
||||
procedure addMessage(newMsg: TStyleEvent);
|
||||
procedure ActiveServer(aEn: boolean);
|
||||
@@ -35,9 +36,9 @@ uses ugeneral;
|
||||
|
||||
{ TTTW_Events }
|
||||
|
||||
constructor TTTW_Events.Create(FontList: TStrings; aPort:integer);
|
||||
constructor TTTW_Events.Create(FontList: TStrings; aPort: integer);
|
||||
var
|
||||
I: Integer;
|
||||
I: integer;
|
||||
begin
|
||||
FCriticalSection := TCriticalSection.Create;
|
||||
FMessages := TList<TStyleEvent>.Create;
|
||||
@@ -71,27 +72,19 @@ end;
|
||||
|
||||
procedure TTTW_Events.CleanupOldMessages;
|
||||
var
|
||||
I: Integer;
|
||||
I: integer;
|
||||
TimeNow: TDateTime;
|
||||
begin
|
||||
TimeNow := Now;
|
||||
FCriticalSection.Enter;
|
||||
try
|
||||
for I := FMessages.Count - 1 downto 0 do
|
||||
begin
|
||||
if SecondsBetween(TimeNow, FMessages[I].Timestamp) >= FMessages[I].TimeMsg then
|
||||
FMessages.Delete(I);
|
||||
end;
|
||||
finally
|
||||
FCriticalSection.Leave;
|
||||
end;
|
||||
for I := FMessages.Count - 1 downto 0 do
|
||||
if SecondsBetween(TimeNow, FMessages[I].Timestamp) >= FMessages[I].TimeMsg
|
||||
then
|
||||
FMessages.Delete(I);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TTTW_Events.GenerateHTML: string;
|
||||
var
|
||||
I: Integer;
|
||||
I: integer;
|
||||
s, s1: string;
|
||||
begin
|
||||
// Ãåíåðàöèÿ CSS äëÿ øðèôòîâ
|
||||
@@ -99,126 +92,82 @@ begin
|
||||
for I := 41 to fFontsList.Count - 1 do
|
||||
begin
|
||||
s1 := StringReplace(fFontsList[I], '.ttf', '', [rfReplaceAll]);
|
||||
s := s + Format('@font-face { font-family: ''%s''; src: url(fonts/%s); }', [s1, fFontsList[I]]) + #13#10;
|
||||
s := s + Format('@font-face { font-family: ''%s''; src: url(fonts/%s); }',
|
||||
[s1, fFontsList[I]]) + #13#10;
|
||||
end;
|
||||
|
||||
Result := '<!DOCTYPE html><html><head>' +
|
||||
'<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">' +
|
||||
'<meta http-equiv="Pragma" content="no-cache">' +
|
||||
'<meta http-equiv="Expires" content="0">' +
|
||||
'<title>Twitch Messages</title>' +
|
||||
'<style>' + s +
|
||||
'.message { ' +
|
||||
' will-change: transform, opacity;' + // Îïòèìèçàöèÿ àíèìàöèè
|
||||
' backface-visibility: hidden;' +
|
||||
' transform: translateZ(0);' +
|
||||
' margin:5px; ' +
|
||||
' border-radius:5px; ' +
|
||||
' transition: opacity 1s linear; ' +
|
||||
' max-width: 600px; ' +
|
||||
' margin-left: auto; ' +
|
||||
' margin-right: auto; ' +
|
||||
'}' +
|
||||
'.nick { margin: 0; padding: 2px; }' +
|
||||
'.text { margin: 0; padding: 5px; }' +
|
||||
'#audio-warning { ' +
|
||||
' display: none; ' +
|
||||
' position: fixed; ' +
|
||||
' top: 10px; ' +
|
||||
' right: 10px; ' +
|
||||
' background: #ffcccc; ' +
|
||||
' padding: 10px; ' +
|
||||
' border: 1px solid red; ' +
|
||||
'}' +
|
||||
'</style>' +
|
||||
'<script>' +
|
||||
'let lastPlayedTimestamp = 0;' +
|
||||
'let audioEnabled = false;' +
|
||||
'<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">'
|
||||
+ '<meta http-equiv="Pragma" content="no-cache">' +
|
||||
'<meta http-equiv="Expires" content="0">' + '<title>Twitch Messages</title>'
|
||||
+ '<style>' + s + '.message { ' + ' will-change: transform, opacity;' +
|
||||
// Îïòèìèçàöèÿ àíèìàöèè
|
||||
' backface-visibility: hidden;' + ' transform: translateZ(0);' +
|
||||
' margin:5px; ' + ' border-radius:5px; ' +
|
||||
' transition: opacity 1s linear; ' + ' max-width: 600px; ' +
|
||||
' margin-left: auto; ' + ' margin-right: auto; ' + '}' +
|
||||
'.nick { margin: 0; padding: 2px; }' + '.text { margin: 0; padding: 5px; }'
|
||||
+ '#audio-warning { ' + ' display: none; ' + ' position: fixed; ' +
|
||||
' top: 10px; ' + ' right: 10px; ' + ' background: #ffcccc; ' +
|
||||
' padding: 10px; ' + ' border: 1px solid red; ' + '}' + '</style>' +
|
||||
'<script>' + 'let lastPlayedTimestamp = 0;' + 'let audioEnabled = false;' +
|
||||
'let pendingMessages = [];' +
|
||||
|
||||
'function enableAudio() {' +
|
||||
' audioEnabled = true;' +
|
||||
'function enableAudio() {' + ' audioEnabled = true;' +
|
||||
' document.getElementById("audio-overlay").style.display = "none";' +
|
||||
' processPendingMessages();' +
|
||||
'}' +
|
||||
' processPendingMessages();' + '}' +
|
||||
|
||||
'function processPendingMessages() {' +
|
||||
' pendingMessages.forEach(msg => {' +
|
||||
' playNotificationSound(msg);' +
|
||||
' });' +
|
||||
' pendingMessages = [];' +
|
||||
'}' +
|
||||
'function processPendingMessages() {' + ' pendingMessages.forEach(msg => {'
|
||||
+ ' playNotificationSound(msg);' + ' });' +
|
||||
' pendingMessages = [];' + '}' +
|
||||
|
||||
'function playNotificationSound(msg) {' +
|
||||
' if(!msg.sound) return;' +
|
||||
' const audio = new Audio(msg.sound);' +
|
||||
' audio.play()' +
|
||||
' .catch(error => console.log("Audio error:", error));' +
|
||||
'}' +
|
||||
'function playNotificationSound(msg) {' + ' if(!msg.sound) return;' +
|
||||
' const audio = new Audio(msg.sound);' + ' audio.play()' +
|
||||
' .catch(error => console.log("Audio error:", error));' + '}' +
|
||||
|
||||
'function fetchMessages() {' +
|
||||
' fetch("/messages")' +
|
||||
' .then(response => response.json())' +
|
||||
' .then(data => {' +
|
||||
'function fetchMessages() {' + ' fetch("/messages")' +
|
||||
' .then(response => response.json())' + ' .then(data => {' +
|
||||
' const container = document.getElementById("messages");' +
|
||||
' container.innerHTML = "";' +
|
||||
' data.forEach(msg => {' +
|
||||
' container.innerHTML = "";' + ' data.forEach(msg => {' +
|
||||
|
||||
// Ñîõðàíÿåì ñîîáùåíèÿ äî àêòèâàöèè çâóêà
|
||||
// Ñîõðàíÿåì ñîîáùåíèÿ äî àêòèâàöèè çâóêà
|
||||
' if(msg.sound && msg.timestamp > lastPlayedTimestamp) {' +
|
||||
' playNotificationSound(msg);' +
|
||||
' lastPlayedTimestamp = msg.timestamp;' +
|
||||
' }' +
|
||||
' lastPlayedTimestamp = msg.timestamp;' + ' }' +
|
||||
|
||||
' const div = document.createElement("div");' +
|
||||
' div.className = "message";' +
|
||||
' div.id = "msg-" + msg.timestamp;' +
|
||||
' div.style = `' +
|
||||
' div.id = "msg-" + msg.timestamp;' + ' div.style = `' +
|
||||
' background-color: ${msg.color};' +
|
||||
' padding: ${msg.padding}px;' +
|
||||
' border: ${msg.sizeBorder}px solid ${msg.colorBorder};' +
|
||||
' text-align: center;' +
|
||||
' `;' +
|
||||
' text-align: center;' + ' `;' +
|
||||
|
||||
// Âíóòðåííèé HTML
|
||||
' let content = "";' +
|
||||
' if(msg.url) {' +
|
||||
' content += `<img src="${msg.url}" style="max-width: 100%; height: auto;">`;' +
|
||||
' }' +
|
||||
' content += `' +
|
||||
' <p class="nick" style="' +
|
||||
' color: ${msg.titlecolor};' +
|
||||
// Âíóòðåííèé HTML
|
||||
' let content = "";' + ' if(msg.url) {' +
|
||||
' content += `<img src="${msg.url}" style="max-width: 100%; height: auto;">`;'
|
||||
+ ' }' + ' content += `' + ' <p class="nick" style="'
|
||||
+ ' color: ${msg.titlecolor};' +
|
||||
' font-family: ''${msg.titlefamily}'';' +
|
||||
' font-size: ${msg.titleSize}px;">' +
|
||||
' ${msg.nickname}' +
|
||||
' </p>' +
|
||||
' ${msg.nickname}' + ' </p>' +
|
||||
' <p class="text" style="' +
|
||||
' color: ${msg.contentcolor};' +
|
||||
' font-family: ''${msg.contentfamily}'';' +
|
||||
' font-size: ${msg.contentSize}px;">' +
|
||||
' ${msg.content}' +
|
||||
' </p>' +
|
||||
' `;' +
|
||||
' ${msg.content}' + ' </p>' + ' `;' +
|
||||
' div.innerHTML = content;' +
|
||||
|
||||
// Àíèìàöèÿ èñ÷åçíîâåíèÿ
|
||||
' setTimeout(() => {' +
|
||||
' div.style.opacity = "0";' +
|
||||
// Àíèìàöèÿ èñ÷åçíîâåíèÿ
|
||||
' setTimeout(() => {' + ' div.style.opacity = "0";' +
|
||||
' setTimeout(() => div.remove(), 1000);' +
|
||||
' }, (msg.duration - 1) * 1000);' +
|
||||
|
||||
' container.appendChild(div);' +
|
||||
' });' +
|
||||
' });' +
|
||||
'}' +
|
||||
' container.appendChild(div);' + ' });' + ' });' + '}' +
|
||||
|
||||
'setInterval(fetchMessages, 500);' +
|
||||
'fetchMessages();' +
|
||||
'</script>' +
|
||||
'setInterval(fetchMessages, 1000);' + 'fetchMessages();' + '</script>' +
|
||||
|
||||
'</head>' +
|
||||
'<body>' +
|
||||
' <div id="messages"></div>' +
|
||||
'</head>' + '<body>' + ' <div id="messages"></div>' +
|
||||
|
||||
'</body></html>';
|
||||
end;
|
||||
@@ -226,55 +175,49 @@ end;
|
||||
function TTTW_Events.GenerateJSON: string;
|
||||
var
|
||||
JSONArray: TJSONArray;
|
||||
I: Integer; S,S1:STRING;
|
||||
I: Integer;
|
||||
Msg: TStyleEvent;
|
||||
begin
|
||||
JSONArray := TJSONArray.Create;
|
||||
try
|
||||
FCriticalSection.Enter;
|
||||
try
|
||||
CleanupOldMessages;
|
||||
for I := 0 to FMessages.Count - 1 do
|
||||
begin
|
||||
Msg := FMessages[I];
|
||||
s:=StringReplace(Msg.FontTitle.Font,'.ttf','',[rfReplaceAll]);
|
||||
s1:=StringReplace(Msg.FontContext.Font,'.ttf','',[rfReplaceAll]);
|
||||
FCriticalSection.Enter;
|
||||
try
|
||||
for I := 0 to FMessages.Count - 1 do
|
||||
begin
|
||||
Msg := FMessages[I];
|
||||
|
||||
JSONArray.AddElement(TJSONObject.Create
|
||||
.AddPair('nickname', Msg.Title)
|
||||
.AddPair('url', Msg.Url)
|
||||
.AddPair('content', Msg.Context)
|
||||
.AddPair('timestamp', TJSONNumber.Create(DateTimeToUnix(Msg.Timestamp)))
|
||||
.AddPair('sound', Msg.SoundURL)
|
||||
.AddPair('duration', Msg.TimeMsg)
|
||||
|
||||
.AddPair('color', Msg.BlockColor)
|
||||
.AddPair('colorBorder', Msg.BorderColor)
|
||||
.AddPair('sizeBorder', TJSONNumber.Create(Msg.BorderSize))
|
||||
.AddPair('fontSize', TJSONNumber.Create(Msg.FontTitle.size))
|
||||
|
||||
.AddPair('titlecolor', Msg.FontTitle.Color)
|
||||
.AddPair('titlefamily', s)
|
||||
.AddPair('titleSize', TJSONNumber.Create(Msg.FontTitle.Size))
|
||||
.AddPair('contentcolor', Msg.FontContext.Color)
|
||||
.AddPair('contentfamily', s1)
|
||||
.AddPair('contentSize', TJSONNumber.Create(Msg.FontContext.Size))
|
||||
|
||||
|
||||
); // Ôèêñèðîâàííûé ðàçìåð òåêñòà
|
||||
JSONArray.AddElement(
|
||||
TJSONObject.Create
|
||||
.AddPair('nickname', Msg.Title)
|
||||
.AddPair('url', Msg.Url)
|
||||
.AddPair('content', Msg.Context)
|
||||
.AddPair('timestamp', TJSONNumber.Create(DateTimeToUnix(Msg.Timestamp)))
|
||||
.AddPair('sound', Msg.SoundURL)
|
||||
.AddPair('duration', Msg.TimeMsg)
|
||||
.AddPair('color', Msg.BlockColor)
|
||||
.AddPair('colorBorder', Msg.BorderColor)
|
||||
.AddPair('sizeBorder', TJSONNumber.Create(Msg.BorderSize))
|
||||
.AddPair('fontSize', TJSONNumber.Create(Msg.FontTitle.Size))
|
||||
.AddPair('titlecolor', Msg.FontTitle.Color)
|
||||
.AddPair('titlefamily', TPath.GetFileNameWithoutExtension(Msg.FontTitle.Font))
|
||||
.AddPair('titleSize', TJSONNumber.Create(Msg.FontTitle.Size))
|
||||
.AddPair('contentcolor', Msg.FontContext.Color)
|
||||
.AddPair('contentfamily', TPath.GetFileNameWithoutExtension(Msg.FontContext.Font))
|
||||
.AddPair('contentSize', TJSONNumber.Create(Msg.FontContext.Size))
|
||||
);
|
||||
end;
|
||||
finally
|
||||
FCriticalSection.Leave;
|
||||
end;
|
||||
finally
|
||||
FCriticalSection.Leave;
|
||||
end;
|
||||
|
||||
Result := JSONArray.ToString;
|
||||
Result := JSONArray.ToString;
|
||||
finally
|
||||
JSONArray.Free;
|
||||
JSONArray.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TTTW_Events.ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
|
||||
procedure TTTW_Events.ProcessFileRequest(ARequestInfo: TIdHTTPRequestInfo;
|
||||
AResponseInfo: TIdHTTPResponseInfo; const Folder: string);
|
||||
var
|
||||
FileName: string;
|
||||
FilePath: string;
|
||||
@@ -290,6 +233,7 @@ begin
|
||||
AResponseInfo.ContentStream := FS;
|
||||
AResponseInfo.ContentType := GetMIMETypeFromFile(FilePath);;
|
||||
AResponseInfo.ResponseNo := 200;
|
||||
AResponseInfo.FreeContentStream := True;
|
||||
except
|
||||
FS.Free;
|
||||
AResponseInfo.ResponseNo := 500;
|
||||
|
||||
@@ -28,7 +28,7 @@ uses
|
||||
procedure GenerationError(Sender: TObject; const ErrorMessage: string);
|
||||
procedure GenerationUpdate(Sender: TObject; const Message: string);
|
||||
public
|
||||
constructor Create(aKey:string; aSecret:string);
|
||||
constructor Create(aKey:string; aSecret:string; aPort:integer);
|
||||
destructor Destroy;
|
||||
procedure generate(prompt:string; aNick:string);
|
||||
procedure ActiveServer(aEn: boolean);
|
||||
@@ -51,10 +51,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TKandinsky_Web.Create(aKey:string; aSecret:string);
|
||||
constructor TKandinsky_Web.Create(aKey:string; aSecret:string; aPort:integer);
|
||||
begin
|
||||
IdHTTPServer1 := TIdHTTPServer.Create;
|
||||
IdHTTPServer1.DefaultPort := 8087;
|
||||
IdHTTPServer1.DefaultPort := aPort;
|
||||
IdHTTPServer1.OnCommandGet := IdHTTPServer1CommandGet;
|
||||
ka:=TFusionBrainAPI.Create(nil,aKey, aSecret);
|
||||
ka.OnGenerationDone := GenerationDone;
|
||||
|
||||
Reference in New Issue
Block a user