реструктуризация файлов, добавление вебчатов
This commit is contained in:
@@ -0,0 +1,410 @@
|
||||
unit uCustomEmoties;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, System.Generics.Collections, System.JSON, uRecords, IdHTTP, IdSSLOpenSSL,
|
||||
System.Net.HttpClient, System.SysUtils;
|
||||
|
||||
type
|
||||
TOnLog = procedure(aModul: string; aMethod: string; aMessage: string; aLevel: integer) of object;
|
||||
|
||||
|
||||
type
|
||||
TBTTV = class(TObject)
|
||||
private
|
||||
list: TList<TBTTVr>;
|
||||
FOnLog: TOnLog;
|
||||
procedure AddEmotesGlobalJson(const JsonStr: string);
|
||||
procedure AddEmotesUserJson(const JsonStr: string);
|
||||
function GetHTTP(aMethod: string): string;
|
||||
procedure toLog(alevel: integer; amethod: string; amessage: string);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure GetGlobal;
|
||||
procedure GetCustom(uid: string);
|
||||
function GenerateURL(emoteName: string): string;
|
||||
property OnLog: TOnLog read FOnLog write FOnLog;
|
||||
end;
|
||||
|
||||
type
|
||||
T7TV = class(TObject)
|
||||
private
|
||||
list7: TList<T7TVr>;
|
||||
FOnLog: TOnLog;
|
||||
procedure AddEmotesGlobalJson(const JsonStr: string);
|
||||
procedure AddEmotesUserJson(const JsonStr: string);
|
||||
function GetHTTP(aMethod: string): string;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure GetGlobal;
|
||||
procedure GetCustom(uid: string);
|
||||
function GenerateURL(emoteName: string): string;
|
||||
procedure toLog(alevel: integer; amethod: string; amessage: string);
|
||||
property OnLog: TOnLog read FOnLog write FOnLog;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TBTTV }
|
||||
|
||||
constructor TBTTV.Create;
|
||||
begin
|
||||
inherited;
|
||||
list := TList<TBTTVr>.Create;
|
||||
end;
|
||||
|
||||
destructor TBTTV.Destroy;
|
||||
begin
|
||||
FreeAndNil(list);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TBTTV.AddEmotesGlobalJson(const JsonStr: string);
|
||||
var
|
||||
JSONValue: TJSONValue;
|
||||
JSONArray: TJSONArray;
|
||||
EmoteObj: TJSONObject;
|
||||
NewEmote: TBTTVr;
|
||||
i: Integer;
|
||||
begin
|
||||
JSONValue := TJSONObject.ParseJSONValue(JsonStr);
|
||||
if not Assigned(JSONValue) then Exit;
|
||||
|
||||
try
|
||||
if not (JSONValue is TJSONArray) then Exit;
|
||||
JSONArray := TJSONArray(JSONValue);
|
||||
|
||||
for i := 0 to JSONArray.Count - 1 do
|
||||
begin
|
||||
if not (JSONArray.Items[i] is TJSONObject) then Continue;
|
||||
|
||||
EmoteObj := TJSONObject(JSONArray.Items[i]);
|
||||
NewEmote := Default(TBTTVr);
|
||||
|
||||
if Assigned(EmoteObj.GetValue('id')) then
|
||||
NewEmote.id := EmoteObj.GetValue('id').Value;
|
||||
if Assigned(EmoteObj.GetValue('code')) then
|
||||
NewEmote.code := EmoteObj.GetValue('code').Value;
|
||||
|
||||
if not NewEmote.id.IsEmpty and not NewEmote.code.IsEmpty then
|
||||
list.Add(NewEmote);
|
||||
end;
|
||||
finally
|
||||
JSONValue.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBTTV.AddEmotesUserJson(const JsonStr: string);
|
||||
var
|
||||
JSONValue, ChannelEmotes: TJSONValue;
|
||||
JSONArray: TJSONArray;
|
||||
EmoteObj: TJSONObject;
|
||||
NewEmote: TBTTVr;
|
||||
i: Integer;
|
||||
begin
|
||||
JSONValue := TJSONObject.ParseJSONValue(JsonStr);
|
||||
if not Assigned(JSONValue) then Exit;
|
||||
|
||||
try
|
||||
// Îáðàáîòêà channelEmotes
|
||||
ChannelEmotes := TJSONObject(JSONValue).GetValue('channelEmotes');
|
||||
if (ChannelEmotes is TJSONArray) then
|
||||
begin
|
||||
JSONArray := TJSONArray(ChannelEmotes);
|
||||
for i := 0 to JSONArray.Count - 1 do
|
||||
begin
|
||||
if not (JSONArray.Items[i] is TJSONObject) then Continue;
|
||||
|
||||
EmoteObj := TJSONObject(JSONArray.Items[i]);
|
||||
NewEmote := Default(TBTTVr);
|
||||
|
||||
if Assigned(EmoteObj.GetValue('id')) then
|
||||
NewEmote.id := EmoteObj.GetValue('id').Value;
|
||||
if Assigned(EmoteObj.GetValue('code')) then
|
||||
NewEmote.code := EmoteObj.GetValue('code').Value;
|
||||
|
||||
if not NewEmote.id.IsEmpty and not NewEmote.code.IsEmpty then
|
||||
list.Add(NewEmote);
|
||||
end;
|
||||
end;
|
||||
|
||||
// Îáðàáîòêà sharedEmotes
|
||||
ChannelEmotes := TJSONObject(JSONValue).GetValue('sharedEmotes');
|
||||
if (ChannelEmotes is TJSONArray) then
|
||||
begin
|
||||
JSONArray := TJSONArray(ChannelEmotes);
|
||||
for i := 0 to JSONArray.Count - 1 do
|
||||
begin
|
||||
if not (JSONArray.Items[i] is TJSONObject) then Continue;
|
||||
|
||||
EmoteObj := TJSONObject(JSONArray.Items[i]);
|
||||
NewEmote := Default(TBTTVr);
|
||||
|
||||
if Assigned(EmoteObj.GetValue('id')) then
|
||||
NewEmote.id := EmoteObj.GetValue('id').Value;
|
||||
if Assigned(EmoteObj.GetValue('code')) then
|
||||
NewEmote.code := EmoteObj.GetValue('code').Value;
|
||||
|
||||
if not NewEmote.id.IsEmpty and not NewEmote.code.IsEmpty then
|
||||
list.Add(NewEmote);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
JSONValue.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBTTV.GenerateURL(emoteName: string): string;
|
||||
var
|
||||
emote: TBTTVr;
|
||||
begin
|
||||
Result := '';
|
||||
for emote in list do
|
||||
begin
|
||||
if emote.code = emoteName then
|
||||
begin
|
||||
Result := 'https://cdn.betterttv.net/emote/' + emote.id + '/1x';
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBTTV.GetCustom(uid: string);
|
||||
begin
|
||||
if not uid.IsEmpty then
|
||||
AddEmotesUserJson(GetHTTP('users/twitch/' + uid));
|
||||
end;
|
||||
|
||||
procedure TBTTV.GetGlobal;
|
||||
begin
|
||||
AddEmotesGlobalJson(GetHTTP('emotes/global'));
|
||||
end;
|
||||
|
||||
function TBTTV.GetHTTP(aMethod: string): string;
|
||||
var
|
||||
http: TIdHTTP;
|
||||
ssl: TIdSSLIOHandlerSocketOpenSSL;
|
||||
begin
|
||||
Result := '';
|
||||
http := TIdHTTP.Create(nil);
|
||||
try
|
||||
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
|
||||
try
|
||||
http.IOHandler := ssl;
|
||||
ssl.SSLOptions.SSLVersions := [sslvTLSv1_2];
|
||||
http.Request.UserAgent :=
|
||||
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||
Result := http.Get('https://api.betterttv.net/3/cached/' + aMethod);
|
||||
finally
|
||||
ssl.Free;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
toLog(2,'GetCustom',e.Message);
|
||||
Result := '';
|
||||
end;
|
||||
end;
|
||||
http.Free;
|
||||
end;
|
||||
|
||||
procedure TBTTV.toLog(alevel: integer; amethod, amessage: string);
|
||||
begin
|
||||
if Assigned(FOnLog) then
|
||||
FOnLog('uCustomEmoties.TBTTV', amethod, amessage, alevel);
|
||||
end;
|
||||
|
||||
{ T7TV }
|
||||
|
||||
constructor T7TV.Create;
|
||||
begin
|
||||
inherited;
|
||||
list7 := TList<T7TVr>.Create;
|
||||
end;
|
||||
|
||||
destructor T7TV.Destroy;
|
||||
begin
|
||||
FreeAndNil(list7);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure T7TV.AddEmotesGlobalJson(const JsonStr: string);
|
||||
var
|
||||
Root: TJSONObject;
|
||||
EmotesArray: TJSONArray;
|
||||
EmoteObj, DataObj, HostObj: TJSONObject;
|
||||
FilesArray: TJSONArray;
|
||||
i: Integer;
|
||||
Emote: T7TVr;
|
||||
BaseUrl: string;
|
||||
begin
|
||||
Root := TJSONObject.ParseJSONValue(JsonStr) as TJSONObject;
|
||||
if not Assigned(Root) then Exit;
|
||||
|
||||
try
|
||||
EmotesArray := Root.GetValue('emotes') as TJSONArray;
|
||||
if not Assigned(EmotesArray) then Exit;
|
||||
|
||||
for i := 0 to EmotesArray.Count - 1 do
|
||||
begin
|
||||
if not (EmotesArray.Items[i] is TJSONObject) then Continue;
|
||||
|
||||
EmoteObj := EmotesArray.Items[i] as TJSONObject;
|
||||
Emote := Default(T7TVr);
|
||||
|
||||
// Ïîëó÷åíèå áàçîâûõ äàííûõ
|
||||
if Assigned(EmoteObj.GetValue('id')) then
|
||||
Emote.id := EmoteObj.GetValue('id').Value;
|
||||
if Assigned(EmoteObj.GetValue('name')) then
|
||||
Emote.code := EmoteObj.GetValue('name').Value;
|
||||
|
||||
// Ïîëó÷åíèå URL
|
||||
DataObj := EmoteObj.GetValue('data') as TJSONObject;
|
||||
if Assigned(DataObj) then
|
||||
begin
|
||||
HostObj := DataObj.GetValue('host') as TJSONObject;
|
||||
if Assigned(HostObj) then
|
||||
begin
|
||||
if Assigned(HostObj.GetValue('url')) then
|
||||
begin
|
||||
BaseUrl := 'https:' + HostObj.GetValue('url').Value;
|
||||
|
||||
FilesArray := HostObj.GetValue('files') as TJSONArray;
|
||||
if Assigned(FilesArray) and (FilesArray.Count > 0) and
|
||||
(FilesArray.Items[0] is TJSONObject) then
|
||||
begin
|
||||
Emote.url := BaseUrl + '/' +
|
||||
(FilesArray.Items[0] as TJSONObject).GetValue('name').Value;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not Emote.id.IsEmpty and not Emote.code.IsEmpty and not Emote.url.IsEmpty then
|
||||
list7.Add(Emote);
|
||||
end;
|
||||
finally
|
||||
Root.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure T7TV.AddEmotesUserJson(const JsonStr: string);
|
||||
var
|
||||
Root, EmoteSet, EmoteObj, DataObj, HostObj: TJSONObject;
|
||||
EmotesArr, FilesArr: TJSONArray;
|
||||
i: Integer;
|
||||
Emote: T7TVr;
|
||||
BaseUrl: string;
|
||||
begin
|
||||
Root := TJSONObject.ParseJSONValue(JsonStr) as TJSONObject;
|
||||
if not Assigned(Root) then Exit;
|
||||
|
||||
try
|
||||
if not Root.TryGetValue<TJSONObject>('emote_set', EmoteSet) then Exit;
|
||||
|
||||
EmotesArr := EmoteSet.GetValue('emotes') as TJSONArray;
|
||||
if not Assigned(EmotesArr) then Exit;
|
||||
|
||||
for i := 0 to EmotesArr.Count - 1 do
|
||||
begin
|
||||
if not (EmotesArr.Items[i] is TJSONObject) then Continue;
|
||||
|
||||
EmoteObj := EmotesArr.Items[i] as TJSONObject;
|
||||
Emote := Default(T7TVr);
|
||||
|
||||
// Ïîëó÷åíèå áàçîâûõ äàííûõ
|
||||
if Assigned(EmoteObj.GetValue('id')) then
|
||||
Emote.id := EmoteObj.GetValue('id').Value;
|
||||
if Assigned(EmoteObj.GetValue('name')) then
|
||||
Emote.code := EmoteObj.GetValue('name').Value;
|
||||
|
||||
// Ïîëó÷åíèå URL
|
||||
DataObj := EmoteObj.GetValue('data') as TJSONObject;
|
||||
if Assigned(DataObj) then
|
||||
begin
|
||||
HostObj := DataObj.GetValue('host') as TJSONObject;
|
||||
if Assigned(HostObj) then
|
||||
begin
|
||||
if Assigned(HostObj.GetValue('url')) then
|
||||
begin
|
||||
BaseUrl := 'https:' + HostObj.GetValue('url').Value;
|
||||
|
||||
FilesArr := HostObj.GetValue('files') as TJSONArray;
|
||||
if Assigned(FilesArr) and (FilesArr.Count > 0) and
|
||||
(FilesArr.Items[0] is TJSONObject) then
|
||||
begin
|
||||
Emote.url := BaseUrl + '/' +
|
||||
(FilesArr.Items[0] as TJSONObject).GetValue('name').Value;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not Emote.id.IsEmpty and not Emote.code.IsEmpty and not Emote.url.IsEmpty then
|
||||
list7.Add(Emote);
|
||||
end;
|
||||
finally
|
||||
Root.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function T7TV.GenerateURL(emoteName: string): string;
|
||||
var
|
||||
emote: T7TVr;
|
||||
begin
|
||||
Result := '';
|
||||
for emote in list7 do
|
||||
begin
|
||||
if emote.code = emoteName then
|
||||
begin
|
||||
Result := emote.url;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure T7TV.GetCustom(uid: string);
|
||||
begin
|
||||
if not uid.IsEmpty then
|
||||
AddEmotesUserJson(GetHTTP('users/twitch/' + uid));
|
||||
end;
|
||||
|
||||
procedure T7TV.GetGlobal;
|
||||
begin
|
||||
AddEmotesGlobalJson(GetHTTP('emote-sets/global'));
|
||||
end;
|
||||
|
||||
function T7TV.GetHTTP(aMethod: string): string;
|
||||
var
|
||||
HttpClient: THTTPClient;
|
||||
Response: IHTTPResponse;
|
||||
begin
|
||||
Result := '';
|
||||
HttpClient := THTTPClient.Create;
|
||||
try
|
||||
try
|
||||
HttpClient.UserAgent := 'Mozilla/5.0';
|
||||
Response := HttpClient.Get('https://api.7tv.app/v3/' + aMethod);
|
||||
Result := Response.ContentAsString;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
toLog(2,'GetHTTP',e.Message);
|
||||
Result := '';
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
HttpClient.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure T7TV.toLog(alevel: integer; amethod, amessage: string);
|
||||
begin
|
||||
if Assigned(FOnLog) then
|
||||
FOnLog('uCustomEmoties.T7TV', amethod, amessage, alevel);
|
||||
end;
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user