mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 16:59:39 -05:00
Compare commits
56 Commits
develop-1.
...
1.6.1-Rele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2ea00bcae | ||
|
|
4297af1349 | ||
|
|
d09c90ef54 | ||
|
|
9c96c8899a | ||
|
|
301df6392d | ||
|
|
fb9fc04ee5 | ||
|
|
43a8ba4225 | ||
|
|
dffccf1f0b | ||
|
|
6dcccccb78 | ||
|
|
0d467d79c3 | ||
|
|
33c98508c0 | ||
|
|
67948b14cc | ||
|
|
22e11a7822 | ||
|
|
4545503441 | ||
|
|
498d34a90b | ||
|
|
103ed7e3ed | ||
|
|
67e70c34bc | ||
|
|
786c24d267 | ||
|
|
966d2f65d8 | ||
|
|
7ba7143f5a | ||
|
|
92fde03f2b | ||
|
|
e058290118 | ||
|
|
d25741b229 | ||
|
|
560a8d7c3b | ||
|
|
6178bc25cf | ||
|
|
48d1138754 | ||
|
|
a5320db820 | ||
|
|
4e1ab35a60 | ||
|
|
cef4972f37 | ||
|
|
713c90a271 | ||
|
|
71853db5cc | ||
|
|
ef90d4cd58 | ||
|
|
dad4048bc0 | ||
|
|
9ba049d37a | ||
|
|
f7d657371b | ||
|
|
eea691a5aa | ||
|
|
a249ac0cdd | ||
|
|
b82c7184b3 | ||
|
|
29631ac468 | ||
|
|
15c642297c | ||
|
|
d3004d76c1 | ||
|
|
3ae73072ff | ||
|
|
9c5f97157a | ||
|
|
ea847bb883 | ||
|
|
45bac053b9 | ||
|
|
8cb647f27a | ||
|
|
ffbd67eef4 | ||
|
|
e923f3fad7 | ||
|
|
faa1185b97 | ||
|
|
ead954dd27 | ||
|
|
e37b30ff12 | ||
|
|
7a5c00d99a | ||
|
|
407f51fa73 | ||
|
|
8581df7f49 | ||
|
|
3e52523644 | ||
|
|
3387986ced |
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
<artifactId>TikTokLiveJava</artifactId>
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<version>1.3.0-Release</version>
|
<version>1.6.0-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>API</artifactId>
|
<artifactId>API</artifactId>
|
||||||
|
|||||||
@@ -47,11 +47,23 @@ public class TikTokCommentEvent extends TikTokHeaderEvent {
|
|||||||
|
|
||||||
public TikTokCommentEvent(WebcastChatMessage msg) {
|
public TikTokCommentEvent(WebcastChatMessage msg) {
|
||||||
super(msg.getCommon());
|
super(msg.getCommon());
|
||||||
user = User.map(msg.getUser(),msg.getUserIdentity());
|
user = User.map(msg.getUser(), msg.getUserIdentity());
|
||||||
text = msg.getContent();
|
text = msg.getContent();
|
||||||
visibleToSender = msg.getVisibleToSender();
|
visibleToSender = msg.getVisibleToSender();
|
||||||
getUserLanguage = msg.getContentLanguage();
|
getUserLanguage = msg.getContentLanguage();
|
||||||
mentionedUser = User.map(msg.getAtUser());
|
mentionedUser = User.map(msg.getAtUser());
|
||||||
pictures = msg.getEmotesListList().stream().map(e -> Picture.map(e.getEmote().getImage())).toList();
|
pictures = msg.getEmotesListList().stream().map(e -> Picture.map(e.getEmote().getImage())).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static TikTokCommentEvent of(String userName, String message) {
|
||||||
|
var builder = WebcastChatMessage.newBuilder();
|
||||||
|
builder.setUser(io.github.jwdeveloper.tiktok.messages.data.User.newBuilder()
|
||||||
|
.setNickname(userName)
|
||||||
|
.build());
|
||||||
|
builder.setContentLanguage("en");
|
||||||
|
builder.setVisibleToSender(true);
|
||||||
|
builder.setContent(message);
|
||||||
|
return new TikTokCommentEvent(builder.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ import io.github.jwdeveloper.tiktok.annotations.EventType;
|
|||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.LinkMicArmy;
|
import io.github.jwdeveloper.tiktok.data.models.LinkMicArmy;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.enums.LinkMicBattleStatus;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicArmies;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicArmies;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered every time a battle participant receives points. Contains the current status of the battle and the army that suported the group.
|
* Triggered every time a battle participant receives points. Contains the current status of the battle and the army that suported the group.
|
||||||
*/
|
*/
|
||||||
@@ -40,8 +40,10 @@ import java.util.List;
|
|||||||
@EventMeta(eventType = EventType.Message)
|
@EventMeta(eventType = EventType.Message)
|
||||||
public class TikTokLinkMicArmiesEvent extends TikTokHeaderEvent {
|
public class TikTokLinkMicArmiesEvent extends TikTokHeaderEvent {
|
||||||
private final Long battleId;
|
private final Long battleId;
|
||||||
|
/**
|
||||||
private final Integer battleStatus;
|
true if battle is finished otherwise false
|
||||||
|
*/
|
||||||
|
private final boolean finished;
|
||||||
|
|
||||||
private final Picture picture;
|
private final Picture picture;
|
||||||
|
|
||||||
@@ -52,6 +54,6 @@ public class TikTokLinkMicArmiesEvent extends TikTokHeaderEvent {
|
|||||||
battleId = msg.getId();
|
battleId = msg.getId();
|
||||||
armies = msg.getBattleItemsList().stream().map(LinkMicArmy::new).toList();
|
armies = msg.getBattleItemsList().stream().map(LinkMicArmy::new).toList();
|
||||||
picture = Picture.map(msg.getImage());
|
picture = Picture.map(msg.getImage());
|
||||||
battleStatus = msg.getBattleStatus();
|
finished = msg.getBattleStatus() == LinkMicBattleStatus.ARMY_FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,29 +22,62 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.data.events;
|
package io.github.jwdeveloper.tiktok.data.events;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
import io.github.jwdeveloper.tiktok.annotations.*;
|
||||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.LinkMicBattleTeam;
|
import io.github.jwdeveloper.tiktok.data.models.battles.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.enums.LinkMicBattleStatus;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
||||||
import lombok.Getter;
|
import lombok.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered every time a battle starts.
|
* Triggered every time a battle starts & ends
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@EventMeta(eventType = EventType.Message)
|
@EventMeta(eventType = EventType.Message)
|
||||||
public class TikTokLinkMicBattleEvent extends TikTokHeaderEvent {
|
public class TikTokLinkMicBattleEvent extends TikTokHeaderEvent
|
||||||
private final Long battleId;
|
{
|
||||||
private final List<LinkMicBattleTeam> team1;
|
private final Long battleId;
|
||||||
private final List<LinkMicBattleTeam> team2;
|
/**
|
||||||
|
true if battle is finished otherwise false
|
||||||
|
*/
|
||||||
|
private final boolean finished;
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
private final boolean oneVsOne;
|
||||||
|
private final List<Team> teams;
|
||||||
|
|
||||||
public TikTokLinkMicBattleEvent(WebcastLinkMicBattle msg) {
|
public TikTokLinkMicBattleEvent(WebcastLinkMicBattle msg) {
|
||||||
super(msg.getCommon());
|
super(msg.getCommon());
|
||||||
battleId = msg.getId();
|
battleId = msg.getId();
|
||||||
team1 = msg.getTeams1List().stream().map(LinkMicBattleTeam::new).toList();
|
finished = msg.getBattleStatus() == LinkMicBattleStatus.BATTLE_FINISHED;
|
||||||
team2 = msg.getTeams2List().stream().map(LinkMicBattleTeam::new).toList();
|
teams = new ArrayList<>();
|
||||||
}
|
if (msg.getHostTeamCount() == 2) { // 1v1 battle
|
||||||
}
|
teams.add(new Team1v1(msg.getHostTeam(0), msg));
|
||||||
|
teams.add(new Team1v1(msg.getHostTeam(1), msg));
|
||||||
|
oneVsOne = true;
|
||||||
|
} else { // 2v2 battle
|
||||||
|
if (isFinished()) {
|
||||||
|
teams.add(new Team2v2(msg.getHostData2V2List().stream().filter(data -> data.getTeamNumber() == 1).findFirst().orElse(null), msg));
|
||||||
|
teams.add(new Team2v2(msg.getHostData2V2List().stream().filter(data -> data.getTeamNumber() == 2).findFirst().orElse(null), msg));
|
||||||
|
} else {
|
||||||
|
teams.add(new Team2v2(msg.getHostTeam(0), msg.getHostTeam(1), msg));
|
||||||
|
teams.add(new Team2v2(msg.getHostTeam(2), msg.getHostTeam(3), msg));
|
||||||
|
}
|
||||||
|
oneVsOne = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info:
|
||||||
|
// - msg.getDetailsList() & msg.getViewerTeamList() both only have content when battle is finished
|
||||||
|
// - msg.getDetailsCount() & msg.getViewerTeamCount() always is 2 only when battle is finished
|
||||||
|
// - msg.getHostTeamCount() always is 2 for 1v1 or 4 for 2v2
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean is1v1() {
|
||||||
|
return oneVsOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean is2v2() {
|
||||||
|
return !oneVsOne;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,10 +36,10 @@ import lombok.Getter;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@EventMeta(eventType = EventType.Message)
|
@EventMeta(eventType = EventType.Message)
|
||||||
public class TikTokSubscribeEvent extends TikTokHeaderEvent
|
public class TikTokSubscribeEvent extends TikTokHeaderEvent {
|
||||||
{
|
|
||||||
private final User user;
|
private final User user;
|
||||||
|
|
||||||
|
|
||||||
public TikTokSubscribeEvent(WebcastMemberMessage msg) {
|
public TikTokSubscribeEvent(WebcastMemberMessage msg) {
|
||||||
super(msg.getCommon());
|
super(msg.getCommon());
|
||||||
user = User.map(msg.getUser());
|
user = User.map(msg.getUser());
|
||||||
@@ -52,4 +52,11 @@ public class TikTokSubscribeEvent extends TikTokHeaderEvent
|
|||||||
user.addAttribute(UserAttribute.Subscriber);
|
user.addAttribute(UserAttribute.Subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TikTokSubscribeEvent of(String userName) {
|
||||||
|
return new TikTokSubscribeEvent(WebcastMemberMessage.newBuilder()
|
||||||
|
.setUser(io.github.jwdeveloper.tiktok.messages.data.User.newBuilder()
|
||||||
|
.setNickname(userName)
|
||||||
|
.build())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
package io.github.jwdeveloper.tiktok.data.events.gift;
|
package io.github.jwdeveloper.tiktok.data.events.gift;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.annotations.*;
|
import io.github.jwdeveloper.tiktok.annotations.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||||
@@ -32,7 +33,7 @@ import lombok.Getter;
|
|||||||
/**
|
/**
|
||||||
* Triggered every time gift is sent
|
* Triggered every time gift is sent
|
||||||
*
|
*
|
||||||
* @see GiftSendType it has 3 states
|
* @see GiftComboStateType it has 3 states
|
||||||
*
|
*
|
||||||
* <p>Example when user sends gift with combo</p>
|
* <p>Example when user sends gift with combo</p>
|
||||||
* <p>>Combo: 1 -> comboState = GiftSendType.Begin</p>
|
* <p>>Combo: 1 -> comboState = GiftSendType.Begin</p>
|
||||||
@@ -45,10 +46,21 @@ import lombok.Getter;
|
|||||||
@EventMeta(eventType = EventType.Message)
|
@EventMeta(eventType = EventType.Message)
|
||||||
@Getter
|
@Getter
|
||||||
public class TikTokGiftComboEvent extends TikTokGiftEvent {
|
public class TikTokGiftComboEvent extends TikTokGiftEvent {
|
||||||
private final GiftSendType comboState;
|
private final GiftComboStateType comboState;
|
||||||
|
|
||||||
public TikTokGiftComboEvent(Gift gift, User host, WebcastGiftMessage msg, GiftSendType comboState) {
|
public TikTokGiftComboEvent(Gift gift, User host, WebcastGiftMessage msg, GiftComboStateType comboState) {
|
||||||
super(gift, host, msg);
|
super(gift, host, msg);
|
||||||
this.comboState = comboState;
|
this.comboState = comboState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TikTokGiftComboEvent of(Gift gift, int combo, GiftComboStateType comboState) {
|
||||||
|
return new TikTokGiftComboEvent(
|
||||||
|
gift,
|
||||||
|
new User(0L, "Test", new Picture("")),
|
||||||
|
WebcastGiftMessage
|
||||||
|
.newBuilder()
|
||||||
|
.setComboCount(combo)
|
||||||
|
.build(),
|
||||||
|
comboState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,7 @@ package io.github.jwdeveloper.tiktok.data.events.gift;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.annotations.*;
|
import io.github.jwdeveloper.tiktok.annotations.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||||
@@ -55,4 +56,20 @@ public class TikTokGiftEvent extends TikTokHeaderEvent {
|
|||||||
}
|
}
|
||||||
combo = msg.getComboCount();
|
combo = msg.getComboCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TikTokGiftEvent(Gift gift) {
|
||||||
|
this.gift = gift;
|
||||||
|
user = new User(0L, "sender", new Picture(""));
|
||||||
|
toUser = new User(0L, "receiver", new Picture(""));
|
||||||
|
combo = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static TikTokGiftEvent of(Gift gift) {
|
||||||
|
return new TikTokGiftEvent(gift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TikTokGiftEvent of(String name, int id, int diamonds) {
|
||||||
|
return TikTokGiftEvent.of(new Gift(id, name, diamonds, ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,8 +24,10 @@ package io.github.jwdeveloper.tiktok.data.events.social;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
||||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastMemberMessage;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
@@ -45,4 +47,12 @@ public class TikTokFollowEvent extends TikTokHeaderEvent
|
|||||||
totalFollowers = msg.getFollowCount();
|
totalFollowers = msg.getFollowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TikTokFollowEvent of(String userName)
|
||||||
|
{
|
||||||
|
return new TikTokFollowEvent(WebcastSocialMessage.newBuilder()
|
||||||
|
.setUser(io.github.jwdeveloper.tiktok.messages.data.User.newBuilder()
|
||||||
|
.setNickname(userName)
|
||||||
|
.build())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import io.github.jwdeveloper.tiktok.annotations.EventMeta;
|
|||||||
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
import io.github.jwdeveloper.tiktok.annotations.EventType;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLikeMessage;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastMemberMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastMemberMessage;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastSocialMessage;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -47,4 +48,13 @@ public class TikTokJoinEvent extends TikTokHeaderEvent {
|
|||||||
user = User.map(msg.getUser());
|
user = User.map(msg.getUser());
|
||||||
totalUsers = msg.getMemberCount();
|
totalUsers = msg.getMemberCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TikTokJoinEvent of(String userName)
|
||||||
|
{
|
||||||
|
return new TikTokJoinEvent(WebcastMemberMessage.newBuilder()
|
||||||
|
.setUser(io.github.jwdeveloper.tiktok.messages.data.User.newBuilder()
|
||||||
|
.setNickname(userName)
|
||||||
|
.build())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,4 +57,15 @@ public class TikTokLikeEvent extends TikTokHeaderEvent
|
|||||||
likes = msg.getCount();
|
likes = msg.getCount();
|
||||||
totalLikes = msg.getTotal();
|
totalLikes = msg.getTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TikTokLikeEvent of(String userName, int likes)
|
||||||
|
{
|
||||||
|
return new TikTokLikeEvent(WebcastLikeMessage.newBuilder()
|
||||||
|
.setCount(likes)
|
||||||
|
.setTotal(likes)
|
||||||
|
.setUser(io.github.jwdeveloper.tiktok.messages.data.User.newBuilder()
|
||||||
|
.setNickname(userName)
|
||||||
|
.build())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,4 +46,4 @@ public class LinkMicArmy {
|
|||||||
List<User> Users;
|
List<User> Users;
|
||||||
Integer Points;
|
Integer Points;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.data.models;
|
|
||||||
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class LinkMicBattleTeam {
|
|
||||||
Long teamId;
|
|
||||||
List<User> users;
|
|
||||||
|
|
||||||
public LinkMicBattleTeam(WebcastLinkMicBattle.LinkMicBattleTeam team) {
|
|
||||||
this.teamId = team.getId();
|
|
||||||
this.users = team.getUsersList().stream().map(User::new).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -44,11 +44,11 @@ public class Picture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Picture map(io.github.jwdeveloper.tiktok.messages.data.Image profilePicture) {
|
public static Picture map(io.github.jwdeveloper.tiktok.messages.data.Image profilePicture) {
|
||||||
var index = profilePicture.getUrlListCount() - 1;
|
var index = profilePicture.getUrlCount() - 1;
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return new Picture("");
|
return new Picture("");
|
||||||
}
|
}
|
||||||
var url = profilePicture.getUrlList(index);
|
var url = profilePicture.getUrl(index);
|
||||||
return new Picture(url);
|
return new Picture(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.data.models.battles;
|
||||||
|
|
||||||
|
public abstract class Team {
|
||||||
|
/**
|
||||||
|
* Provides a check for verifying if this team represents a 1v1 Team.
|
||||||
|
* @return true if this team is of type {@link Team1v1}, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean is1v1Team() {
|
||||||
|
return this instanceof Team1v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a check for verifying if this team represents a 1v1 Team.
|
||||||
|
* @return true if this team is of type {@link Team1v1}, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean is2v2Team() {
|
||||||
|
return this instanceof Team2v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to get this team as a {@link Team1v1}. If this team is of some
|
||||||
|
* other type, an {@link IllegalStateException} will result. Hence it is best to use this method
|
||||||
|
* after ensuring that this element is of the desired type by calling {@link #is1v1Team()} first.
|
||||||
|
*
|
||||||
|
* @return this team as a {@link Team1v1}.
|
||||||
|
* @throws IllegalStateException if this team is of another type.
|
||||||
|
*/
|
||||||
|
public Team1v1 getAs1v1Team() {
|
||||||
|
if (is1v1Team())
|
||||||
|
return (Team1v1) this;
|
||||||
|
throw new IllegalStateException("Not a 1v1Team: " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to get this team as a {@link Team2v2}. If this team is of some
|
||||||
|
* other type, an {@link IllegalStateException} will result. Hence it is best to use this method
|
||||||
|
* after ensuring that this element is of the desired type by calling {@link #is2v2Team()} first.
|
||||||
|
*
|
||||||
|
* @return this team as a {@link Team2v2}.
|
||||||
|
* @throws IllegalStateException if this team is of another type.
|
||||||
|
*/
|
||||||
|
public Team2v2 getAs2v2Team() {
|
||||||
|
if (is2v2Team())
|
||||||
|
return (Team2v2) this;
|
||||||
|
throw new IllegalStateException("Not a 2v2Team: " + this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.data.models.battles;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Team1v1 extends Team
|
||||||
|
{
|
||||||
|
/** Value >= 0 when finished otherwise -1 */
|
||||||
|
private final int totalPoints;
|
||||||
|
private final int winStreak;
|
||||||
|
private final User host;
|
||||||
|
private final List<Viewer> viewers;
|
||||||
|
|
||||||
|
public Team1v1(WebcastLinkMicBattle.LinkMicBattleHost hostTeam, WebcastLinkMicBattle msg) {
|
||||||
|
long hostId = hostTeam.getId();
|
||||||
|
this.winStreak = msg.getTeamDataList().stream().filter(data -> data.getTeamId() == hostId).map(data -> data.getData().getWinStreak()).findFirst().orElse(-1);
|
||||||
|
this.totalPoints = msg.getDetailsList().stream().filter(dets -> dets.getId() == hostId).map(dets -> dets.getSummary().getPoints()).findFirst().orElse(-1);
|
||||||
|
this.host = new User(hostTeam.getHostGroup(0).getHost(0));
|
||||||
|
this.viewers = msg.getViewerTeamList().stream().filter(team -> team.getId() == hostId).findFirst().map(topViewers ->
|
||||||
|
topViewers.getViewerGroup(0).getViewerList().stream().map(Viewer::new).toList()).orElseGet(ArrayList::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.data.models.battles;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Team2v2 extends Team {
|
||||||
|
/** Value >= 0 when finished otherwise -1 */
|
||||||
|
private final int totalPoints;
|
||||||
|
|
||||||
|
private final List<User> hosts;
|
||||||
|
private final List<Viewer> viewers;
|
||||||
|
|
||||||
|
public Team2v2(WebcastLinkMicBattle.LinkMicBattleHost hostTeam1, WebcastLinkMicBattle.LinkMicBattleHost hostTeam2, WebcastLinkMicBattle msg) {
|
||||||
|
this.totalPoints = -1;
|
||||||
|
this.hosts = List.of(new User(hostTeam1.getHostGroup(0).getHost(0)), new User(hostTeam2.getHostGroup(0).getHost(0)));
|
||||||
|
this.viewers = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Team2v2(WebcastLinkMicBattle.Host2v2Data hd, WebcastLinkMicBattle msg) {
|
||||||
|
this.totalPoints = hd.getTotalPoints();
|
||||||
|
var host = new User(msg.getHostTeamList().stream().filter(data -> data.getId() == hd.getHostdata(0).getHostId()).findFirst().orElseThrow().getHostGroup(0).getHost(0));
|
||||||
|
var cohost = new User(msg.getHostTeamList().stream().filter(data -> data.getId() == hd.getHostdata(1).getHostId()).findFirst().orElseThrow().getHostGroup(0).getHost(0));
|
||||||
|
this.hosts = List.of(host, cohost);
|
||||||
|
this.viewers = msg.getViewerTeamList().stream().filter(team -> team.getId() == host.getId() || team.getId() == cohost.getId()).findFirst().map(topViewers ->
|
||||||
|
topViewers.getViewerGroup(0).getViewerList().stream().map(Viewer::new).toList()).orElseGet(ArrayList::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.data.models.battles;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Viewer {
|
||||||
|
private final User user;
|
||||||
|
private final int points;
|
||||||
|
|
||||||
|
public Viewer(WebcastLinkMicBattle.LinkMicBattleTopViewers.TopViewerGroup.TopViewer topViewer) {
|
||||||
|
this.user = new User(topViewer.getId(), null, topViewer.getProfileId(), Picture.map(topViewer.getImages(0)));
|
||||||
|
this.points = topViewer.getPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,9 +2,7 @@ package io.github.jwdeveloper.tiktok.data.models.gifts;
|
|||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import lombok.*;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Gift {
|
public class Gift {
|
||||||
@@ -16,7 +14,7 @@ public class Gift {
|
|||||||
|
|
||||||
private final int diamondCost;
|
private final int diamondCost;
|
||||||
|
|
||||||
private final Picture picture;
|
private Picture picture;
|
||||||
|
|
||||||
private final JsonObject properties;
|
private final JsonObject properties;
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,16 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.data.models.gifts;
|
package io.github.jwdeveloper.tiktok.data.models.gifts;
|
||||||
|
|
||||||
public enum GiftSendType
|
//TODO it should be called GiftComboStateType
|
||||||
{
|
public enum GiftComboStateType {
|
||||||
Finished,
|
Finished,
|
||||||
Begin,
|
Begin,
|
||||||
Active;
|
Active;
|
||||||
|
|
||||||
public static GiftSendType fromNumber(long number)
|
public static GiftComboStateType fromNumber(long number) {
|
||||||
{
|
|
||||||
return switch ((int) number) {
|
return switch ((int) number) {
|
||||||
case 1, 2, 4 -> GiftSendType.Active;
|
case 1, 2, 4 -> GiftComboStateType.Active;
|
||||||
default -> GiftSendType.Finished;
|
default -> GiftComboStateType.Finished;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ package io.github.jwdeveloper.tiktok.data.models.users;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.models.badges.Badge;
|
import io.github.jwdeveloper.tiktok.data.models.badges.Badge;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastEnvelopeMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@@ -136,6 +136,14 @@ public class User {
|
|||||||
this.picture = picture;
|
this.picture = picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User(long id, String name, String profileId, Picture picture) {
|
||||||
|
this(id, name, profileId, picture, 0, 0, List.of(Badge.empty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(WebcastLinkMicBattle.LinkMicBattleHost.HostGroup.Host host) {
|
||||||
|
this(host.getId(), host.getName(), host.getProfileId(), Picture.map(host.getImages(0)));
|
||||||
|
}
|
||||||
|
|
||||||
public User(io.github.jwdeveloper.tiktok.messages.data.User user) {
|
public User(io.github.jwdeveloper.tiktok.messages.data.User user) {
|
||||||
this(user.getId(), user.getDisplayId(), Picture.map(user.getAvatarThumb()));
|
this(user.getId(), user.getDisplayId(), Picture.map(user.getAvatarThumb()));
|
||||||
profileName = user.getNickname();
|
profileName = user.getNickname();
|
||||||
@@ -159,7 +167,6 @@ public class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static User EMPTY = new User(0L,
|
public static User EMPTY = new User(0L,
|
||||||
"",
|
"",
|
||||||
Picture.Empty(),
|
Picture.Empty(),
|
||||||
@@ -209,4 +216,18 @@ public class User {
|
|||||||
0,
|
0,
|
||||||
List.of(Badge.empty()));
|
List.of(Badge.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + "'" +
|
||||||
|
", profileName='" + profileName + "'" +
|
||||||
|
", picture=" + picture +
|
||||||
|
", following=" + following +
|
||||||
|
", followers=" + followers +
|
||||||
|
", badges=" + badges +
|
||||||
|
", attributes=" + attributes +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ public class LiveData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
public static class Response {
|
public static class Response {
|
||||||
private String json;
|
private String json;
|
||||||
private LiveStatus liveStatus;
|
private LiveStatus liveStatus;
|
||||||
@@ -45,6 +46,11 @@ public class LiveData {
|
|||||||
private boolean ageRestricted;
|
private boolean ageRestricted;
|
||||||
private User host;
|
private User host;
|
||||||
private LiveType liveType;
|
private LiveType liveType;
|
||||||
|
public Response() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LiveStatus {
|
public enum LiveStatus {
|
||||||
|
|||||||
@@ -35,10 +35,20 @@ public class LiveClientSettings {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO: give better description
|
||||||
|
* <p>
|
||||||
|
* sets client in the offline mode, so it do not connects to TikTok servers
|
||||||
|
* it makes sense to use it when you are testing client with your custom events
|
||||||
|
*/
|
||||||
|
private boolean offline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: give better description
|
||||||
|
* <p>
|
||||||
* Determines if gifts data is downloaded before TikTokLive starts,
|
* Determines if gifts data is downloaded before TikTokLive starts,
|
||||||
* when `false` then client.giftManager() does not contain initial gifts
|
* when `false` then client.giftManager() does not contain initial gifts
|
||||||
*/
|
*/
|
||||||
private boolean fetchGifts;
|
private boolean fetchGifts = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ISO-Language for Client
|
* ISO-Language for Client
|
||||||
@@ -76,14 +86,22 @@ public class LiveClientSettings {
|
|||||||
private HttpClientSettings httpSettings;
|
private HttpClientSettings httpSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional: Sometimes not every messages from chat are send to TikTokLiveJava to fix this issue you can set sessionId
|
* Interval of time in milliseconds between pings to TikTok
|
||||||
* documentation how to obtain sessionId https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages
|
* @apiNote Min: 250 (0.25 seconds), Default: 5000 (5 seconds)
|
||||||
*/
|
*/
|
||||||
|
private long pingInterval = 5000;
|
||||||
|
|
||||||
|
/** Throw an exception on 18+ Age Restriction */
|
||||||
|
private boolean throwOnAgeRestriction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional: Sometimes not every messages from chat are send to TikTokLiveJava to fix this issue you can set sessionId
|
||||||
|
* @see <a href="https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages">Documentation: How to obtain sessionId</a>
|
||||||
|
*/
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional: By default roomID is fetched before connect to live, but you can set it manually
|
* Optional: By default roomID is fetched before connect to live, but you can set it manually
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private String roomId;
|
private String roomId;
|
||||||
|
|
||||||
@@ -92,8 +110,7 @@ public class LiveClientSettings {
|
|||||||
*/
|
*/
|
||||||
private String apiKey;
|
private String apiKey;
|
||||||
|
|
||||||
public static LiveClientSettings createDefault()
|
public static LiveClientSettings createDefault() {
|
||||||
{
|
|
||||||
var httpSettings = new HttpClientSettings();
|
var httpSettings = new HttpClientSettings();
|
||||||
httpSettings.getParams().putAll(DefaultClientParams());
|
httpSettings.getParams().putAll(DefaultClientParams());
|
||||||
httpSettings.getHeaders().putAll(DefaultRequestHeaders());
|
httpSettings.getHeaders().putAll(DefaultRequestHeaders());
|
||||||
@@ -166,4 +183,6 @@ public class LiveClientSettings {
|
|||||||
headers.put("Accept-Language", "en-US,en; q=0.9");
|
headers.put("Accept-Language", "en-US,en; q=0.9");
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,16 @@ public interface LiveClient {
|
|||||||
/**
|
/**
|
||||||
* Use to manually invoke event
|
* Use to manually invoke event
|
||||||
*/
|
*/
|
||||||
void publishEvent(TikTokEvent event);
|
void publishEvent(TikTokEvent event);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param webcastMessageName name of TikTok protocol-buffer message
|
||||||
|
* @param payloadBase64 protocol-buffer message bytes payload
|
||||||
|
*/
|
||||||
|
void publishMessage(String webcastMessageName, String payloadBase64);
|
||||||
|
|
||||||
|
void publishMessage(String webcastMessageName, byte[] payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get information about gifts
|
* Get information about gifts
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public interface LiveRoomInfo
|
|||||||
String getRoomId();
|
String getRoomId();
|
||||||
String getHostName();
|
String getHostName();
|
||||||
String getTitle();
|
String getTitle();
|
||||||
User getHostUser();
|
User getHost();
|
||||||
List<RankingUser> getUsersRanking();
|
List<RankingUser> getUsersRanking();
|
||||||
ConnectionState getConnectionState();
|
ConnectionState getConnectionState();
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,8 @@ message Text {
|
|||||||
|
|
||||||
// @Image
|
// @Image
|
||||||
message Image {
|
message Image {
|
||||||
repeated string urlList = 1;
|
repeated string url = 1;
|
||||||
|
string extras = 2;
|
||||||
bool isAnimated = 9;
|
bool isAnimated = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ enum LinkmicApplierSortSetting {
|
|||||||
LINKMIC_APPLIER_SORT_SETTING_BY_GIFT_SCORE = 1;
|
LINKMIC_APPLIER_SORT_SETTING_BY_GIFT_SCORE = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum LinkMicBattleStatus {
|
||||||
|
BATTLE_ARMY_UNKNOWN = 0;
|
||||||
|
ARMY_ONGOING = 1;
|
||||||
|
ARMY_FINISHED = 2;
|
||||||
|
BATTLE_ONGOING = 4;
|
||||||
|
BATTLE_FINISHED = 5;
|
||||||
|
}
|
||||||
|
|
||||||
enum HashtagNamespace {
|
enum HashtagNamespace {
|
||||||
GLOBAL = 0;
|
GLOBAL = 0;
|
||||||
GAMING = 1;
|
GAMING = 1;
|
||||||
|
|||||||
@@ -521,7 +521,7 @@ message WebcastLinkMicArmies {
|
|||||||
uint64 id2 = 4;
|
uint64 id2 = 4;
|
||||||
uint64 timeStamp1 = 5;
|
uint64 timeStamp1 = 5;
|
||||||
uint64 timeStamp2 = 6;
|
uint64 timeStamp2 = 6;
|
||||||
int32 battleStatus = 7; // SHOULD BE AN ENUM
|
LinkMicBattleStatus battleStatus = 7;
|
||||||
uint64 data1 = 8;
|
uint64 data1 = 8;
|
||||||
uint64 data2 = 9;
|
uint64 data2 = 9;
|
||||||
uint32 data3 = 10;
|
uint32 data3 = 10;
|
||||||
@@ -574,11 +574,26 @@ message WebcastLinkMicBattle {
|
|||||||
Common common = 1;
|
Common common = 1;
|
||||||
uint64 id = 2;
|
uint64 id = 2;
|
||||||
LinkMicBattleConfig battleConfig = 3;
|
LinkMicBattleConfig battleConfig = 3;
|
||||||
uint32 data2 = 4;
|
LinkMicBattleStatus battleStatus = 4;
|
||||||
repeated LinkMicBattleDetails details = 5;
|
repeated LinkMicBattleDetails details = 5;
|
||||||
repeated LinkMicBattleTeam teams1 = 9;
|
repeated LinkMicBattleTopViewers viewerTeam = 9;
|
||||||
repeated LinkMicBattleTeam teams2 = 10;
|
repeated LinkMicBattleHost hostTeam = 10;
|
||||||
repeated LinkMicBattleTeamData teamData = 13;
|
repeated LinkMicBattleTeamData teamData = 13;
|
||||||
|
uint64 unknownData16 = 16;
|
||||||
|
repeated Host2v2Data hostData2v2 = 17;
|
||||||
|
|
||||||
|
message Host2v2Data {
|
||||||
|
uint32 teamNumber = 1;
|
||||||
|
repeated HostData hostdata = 2;
|
||||||
|
uint32 unknownData3 = 3;
|
||||||
|
uint32 totalPoints = 4;
|
||||||
|
|
||||||
|
message HostData {
|
||||||
|
uint64 hostId = 1;
|
||||||
|
uint32 points = 2;
|
||||||
|
string hostIdStr = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message LinkMicBattleConfig {
|
message LinkMicBattleConfig {
|
||||||
uint64 id1 = 1;
|
uint64 id1 = 1;
|
||||||
@@ -586,29 +601,69 @@ message WebcastLinkMicBattle {
|
|||||||
uint32 data1 = 3;
|
uint32 data1 = 3;
|
||||||
uint64 id2 = 4;
|
uint64 id2 = 4;
|
||||||
uint32 data2 = 5;
|
uint32 data2 = 5;
|
||||||
|
uint32 data3 = 6;
|
||||||
|
uint32 data4 = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LinkMicBattleTeamData {
|
||||||
|
uint64 teamId = 1;
|
||||||
|
LinkMicBattleData data = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LinkMicBattleData {
|
message LinkMicBattleData {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
uint32 data1 = 2;
|
uint32 data1 = 2;
|
||||||
uint32 data2 = 3;
|
uint32 winStreak = 3;
|
||||||
uint32 data3 = 5;
|
uint32 data3 = 5;
|
||||||
string url = 6;
|
string url = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LinkMicBattleDetails {
|
message LinkMicBattleDetails {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
LinkMicBattleData details = 2;
|
LinkMicBattleDetailsSummary summary = 2;
|
||||||
|
|
||||||
|
message LinkMicBattleDetailsSummary {
|
||||||
|
uint64 id = 1;
|
||||||
|
uint32 unknownData2 = 2;
|
||||||
|
uint32 points = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message LinkMicBattleTeam {
|
message LinkMicBattleTopViewers {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
repeated User users = 2;
|
repeated TopViewerGroup viewerGroup = 2;
|
||||||
|
|
||||||
|
message TopViewerGroup {
|
||||||
|
repeated TopViewer viewer = 1;
|
||||||
|
uint32 points = 2;
|
||||||
|
string hostIdOrTeamNum = 3; // 1v1 Battle = HostId | 2v2 Battle = Team # - 1 & 2
|
||||||
|
|
||||||
|
message TopViewer {
|
||||||
|
uint64 id = 1;
|
||||||
|
uint32 points = 2;
|
||||||
|
string profileId = 3;
|
||||||
|
repeated Image images = 4;
|
||||||
|
string stringId = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message LinkMicBattleTeamData {
|
message LinkMicBattleHost {
|
||||||
uint64 teamId = 1;
|
uint64 id = 1;
|
||||||
LinkMicBattleData data = 2;
|
repeated HostGroup hostGroup = 2;
|
||||||
|
|
||||||
|
message HostGroup {
|
||||||
|
repeated Host host = 1;
|
||||||
|
uint32 points = 2;
|
||||||
|
string hostId = 3;
|
||||||
|
|
||||||
|
message Host {
|
||||||
|
uint64 id = 1;
|
||||||
|
string profileId = 2;
|
||||||
|
repeated Image images = 3;
|
||||||
|
string name = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,6 +847,4 @@ message RoomVerifyMessage {
|
|||||||
string content = 3;
|
string content = 3;
|
||||||
int64 noticeType = 4;
|
int64 noticeType = 4;
|
||||||
bool closeRoom = 5;
|
bool closeRoom = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
<artifactId>TikTokLiveJava</artifactId>
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<version>1.3.0-Release</version>
|
<version>1.6.0-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
|||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class TikTokLive {
|
public class TikTokLive {
|
||||||
@@ -92,7 +91,6 @@ public class TikTokLive {
|
|||||||
return new TikTokLiveHttpClient();
|
return new TikTokLiveHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//I don't like it, but it is reasonable for now
|
//I don't like it, but it is reasonable for now
|
||||||
private static GiftsManager giftsManager;
|
private static GiftsManager giftsManager;
|
||||||
|
|
||||||
@@ -102,18 +100,11 @@ public class TikTokLive {
|
|||||||
* @return GiftsManager
|
* @return GiftsManager
|
||||||
*/
|
*/
|
||||||
public static GiftsManager gifts() {
|
public static GiftsManager gifts() {
|
||||||
if (giftsManager != null) {
|
if (giftsManager == null) {
|
||||||
return giftsManager;
|
synchronized (GiftsManager.class) {
|
||||||
}
|
giftsManager = new TikTokGiftsManager(requests().fetchGiftsData().getGifts());
|
||||||
synchronized (GiftsManager.class)
|
|
||||||
{
|
|
||||||
if (giftsManager == null)
|
|
||||||
{
|
|
||||||
return new TikTokGiftsManager(requests().fetchGiftsData().getGifts());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return giftsManager;
|
return giftsManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -22,48 +22,49 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
import com.google.protobuf.ByteString;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
import io.github.jwdeveloper.tiktok.data.events.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.control.*;
|
import io.github.jwdeveloper.tiktok.data.events.control.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.http.TikTokRoomDataResponseEvent;
|
import io.github.jwdeveloper.tiktok.data.events.http.TikTokRoomDataResponseEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomInfoEvent;
|
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomInfoEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
import io.github.jwdeveloper.tiktok.data.requests.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveData;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.*;
|
|
||||||
import io.github.jwdeveloper.tiktok.listener.ListenersManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
|
||||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
||||||
|
import io.github.jwdeveloper.tiktok.exceptions.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
||||||
|
import io.github.jwdeveloper.tiktok.listener.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.live.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
|
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||||
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class TikTokLiveClient implements LiveClient {
|
public class TikTokLiveClient implements LiveClient {
|
||||||
private final TikTokRoomInfo liveRoomInfo;
|
private final TikTokRoomInfo liveRoomInfo;
|
||||||
private final TikTokLiveHttpClient httpClient;
|
private final LiveHttpClient httpClient;
|
||||||
private final SocketClient webSocketClient;
|
private final SocketClient webSocketClient;
|
||||||
private final TikTokLiveEventHandler tikTokEventHandler;
|
private final TikTokLiveEventHandler tikTokEventHandler;
|
||||||
private final LiveClientSettings clientSettings;
|
private final LiveClientSettings clientSettings;
|
||||||
private final TikTokListenersManager listenersManager;
|
private final TikTokListenersManager listenersManager;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final GiftsManager giftsManager;
|
private final GiftsManager giftsManager;
|
||||||
|
private final TikTokLiveMessageHandler messageHandler;
|
||||||
|
|
||||||
public TikTokLiveClient(GiftsManager giftsManager,
|
public TikTokLiveClient(
|
||||||
TikTokRoomInfo tikTokLiveMeta,
|
TikTokLiveMessageHandler messageHandler,
|
||||||
TikTokLiveHttpClient tiktokHttpClient,
|
GiftsManager giftsManager,
|
||||||
SocketClient webSocketClient,
|
TikTokRoomInfo tikTokLiveMeta,
|
||||||
TikTokLiveEventHandler tikTokEventHandler,
|
LiveHttpClient tiktokHttpClient,
|
||||||
LiveClientSettings clientSettings,
|
SocketClient webSocketClient,
|
||||||
TikTokListenersManager listenersManager,
|
TikTokLiveEventHandler tikTokEventHandler,
|
||||||
Logger logger) {
|
LiveClientSettings clientSettings,
|
||||||
|
TikTokListenersManager listenersManager,
|
||||||
|
Logger logger) {
|
||||||
|
this.messageHandler = messageHandler;
|
||||||
this.giftsManager = giftsManager;
|
this.giftsManager = giftsManager;
|
||||||
this.liveRoomInfo = tikTokLiveMeta;
|
this.liveRoomInfo = tikTokLiveMeta;
|
||||||
this.httpClient = tiktokHttpClient;
|
this.httpClient = tiktokHttpClient;
|
||||||
@@ -136,7 +137,7 @@ public class TikTokLiveClient implements LiveClient {
|
|||||||
var liveDataRequest = new LiveData.Request(userData.getRoomId());
|
var liveDataRequest = new LiveData.Request(userData.getRoomId());
|
||||||
var liveData = httpClient.fetchLiveData(liveDataRequest);
|
var liveData = httpClient.fetchLiveData(liveDataRequest);
|
||||||
|
|
||||||
if (liveData.isAgeRestricted())
|
if (liveData.isAgeRestricted() && clientSettings.isThrowOnAgeRestriction())
|
||||||
throw new TikTokLiveException("Livestream for " + liveRoomInfo.getHostName() + " is 18+ or age restricted!");
|
throw new TikTokLiveException("Livestream for " + liveRoomInfo.getHostName() + " is 18+ or age restricted!");
|
||||||
|
|
||||||
if (liveData.getLiveStatus() == LiveData.LiveStatus.HostNotFound)
|
if (liveData.getLiveStatus() == LiveData.LiveStatus.HostNotFound)
|
||||||
@@ -183,6 +184,20 @@ public class TikTokLiveClient implements LiveClient {
|
|||||||
tikTokEventHandler.publish(this, event);
|
tikTokEventHandler.publish(this, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishMessage(String webcastMessageName, String payloadBase64) {
|
||||||
|
this.publishMessage(webcastMessageName, Base64.getDecoder().decode(payloadBase64));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void publishMessage(String webcastMessageName, byte[] payload) {
|
||||||
|
|
||||||
|
var builder = WebcastResponse.Message.newBuilder();
|
||||||
|
builder.setMethod(webcastMessageName);
|
||||||
|
builder.setPayload(ByteString.copyFrom(payload));
|
||||||
|
var message = builder.build();
|
||||||
|
messageHandler.handleSingleMessage(this, message);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GiftsManager getGiftManager() {
|
public GiftsManager getGiftManager() {
|
||||||
return giftsManager;
|
return giftsManager;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
|
|||||||
import io.github.jwdeveloper.tiktok.mappers.handlers.*;
|
import io.github.jwdeveloper.tiktok.mappers.handlers.*;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||||
|
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketOfflineClient;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@@ -54,7 +55,7 @@ import java.util.logging.Logger;
|
|||||||
public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||||
|
|
||||||
protected final LiveClientSettings clientSettings;
|
protected final LiveClientSettings clientSettings;
|
||||||
protected final TikTokLiveEventHandler tikTokEventHandler;
|
protected final TikTokLiveEventHandler eventHandler;
|
||||||
protected final List<TikTokEventListener> listeners;
|
protected final List<TikTokEventListener> listeners;
|
||||||
protected Consumer<TikTokMapper> onCustomMappings;
|
protected Consumer<TikTokMapper> onCustomMappings;
|
||||||
protected Logger logger;
|
protected Logger logger;
|
||||||
@@ -63,7 +64,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
public TikTokLiveClientBuilder(String userName) {
|
public TikTokLiveClientBuilder(String userName) {
|
||||||
this.clientSettings = LiveClientSettings.createDefault();
|
this.clientSettings = LiveClientSettings.createDefault();
|
||||||
this.clientSettings.setHostName(userName);
|
this.clientSettings.setHostName(userName);
|
||||||
this.tikTokEventHandler = new TikTokLiveEventHandler();
|
this.eventHandler = new TikTokLiveEventHandler();
|
||||||
this.listeners = new ArrayList<>();
|
this.listeners = new ArrayList<>();
|
||||||
this.onCustomMappings = (e) -> {
|
this.onCustomMappings = (e) -> {
|
||||||
};
|
};
|
||||||
@@ -95,6 +96,9 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
if (clientSettings.getHostName().startsWith("@"))
|
if (clientSettings.getHostName().startsWith("@"))
|
||||||
clientSettings.setHostName(clientSettings.getHostName().substring(1));
|
clientSettings.setHostName(clientSettings.getHostName().substring(1));
|
||||||
|
|
||||||
|
if (clientSettings.getPingInterval() < 250)
|
||||||
|
throw new TikTokLiveException("Minimum allowed ping interval is 250 millseconds");
|
||||||
|
|
||||||
var httpSettings = clientSettings.getHttpSettings();
|
var httpSettings = clientSettings.getHttpSettings();
|
||||||
httpSettings.getParams().put("app_language", clientSettings.getClientLanguage());
|
httpSettings.getParams().put("app_language", clientSettings.getClientLanguage());
|
||||||
httpSettings.getParams().put("webcast_language", clientSettings.getClientLanguage());
|
httpSettings.getParams().put("webcast_language", clientSettings.getClientLanguage());
|
||||||
@@ -109,27 +113,31 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
var tiktokRoomInfo = new TikTokRoomInfo();
|
var tiktokRoomInfo = new TikTokRoomInfo();
|
||||||
tiktokRoomInfo.setHostName(clientSettings.getHostName());
|
tiktokRoomInfo.setHostName(clientSettings.getHostName());
|
||||||
|
|
||||||
var listenerManager = new TikTokListenersManager(listeners, tikTokEventHandler);
|
var listenerManager = new TikTokListenersManager(listeners, eventHandler);
|
||||||
|
|
||||||
var httpClientFactory = new HttpClientFactory(clientSettings);
|
var httpClientFactory = new HttpClientFactory(clientSettings);
|
||||||
var tikTokLiveHttpClient = new TikTokLiveHttpClient(httpClientFactory, clientSettings);
|
|
||||||
|
|
||||||
|
var liveHttpClient = clientSettings.isOffline() ?
|
||||||
|
new TikTokLiveHttpOfflineClient() :
|
||||||
|
new TikTokLiveHttpClient(httpClientFactory, clientSettings);
|
||||||
|
|
||||||
var eventsMapper = createMapper(giftsManager, tiktokRoomInfo);
|
var eventsMapper = createMapper(giftsManager, tiktokRoomInfo);
|
||||||
var messageHandler = new TikTokLiveMessageHandler(tikTokEventHandler, eventsMapper);
|
var messageHandler = new TikTokLiveMessageHandler(eventHandler, eventsMapper);
|
||||||
|
|
||||||
|
var webSocketClient = clientSettings.isOffline() ?
|
||||||
var webSocketClient = new TikTokWebSocketClient(
|
new TikTokWebSocketOfflineClient(eventHandler) :
|
||||||
clientSettings,
|
new TikTokWebSocketClient(
|
||||||
messageHandler,
|
clientSettings,
|
||||||
tikTokEventHandler);
|
messageHandler,
|
||||||
|
eventHandler);
|
||||||
|
|
||||||
return new TikTokLiveClient(
|
return new TikTokLiveClient(
|
||||||
|
messageHandler,
|
||||||
giftsManager,
|
giftsManager,
|
||||||
tiktokRoomInfo,
|
tiktokRoomInfo,
|
||||||
tikTokLiveHttpClient,
|
liveHttpClient,
|
||||||
webSocketClient,
|
webSocketClient,
|
||||||
tikTokEventHandler,
|
eventHandler,
|
||||||
clientSettings,
|
clientSettings,
|
||||||
listenerManager,
|
listenerManager,
|
||||||
logger);
|
logger);
|
||||||
@@ -199,9 +207,15 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
|
|
||||||
|
|
||||||
//LinkMic events
|
//LinkMic events
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicBattle.class, TikTokLinkMicBattleEvent.class);
|
mapper.forMessage(WebcastLinkMicBattle.class, (inputBytes, messageName, mapperHelper) -> {
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicArmies.class, TikTokLinkMicArmiesEvent.class);
|
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicBattle.class);
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
return MappingResult.of(message, new TikTokLinkMicBattleEvent(message));
|
||||||
|
});
|
||||||
|
mapper.forMessage(WebcastLinkMicArmies.class, (inputBytes, messageName, mapperHelper) -> {
|
||||||
|
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicArmies.class);
|
||||||
|
return MappingResult.of(message, new TikTokLinkMicArmiesEvent(message));
|
||||||
|
});
|
||||||
|
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
||||||
|
|
||||||
//Rank events
|
//Rank events
|
||||||
@@ -235,255 +249,255 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onUnhandledSocial(EventConsumer<TikTokUnhandledSocialEvent> event) {
|
public TikTokLiveClientBuilder onUnhandledSocial(EventConsumer<TikTokUnhandledSocialEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokUnhandledSocialEvent.class, event);
|
eventHandler.subscribe(TikTokUnhandledSocialEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveClientBuilder onChest(EventConsumer<TikTokChestEvent> event) {
|
public LiveClientBuilder onChest(EventConsumer<TikTokChestEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokChestEvent.class, event);
|
eventHandler.subscribe(TikTokChestEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLinkMicFanTicket(EventConsumer<TikTokLinkMicFanTicketEvent> event) {
|
public TikTokLiveClientBuilder onLinkMicFanTicket(EventConsumer<TikTokLinkMicFanTicketEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkMicFanTicketEvent.class, event);
|
eventHandler.subscribe(TikTokLinkMicFanTicketEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onEnvelope(EventConsumer<TikTokEnvelopeEvent> event) {
|
public TikTokLiveClientBuilder onEnvelope(EventConsumer<TikTokEnvelopeEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokEnvelopeEvent.class, event);
|
eventHandler.subscribe(TikTokEnvelopeEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onShop(EventConsumer<TikTokShopEvent> event) {
|
public TikTokLiveClientBuilder onShop(EventConsumer<TikTokShopEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokShopEvent.class, event);
|
eventHandler.subscribe(TikTokShopEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onDetect(EventConsumer<TikTokDetectEvent> event) {
|
public TikTokLiveClientBuilder onDetect(EventConsumer<TikTokDetectEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokDetectEvent.class, event);
|
eventHandler.subscribe(TikTokDetectEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLinkLayer(EventConsumer<TikTokLinkLayerEvent> event) {
|
public TikTokLiveClientBuilder onLinkLayer(EventConsumer<TikTokLinkLayerEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkLayerEvent.class, event);
|
eventHandler.subscribe(TikTokLinkLayerEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onConnected(EventConsumer<TikTokConnectedEvent> event) {
|
public TikTokLiveClientBuilder onConnected(EventConsumer<TikTokConnectedEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokConnectedEvent.class, event);
|
eventHandler.subscribe(TikTokConnectedEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onPreConnection(EventConsumer<TikTokPreConnectionEvent> event) {
|
public TikTokLiveClientBuilder onPreConnection(EventConsumer<TikTokPreConnectionEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokPreConnectionEvent.class, event);
|
eventHandler.subscribe(TikTokPreConnectionEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onCaption(EventConsumer<TikTokCaptionEvent> event) {
|
public TikTokLiveClientBuilder onCaption(EventConsumer<TikTokCaptionEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokCaptionEvent.class, event);
|
eventHandler.subscribe(TikTokCaptionEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onQuestion(EventConsumer<TikTokQuestionEvent> event) {
|
public TikTokLiveClientBuilder onQuestion(EventConsumer<TikTokQuestionEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokQuestionEvent.class, event);
|
eventHandler.subscribe(TikTokQuestionEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onRoomPin(EventConsumer<TikTokRoomPinEvent> event) {
|
public TikTokLiveClientBuilder onRoomPin(EventConsumer<TikTokRoomPinEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokRoomPinEvent.class, event);
|
eventHandler.subscribe(TikTokRoomPinEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E extends TikTokEvent> LiveClientBuilder onEvent(Class<E> eventClass, EventConsumer<E> event) {
|
public <E extends TikTokEvent> LiveClientBuilder onEvent(Class<E> eventClass, EventConsumer<E> event) {
|
||||||
tikTokEventHandler.subscribe(eventClass, event);
|
eventHandler.subscribe(eventClass, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event) {
|
public TikTokLiveClientBuilder onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokRoomInfoEvent.class, event);
|
eventHandler.subscribe(TikTokRoomInfoEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLivePaused(EventConsumer<TikTokLivePausedEvent> event) {
|
public TikTokLiveClientBuilder onLivePaused(EventConsumer<TikTokLivePausedEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLivePausedEvent.class, event);
|
eventHandler.subscribe(TikTokLivePausedEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event) {
|
public TikTokLiveClientBuilder onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLiveUnpausedEvent.class, event);
|
eventHandler.subscribe(TikTokLiveUnpausedEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLike(EventConsumer<TikTokLikeEvent> event) {
|
public TikTokLiveClientBuilder onLike(EventConsumer<TikTokLikeEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLikeEvent.class, event);
|
eventHandler.subscribe(TikTokLikeEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLink(EventConsumer<TikTokLinkEvent> event) {
|
public TikTokLiveClientBuilder onLink(EventConsumer<TikTokLinkEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkEvent.class, event);
|
eventHandler.subscribe(TikTokLinkEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onBarrage(EventConsumer<TikTokBarrageEvent> event) {
|
public TikTokLiveClientBuilder onBarrage(EventConsumer<TikTokBarrageEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokBarrageEvent.class, event);
|
eventHandler.subscribe(TikTokBarrageEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onGift(EventConsumer<TikTokGiftEvent> event) {
|
public TikTokLiveClientBuilder onGift(EventConsumer<TikTokGiftEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokGiftEvent.class, event);
|
eventHandler.subscribe(TikTokGiftEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboEvent> event) {
|
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokGiftComboEvent.class, event);
|
eventHandler.subscribe(TikTokGiftComboEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLinkMicArmies(EventConsumer<TikTokLinkMicArmiesEvent> event) {
|
public TikTokLiveClientBuilder onLinkMicArmies(EventConsumer<TikTokLinkMicArmiesEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkMicArmiesEvent.class, event);
|
eventHandler.subscribe(TikTokLinkMicArmiesEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onEmote(EventConsumer<TikTokEmoteEvent> event) {
|
public TikTokLiveClientBuilder onEmote(EventConsumer<TikTokEmoteEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokEmoteEvent.class, event);
|
eventHandler.subscribe(TikTokEmoteEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onUnauthorizedMember(EventConsumer<TikTokUnauthorizedMemberEvent> event) {
|
public TikTokLiveClientBuilder onUnauthorizedMember(EventConsumer<TikTokUnauthorizedMemberEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokUnauthorizedMemberEvent.class, event);
|
eventHandler.subscribe(TikTokUnauthorizedMemberEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onInRoomBanner(EventConsumer<TikTokInRoomBannerEvent> event) {
|
public TikTokLiveClientBuilder onInRoomBanner(EventConsumer<TikTokInRoomBannerEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokInRoomBannerEvent.class, event);
|
eventHandler.subscribe(TikTokInRoomBannerEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLinkMicMethod(EventConsumer<TikTokLinkMicMethodEvent> event) {
|
public TikTokLiveClientBuilder onLinkMicMethod(EventConsumer<TikTokLinkMicMethodEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkMicMethodEvent.class, event);
|
eventHandler.subscribe(TikTokLinkMicMethodEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onSubscribe(EventConsumer<TikTokSubscribeEvent> event) {
|
public TikTokLiveClientBuilder onSubscribe(EventConsumer<TikTokSubscribeEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokSubscribeEvent.class, event);
|
eventHandler.subscribe(TikTokSubscribeEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onPoll(EventConsumer<TikTokPollEvent> event) {
|
public TikTokLiveClientBuilder onPoll(EventConsumer<TikTokPollEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokPollEvent.class, event);
|
eventHandler.subscribe(TikTokPollEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onFollow(EventConsumer<TikTokFollowEvent> event) {
|
public TikTokLiveClientBuilder onFollow(EventConsumer<TikTokFollowEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokFollowEvent.class, event);
|
eventHandler.subscribe(TikTokFollowEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onComment(EventConsumer<TikTokCommentEvent> event) {
|
public TikTokLiveClientBuilder onComment(EventConsumer<TikTokCommentEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
|
eventHandler.subscribe(TikTokCommentEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LiveClientBuilder onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action) {
|
public LiveClientBuilder onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action) {
|
||||||
tikTokEventHandler.subscribe(TikTokHttpResponseEvent.class, action);
|
eventHandler.subscribe(TikTokHttpResponseEvent.class, action);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onGoalUpdate(EventConsumer<TikTokGoalUpdateEvent> event) {
|
public TikTokLiveClientBuilder onGoalUpdate(EventConsumer<TikTokGoalUpdateEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
|
eventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onRankUpdate(EventConsumer<TikTokRankUpdateEvent> event) {
|
public TikTokLiveClientBuilder onRankUpdate(EventConsumer<TikTokRankUpdateEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class, event);
|
eventHandler.subscribe(TikTokRankUpdateEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onIMDelete(EventConsumer<TikTokIMDeleteEvent> event) {
|
public TikTokLiveClientBuilder onIMDelete(EventConsumer<TikTokIMDeleteEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokIMDeleteEvent.class, event);
|
eventHandler.subscribe(TikTokIMDeleteEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLiveEnded(EventConsumer<TikTokLiveEndedEvent> event) {
|
public TikTokLiveClientBuilder onLiveEnded(EventConsumer<TikTokLiveEndedEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLiveEndedEvent.class, event);
|
eventHandler.subscribe(TikTokLiveEndedEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onError(EventConsumer<TikTokErrorEvent> event) {
|
public TikTokLiveClientBuilder onError(EventConsumer<TikTokErrorEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokErrorEvent.class, event);
|
eventHandler.subscribe(TikTokErrorEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onJoin(EventConsumer<TikTokJoinEvent> event) {
|
public TikTokLiveClientBuilder onJoin(EventConsumer<TikTokJoinEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokJoinEvent.class, event);
|
eventHandler.subscribe(TikTokJoinEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onRankText(EventConsumer<TikTokRankTextEvent> event) {
|
public TikTokLiveClientBuilder onRankText(EventConsumer<TikTokRankTextEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokRankTextEvent.class, event);
|
eventHandler.subscribe(TikTokRankTextEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onShare(EventConsumer<TikTokShareEvent> event) {
|
public TikTokLiveClientBuilder onShare(EventConsumer<TikTokShareEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokShareEvent.class, event);
|
eventHandler.subscribe(TikTokShareEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onUnhandledMember(EventConsumer<TikTokUnhandledMemberEvent> event) {
|
public TikTokLiveClientBuilder onUnhandledMember(EventConsumer<TikTokUnhandledMemberEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokUnhandledMemberEvent.class, event);
|
eventHandler.subscribe(TikTokUnhandledMemberEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onSubNotify(EventConsumer<TikTokSubNotifyEvent> event) {
|
public TikTokLiveClientBuilder onSubNotify(EventConsumer<TikTokSubNotifyEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokSubNotifyEvent.class, event);
|
eventHandler.subscribe(TikTokSubNotifyEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onLinkMicBattle(EventConsumer<TikTokLinkMicBattleEvent> event) {
|
public TikTokLiveClientBuilder onLinkMicBattle(EventConsumer<TikTokLinkMicBattleEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokLinkMicBattleEvent.class, event);
|
eventHandler.subscribe(TikTokLinkMicBattleEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onDisconnected(EventConsumer<TikTokDisconnectedEvent> event) {
|
public TikTokLiveClientBuilder onDisconnected(EventConsumer<TikTokDisconnectedEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokDisconnectedEvent.class, event);
|
eventHandler.subscribe(TikTokDisconnectedEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onUnhandledControl(EventConsumer<TikTokUnhandledControlEvent> event) {
|
public TikTokLiveClientBuilder onUnhandledControl(EventConsumer<TikTokUnhandledControlEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokUnhandledControlEvent.class, event);
|
eventHandler.subscribe(TikTokUnhandledControlEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveClientBuilder onEvent(EventConsumer<TikTokEvent> event) {
|
public TikTokLiveClientBuilder onEvent(EventConsumer<TikTokEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokEvent.class, event);
|
eventHandler.subscribe(TikTokEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> event) {
|
public TikTokLiveClientBuilder onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokWebsocketResponseEvent.class, event);
|
eventHandler.subscribe(TikTokWebsocketResponseEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> event) {
|
public TikTokLiveClientBuilder onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokWebsocketMessageEvent.class, event);
|
eventHandler.subscribe(TikTokWebsocketMessageEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> event) {
|
public TikTokLiveClientBuilder onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokWebsocketUnhandledMessageEvent.class, event);
|
eventHandler.subscribe(TikTokWebsocketUnhandledMessageEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokLiveClientBuilder onReconnecting(EventConsumer<TikTokReconnectingEvent> event) {
|
public TikTokLiveClientBuilder onReconnecting(EventConsumer<TikTokReconnectingEvent> event) {
|
||||||
tikTokEventHandler.subscribe(TikTokReconnectingEvent.class, event);
|
eventHandler.subscribe(TikTokReconnectingEvent.class, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
.toJsonResponse();
|
.toJsonResponse();
|
||||||
|
|
||||||
if (result.isFailure())
|
if (result.isFailure())
|
||||||
throw new TikTokLiveRequestException("Unable to fetch gifts information's"+result.toStack());
|
throw new TikTokLiveRequestException("Unable to fetch gifts information's - "+result);
|
||||||
|
|
||||||
var json = result.getContent();
|
var json = result.getContent();
|
||||||
return giftsDataMapper.map(json);
|
return giftsDataMapper.map(json);
|
||||||
@@ -111,10 +111,10 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
.toJsonResponse();
|
.toJsonResponse();
|
||||||
|
|
||||||
if (result.isFailure())
|
if (result.isFailure())
|
||||||
throw new TikTokLiveRequestException("Unable to get information's about user"+result.toStack());
|
throw new TikTokLiveRequestException("Unable to get information's about user - "+result);
|
||||||
|
|
||||||
var json = result.getContent();
|
var json = result.getContent();
|
||||||
return liveUserDataMapper.map(json);
|
return liveUserDataMapper.map(json, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -138,7 +138,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
.toJsonResponse();
|
.toJsonResponse();
|
||||||
|
|
||||||
if (result.isFailure())
|
if (result.isFailure())
|
||||||
throw new TikTokLiveRequestException("Unable to get info about live room"+result.toStack());
|
throw new TikTokLiveRequestException("Unable to get info about live room - "+result);
|
||||||
|
|
||||||
var json = result.getContent();
|
var json = result.getContent();
|
||||||
return liveDataMapper.map(json);
|
return liveDataMapper.map(json);
|
||||||
@@ -153,7 +153,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
var resultHeader = ActionResult.of(credentialsResponse.headers().firstValue("x-set-tt-cookie"));
|
var resultHeader = ActionResult.of(credentialsResponse.headers().firstValue("x-set-tt-cookie"));
|
||||||
if (resultHeader.isFailure()) {
|
if (resultHeader.isFailure()) {
|
||||||
logger.warning("SignServer Headers: "+request.getRoomId()+" - "+credentialsResponse.headers().map());
|
logger.warning("SignServer Headers: "+request.getRoomId()+" - "+credentialsResponse.headers().map());
|
||||||
throw new TikTokSignServerException("Sign server did not return the x-set-tt-cookie header"+result.toStack());
|
throw new TikTokSignServerException("Sign server did not return the x-set-tt-cookie header - "+result);
|
||||||
}
|
}
|
||||||
var websocketCookie = resultHeader.getContent();
|
var websocketCookie = resultHeader.getContent();
|
||||||
var webcastResponse = WebcastResponse.parseFrom(credentialsResponse.body());
|
var webcastResponse = WebcastResponse.parseFrom(credentialsResponse.body());
|
||||||
@@ -169,7 +169,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
|
|
||||||
return new LiveConnectionData.Response(websocketCookie, webSocketUrl, webcastResponse);
|
return new LiveConnectionData.Response(websocketCookie, webSocketUrl, webcastResponse);
|
||||||
} catch (InvalidProtocolBufferException e) {
|
} catch (InvalidProtocolBufferException e) {
|
||||||
throw new TikTokSignServerException("Unable to parse websocket credentials response to WebcastResponse"+result.toStack());
|
throw new TikTokSignServerException("Unable to parse websocket credentials response to WebcastResponse - "+result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
var result = builder.build().toResponse();
|
var result = builder.build().toResponse();
|
||||||
|
|
||||||
if (result.isFailure())
|
if (result.isFailure())
|
||||||
throw new TikTokSignServerException("Unable to get websocket connection credentials"+result.toStack());
|
throw new TikTokSignServerException("Unable to get websocket connection credentials - "+result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.requests.GiftsData;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.requests.LiveData;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
||||||
|
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TikTokLiveHttpOfflineClient implements LiveHttpClient {
|
||||||
|
@Override
|
||||||
|
public GiftsData.Response fetchGiftsData() {
|
||||||
|
return new GiftsData.Response("", List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) {
|
||||||
|
return new LiveUserData.Response("", LiveUserData.UserStatus.Live, "offline_room_id", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LiveData.Response fetchLiveData(LiveData.Request request) {
|
||||||
|
return new LiveData.Response("",
|
||||||
|
LiveData.LiveStatus.HostOnline,
|
||||||
|
"offline live",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
new User(0L, "offline user", new Picture("")),
|
||||||
|
LiveData.LiveType.SOLO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request) {
|
||||||
|
return new LiveConnectionData.Response("",
|
||||||
|
URI.create("https://example.live"),
|
||||||
|
WebcastResponse.newBuilder().build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,11 +61,6 @@ public class TikTokRoomInfo implements LiveRoomInfo {
|
|||||||
return connectionState == state;
|
return connectionState == state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public User getHostUser() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateRanking(List<RankingUser> rankingUsers) {
|
public void updateRanking(List<RankingUser> rankingUsers) {
|
||||||
usersRanking.clear();
|
usersRanking.clear();
|
||||||
usersRanking.addAll(rankingUsers);
|
usersRanking.addAll(rankingUsers);
|
||||||
|
|||||||
@@ -1,16 +1,27 @@
|
|||||||
package io.github.jwdeveloper.tiktok.common;
|
package io.github.jwdeveloper.tiktok.common;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.http.mappers.*;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.net.http.*;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ActionResult<T> {
|
public class ActionResult<T> {
|
||||||
|
|
||||||
|
private static final Gson gson = new Gson().newBuilder().disableHtmlEscaping()
|
||||||
|
.registerTypeHierarchyAdapter(HttpResponse.class, new HttpResponseJsonMapper())
|
||||||
|
.registerTypeHierarchyAdapter(HttpRequest.class, new HttpRequestJsonMapper())
|
||||||
|
.setPrettyPrinting().create();
|
||||||
|
|
||||||
private boolean success = true;
|
private boolean success = true;
|
||||||
private T content;
|
private T content;
|
||||||
private String message;
|
private String message;
|
||||||
|
@Accessors(chain = true, fluent = true)
|
||||||
|
private ActionResult<?> previous;
|
||||||
|
|
||||||
protected ActionResult(T object) {
|
protected ActionResult(T object) {
|
||||||
this.content = object;
|
this.content = object;
|
||||||
@@ -41,8 +52,9 @@ public class ActionResult<T> {
|
|||||||
public boolean hasMessage() {
|
public boolean hasMessage() {
|
||||||
return message != null;
|
return message != null;
|
||||||
}
|
}
|
||||||
public String toStack() {
|
|
||||||
return hasMessage() ? " - "+message : "";
|
public boolean hasPrevious() {
|
||||||
|
return previous != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasContent() {
|
public boolean hasContent() {
|
||||||
@@ -84,4 +96,18 @@ public class ActionResult<T> {
|
|||||||
public static <T> ActionResult<T> failure() {
|
public static <T> ActionResult<T> failure() {
|
||||||
return failure(null);
|
return failure(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonObject toJson() {
|
||||||
|
JsonObject map = new JsonObject();
|
||||||
|
map.addProperty("success", success);
|
||||||
|
map.add("content", gson.toJsonTree(content));
|
||||||
|
map.addProperty("message", message);
|
||||||
|
map.add("previous", hasPrevious() ? previous.toJson() : null);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ActionResult: "+gson.toJson(toJson());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package io.github.jwdeveloper.tiktok.common;
|
package io.github.jwdeveloper.tiktok.common;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -7,6 +10,8 @@ public class ActionResultBuilder<T>
|
|||||||
{
|
{
|
||||||
private final T content;
|
private final T content;
|
||||||
private String message;
|
private String message;
|
||||||
|
@Setter @Accessors(fluent = true, chain = true)
|
||||||
|
private ActionResult<?> previous;
|
||||||
|
|
||||||
public ActionResultBuilder(T content) {
|
public ActionResultBuilder(T content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
@@ -18,10 +23,10 @@ public class ActionResultBuilder<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult<T> success() {
|
public ActionResult<T> success() {
|
||||||
return ActionResult.success(content, message);
|
return ActionResult.success(content, message).previous(previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult<T> failure() {
|
public ActionResult<T> failure() {
|
||||||
return ActionResult.success(content, message);
|
return ActionResult.success(content, message).previous(previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
package io.github.jwdeveloper.tiktok.gifts;
|
package io.github.jwdeveloper.tiktok.gifts;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -32,11 +28,7 @@ public class TikTokGiftsManager implements GiftsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Gift getById(int giftId) {
|
public Gift getById(int giftId) {
|
||||||
if (!giftsByIdIndex.containsKey(giftId)) {
|
return giftsByIdIndex.getOrDefault(giftId, Gift.UNDEFINED);
|
||||||
return Gift.UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return giftsByIdIndex.get(giftId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gift getByFilter(Predicate<Gift> filter) {
|
public Gift getByFilter(Predicate<Gift> filter) {
|
||||||
@@ -44,7 +36,7 @@ public class TikTokGiftsManager implements GiftsManager {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(filter)
|
.filter(filter)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseGet(() -> Gift.UNDEFINED);
|
.orElse(Gift.UNDEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,4 +54,4 @@ public class TikTokGiftsManager implements GiftsManager {
|
|||||||
public Map<Integer, Gift> toMap() {
|
public Map<Integer, Gift> toMap() {
|
||||||
return Collections.unmodifiableMap(giftsByIdIndex);
|
return Collections.unmodifiableMap(giftsByIdIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.http.mappers;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
|
||||||
|
public class HttpRequestJsonMapper implements JsonSerializer<HttpRequest>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(HttpRequest src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject object = new JsonObject();
|
||||||
|
object.addProperty("method", src.method());
|
||||||
|
object.add("timeout", context.serialize(src.timeout().toString()));
|
||||||
|
object.addProperty("expectContinue", src.expectContinue());
|
||||||
|
object.add("uri", context.serialize(src.uri()));
|
||||||
|
object.add("version", context.serialize(src.version().toString()));
|
||||||
|
object.add("headers", context.serialize(src.headers().map()));
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.http.mappers;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
|
||||||
|
public class HttpResponseJsonMapper implements JsonSerializer<HttpResponse>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(HttpResponse src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject object = new JsonObject();
|
||||||
|
object.addProperty("statusCode", src.statusCode());
|
||||||
|
object.add("request", context.serialize(src.request()));
|
||||||
|
object.add("headers", context.serialize(src.headers().map()));
|
||||||
|
object.add("body", context.serialize(src.body()));
|
||||||
|
object.add("uri", context.serialize(src.uri().toString()));
|
||||||
|
object.add("version", context.serialize(src.version().toString()));
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,8 +65,7 @@ public class LiveDataMapper {
|
|||||||
default -> LiveData.LiveStatus.HostNotFound;
|
default -> LiveData.LiveStatus.HostNotFound;
|
||||||
};
|
};
|
||||||
response.setLiveStatus(statusValue);
|
response.setLiveStatus(statusValue);
|
||||||
} else if (data.has("prompts") && jsonObject.has("status_code") &&
|
} else if (data.has("prompts") && data.get("prompts").getAsString().isEmpty() && jsonObject.has("status_code")) {
|
||||||
data.get("prompts").getAsString().isEmpty() && jsonObject.get("status_code").isJsonPrimitive()) {
|
|
||||||
response.setAgeRestricted(jsonObject.get("status_code").getAsInt() == TikTokLiveHttpClient.TIKTOK_AGE_RESTRICTED_CODE);
|
response.setAgeRestricted(jsonObject.get("status_code").getAsInt() == TikTokLiveHttpClient.TIKTOK_AGE_RESTRICTED_CODE);
|
||||||
} else {
|
} else {
|
||||||
response.setLiveStatus(LiveData.LiveStatus.HostNotFound);
|
response.setLiveStatus(LiveData.LiveStatus.HostNotFound);
|
||||||
|
|||||||
@@ -22,45 +22,52 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok.http.mappers;
|
package io.github.jwdeveloper.tiktok.http.mappers;
|
||||||
|
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class LiveUserDataMapper
|
public class LiveUserDataMapper
|
||||||
{
|
{
|
||||||
public LiveUserData.Response map(String json) {
|
public LiveUserData.Response map(String json, Logger logger) {
|
||||||
var jsonObject = JsonParser.parseString(json).getAsJsonObject();
|
try {
|
||||||
|
var jsonObject = JsonParser.parseString(json).getAsJsonObject();
|
||||||
|
|
||||||
var message = jsonObject.get("message").getAsString();
|
var message = jsonObject.get("message").getAsString();
|
||||||
|
|
||||||
if (message.equals("params_error")) {
|
if (message.equals("params_error")) {
|
||||||
throw new TikTokLiveRequestException("fetchRoomIdFromTiktokApi -> Unable to fetch roomID, contact the developer");
|
throw new TikTokLiveRequestException("fetchRoomIdFromTiktokApi -> Unable to fetch roomID, contact the developer");
|
||||||
}
|
}
|
||||||
if (message.equals("user_not_found")) {
|
if (message.equals("user_not_found")) {
|
||||||
|
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1);
|
||||||
|
}
|
||||||
|
//live -> status 2
|
||||||
|
//live paused -> 3
|
||||||
|
//not live -> status 4
|
||||||
|
var element = jsonObject.get("data");
|
||||||
|
if (element.isJsonNull()) {
|
||||||
|
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1);
|
||||||
|
}
|
||||||
|
var data = element.getAsJsonObject();
|
||||||
|
var user = data.getAsJsonObject("user");
|
||||||
|
var roomId = user.get("roomId").getAsString();
|
||||||
|
var status = user.get("status").getAsInt();
|
||||||
|
|
||||||
|
var liveRoom = data.getAsJsonObject("liveRoom");
|
||||||
|
long startTime = liveRoom.get("startTime").getAsLong();
|
||||||
|
|
||||||
|
var statusEnum = switch (status) {
|
||||||
|
case 2 -> LiveUserData.UserStatus.Live;
|
||||||
|
case 3 -> LiveUserData.UserStatus.LivePaused;
|
||||||
|
case 4 -> LiveUserData.UserStatus.Offline;
|
||||||
|
default -> LiveUserData.UserStatus.NotFound;
|
||||||
|
};
|
||||||
|
|
||||||
|
return new LiveUserData.Response(json, statusEnum, roomId, startTime);
|
||||||
|
} catch (JsonSyntaxException | IllegalStateException e) {
|
||||||
|
logger.warning("Malformed Json: '"+json+"' - Error Message: "+e.getMessage());
|
||||||
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1);
|
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1);
|
||||||
}
|
}
|
||||||
//live -> status 2
|
|
||||||
//live paused -> 3
|
|
||||||
//not live -> status 4
|
|
||||||
var element = jsonObject.get("data");
|
|
||||||
if (element.isJsonNull()) {
|
|
||||||
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1);
|
|
||||||
}
|
|
||||||
var data = element.getAsJsonObject();
|
|
||||||
var user = data.getAsJsonObject("user");
|
|
||||||
var roomId = user.get("roomId").getAsString();
|
|
||||||
var status = user.get("status").getAsInt();
|
|
||||||
|
|
||||||
var liveRoom = data.getAsJsonObject("liveRoom");
|
|
||||||
long startTime = liveRoom.get("startTime").getAsLong();
|
|
||||||
|
|
||||||
var statusEnum = switch (status) {
|
|
||||||
case 2 -> LiveUserData.UserStatus.Live;
|
|
||||||
case 3 -> LiveUserData.UserStatus.LivePaused;
|
|
||||||
case 4 -> LiveUserData.UserStatus.Offline;
|
|
||||||
default -> LiveUserData.UserStatus.NotFound;
|
|
||||||
};
|
|
||||||
|
|
||||||
return new LiveUserData.Response(json, statusEnum, roomId, startTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,13 +27,11 @@ import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
|||||||
import io.github.jwdeveloper.tiktok.data.events.gift.*;
|
import io.github.jwdeveloper.tiktok.data.events.gift.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.*;
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.TikTokMapperHelper;
|
import io.github.jwdeveloper.tiktok.mappers.TikTokMapperHelper;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
|
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import sun.misc.Unsafe;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -58,40 +56,40 @@ public class TikTokGiftEventHandler {
|
|||||||
|
|
||||||
public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage) {
|
public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage) {
|
||||||
var userId = currentMessage.getUser().getId();
|
var userId = currentMessage.getUser().getId();
|
||||||
var currentType = GiftSendType.fromNumber(currentMessage.getSendType());
|
var currentType = GiftComboStateType.fromNumber(currentMessage.getSendType());
|
||||||
var containsPreviousMessage = giftsMessages.containsKey(userId);
|
var containsPreviousMessage = giftsMessages.containsKey(userId);
|
||||||
|
|
||||||
|
|
||||||
//If gift is not streakable just return onGift event
|
//If gift is not streakable just return onGift event
|
||||||
if (currentMessage.getGift().getType() != 1) {
|
if (currentMessage.getGift().getType() != 1) {
|
||||||
var comboEvent = getGiftComboEvent(currentMessage, GiftSendType.Finished);
|
var comboEvent = getGiftComboEvent(currentMessage, GiftComboStateType.Finished);
|
||||||
var giftEvent = getGiftEvent(currentMessage);
|
var giftEvent = getGiftEvent(currentMessage);
|
||||||
return List.of(comboEvent, giftEvent);
|
return List.of(comboEvent, giftEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!containsPreviousMessage) {
|
if (!containsPreviousMessage) {
|
||||||
if (currentType == GiftSendType.Finished) {
|
if (currentType == GiftComboStateType.Finished) {
|
||||||
return List.of(getGiftEvent(currentMessage));
|
return List.of(getGiftEvent(currentMessage));
|
||||||
} else {
|
} else {
|
||||||
giftsMessages.put(userId, currentMessage);
|
giftsMessages.put(userId, currentMessage);
|
||||||
return List.of(getGiftComboEvent(currentMessage, GiftSendType.Begin));
|
return List.of(getGiftComboEvent(currentMessage, GiftComboStateType.Begin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var previousMessage = giftsMessages.get(userId);
|
var previousMessage = giftsMessages.get(userId);
|
||||||
var previousType = GiftSendType.fromNumber(previousMessage.getSendType());
|
var previousType = GiftComboStateType.fromNumber(previousMessage.getSendType());
|
||||||
if (currentType == GiftSendType.Active &&
|
if (currentType == GiftComboStateType.Active &&
|
||||||
previousType == GiftSendType.Active) {
|
previousType == GiftComboStateType.Active) {
|
||||||
giftsMessages.put(userId, currentMessage);
|
giftsMessages.put(userId, currentMessage);
|
||||||
return List.of(getGiftComboEvent(currentMessage, GiftSendType.Active));
|
return List.of(getGiftComboEvent(currentMessage, GiftComboStateType.Active));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (currentType == GiftSendType.Finished &&
|
if (currentType == GiftComboStateType.Finished &&
|
||||||
previousType == GiftSendType.Active) {
|
previousType == GiftComboStateType.Active) {
|
||||||
giftsMessages.clear();
|
giftsMessages.clear();
|
||||||
return List.of(
|
return List.of(
|
||||||
getGiftComboEvent(currentMessage, GiftSendType.Finished),
|
getGiftComboEvent(currentMessage, GiftComboStateType.Finished),
|
||||||
getGiftEvent(currentMessage));
|
getGiftEvent(currentMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +102,7 @@ public class TikTokGiftEventHandler {
|
|||||||
return new TikTokGiftEvent(gift, tikTokRoomInfo.getHost(), message);
|
return new TikTokGiftEvent(gift, tikTokRoomInfo.getHost(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TikTokGiftEvent getGiftComboEvent(WebcastGiftMessage message, GiftSendType state) {
|
private TikTokGiftEvent getGiftComboEvent(WebcastGiftMessage message, GiftComboStateType state) {
|
||||||
var gift = getGiftObject(message);
|
var gift = getGiftObject(message);
|
||||||
return new TikTokGiftComboEvent(gift, tikTokRoomInfo.getHost(), message, state);
|
return new TikTokGiftComboEvent(gift, tikTokRoomInfo.getHost(), message, state);
|
||||||
}
|
}
|
||||||
@@ -124,36 +122,8 @@ public class TikTokGiftEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gift.getPicture().getLink().endsWith(".webp"))
|
if (gift.getPicture().getLink().endsWith(".webp"))
|
||||||
{
|
gift.setPicture(Picture.map(giftMessage.getGift().getImage()));
|
||||||
updatePicture(gift, giftMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gift;
|
return gift;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO-kohlerpop1: I do not think this method is needed for any reason?
|
|
||||||
// TODO response:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some generated gifts in JSON file contains .webp image format,
|
|
||||||
* that's bad since java by the defult is not supporing .webp and when URL is
|
|
||||||
* converted to Java.io.Image then image is null
|
|
||||||
*
|
|
||||||
* However, TikTok in GiftWebcast event always has image in .jpg format,
|
|
||||||
* so I take advantage of it and swap .webp url with .jpg url
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
private void updatePicture(Gift gift, WebcastGiftMessage webcastGiftMessage) {
|
|
||||||
try {
|
|
||||||
var picture = Picture.map(webcastGiftMessage.getGift().getImage());
|
|
||||||
var constructor = Unsafe.class.getDeclaredConstructors()[0];
|
|
||||||
constructor.setAccessible(true);
|
|
||||||
var field = Gift.class.getDeclaredField("picture");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(gift, picture);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new TikTokLiveException("Unable to update picture in gift: " + gift.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
|||||||
private void connectDefault() {
|
private void connectDefault() {
|
||||||
try {
|
try {
|
||||||
webSocketClient.connect();
|
webSocketClient.connect();
|
||||||
pingingTask.run(webSocketClient);
|
pingingTask.run(webSocketClient, clientSettings.getPingInterval());
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
@@ -112,7 +112,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
|||||||
proxySettings.remove();
|
proxySettings.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pingingTask.run(webSocketClient);
|
pingingTask.run(webSocketClient, clientSettings.getPingInterval());
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(e));
|
tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(e));
|
||||||
}
|
}
|
||||||
if (isNotClosing()) {
|
if (isOpen()) {
|
||||||
sendPing();
|
sendPing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,8 +79,7 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
|||||||
pushFrameBuilder.setPayloadType("ack");
|
pushFrameBuilder.setPayloadType("ack");
|
||||||
pushFrameBuilder.setLogId(websocketPushFrame.getLogId());
|
pushFrameBuilder.setLogId(websocketPushFrame.getLogId());
|
||||||
pushFrameBuilder.setPayload(webcastResponse.getInternalExtBytes());
|
pushFrameBuilder.setPayload(webcastResponse.getInternalExtBytes());
|
||||||
if (isNotClosing())
|
if (isOpen()) {
|
||||||
{
|
|
||||||
this.send(pushFrameBuilder.build().toByteArray());
|
this.send(pushFrameBuilder.build().toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +89,7 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
|||||||
@Override
|
@Override
|
||||||
public void onOpen(ServerHandshake serverHandshake) {
|
public void onOpen(ServerHandshake serverHandshake) {
|
||||||
tikTokEventHandler.publish(tikTokLiveClient, new TikTokConnectedEvent());
|
tikTokEventHandler.publish(tikTokLiveClient, new TikTokConnectedEvent());
|
||||||
if (isNotClosing()) {
|
if (isOpen()) {
|
||||||
sendPing();
|
sendPing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +103,7 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
|||||||
@Override
|
@Override
|
||||||
public void onError(Exception error) {
|
public void onError(Exception error) {
|
||||||
tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(error));
|
tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(error));
|
||||||
if (isNotClosing()) {
|
if (isOpen()) {
|
||||||
sendPing();
|
sendPing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,10 +128,6 @@ public class TikTokWebSocketListener extends WebSocketClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNotClosing() {
|
|
||||||
return !isClosed() && !isClosing();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(String s) {
|
public void onMessage(String s) {
|
||||||
// System.err.println(s);
|
// System.err.println(s);
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.websocket;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.TikTokLiveEventHandler;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.TikTokConnectedEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
||||||
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
|
|
||||||
|
public class TikTokWebSocketOfflineClient implements SocketClient {
|
||||||
|
|
||||||
|
private final TikTokLiveEventHandler handler;
|
||||||
|
private LiveClient liveClient;
|
||||||
|
|
||||||
|
public TikTokWebSocketOfflineClient(TikTokLiveEventHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(LiveConnectionData.Response webcastResponse, LiveClient tikTokLiveClient) {
|
||||||
|
liveClient = tikTokLiveClient;
|
||||||
|
handler.publish(liveClient, new TikTokConnectedEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if (liveClient == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handler.publish(liveClient, new TikTokDisconnectedEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,13 +8,13 @@ public class TikTokWebSocketPingingTask
|
|||||||
{
|
{
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private boolean isRunning = false;
|
private boolean isRunning = false;
|
||||||
private final int MIN_TIMEOUT = 250;
|
private final int MAX_TIMEOUT = 250;
|
||||||
private final int MAX_TIMEOUT = 500;
|
private final int SLEEP_TIME = 500;
|
||||||
|
|
||||||
public void run(WebSocket webSocket)
|
public void run(WebSocket webSocket, long pingTaskTime)
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
thread = new Thread(() -> pingTask(webSocket));
|
thread = new Thread(() -> pingTask(webSocket, pingTaskTime));
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
@@ -26,20 +26,18 @@ public class TikTokWebSocketPingingTask
|
|||||||
isRunning = false;
|
isRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void pingTask(WebSocket webSocket, long pingTaskTime)
|
||||||
private void pingTask(WebSocket webSocket)
|
|
||||||
{
|
{
|
||||||
var random = new Random();
|
var random = new Random();
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
try {
|
try {
|
||||||
if (!webSocket.isOpen()) {
|
if (!webSocket.isOpen()) {
|
||||||
Thread.sleep(100);
|
Thread.sleep(SLEEP_TIME);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
webSocket.sendPing();
|
webSocket.sendPing();
|
||||||
|
|
||||||
var timeout = random.nextInt(MAX_TIMEOUT)+MIN_TIMEOUT;
|
Thread.sleep(pingTaskTime+random.nextInt(MAX_TIMEOUT));
|
||||||
Thread.sleep(timeout);
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
|||||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftSendType;
|
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType;
|
||||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokGiftEventHandler;
|
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokGiftEventHandler;
|
||||||
import io.github.jwdeveloper.tiktok.messages.data.GiftStruct;
|
import io.github.jwdeveloper.tiktok.messages.data.GiftStruct;
|
||||||
@@ -40,7 +40,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.TestInstance;
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
@@ -99,9 +98,9 @@ class TikTokGiftEventHandlerTest {
|
|||||||
Assertions.assertEquals(2, result3.size());
|
Assertions.assertEquals(2, result3.size());
|
||||||
var event3 = (TikTokGiftComboEvent) result3.get(0);
|
var event3 = (TikTokGiftComboEvent) result3.get(0);
|
||||||
|
|
||||||
Assertions.assertEquals(GiftSendType.Begin, event1.getComboState());
|
Assertions.assertEquals(GiftComboStateType.Begin, event1.getComboState());
|
||||||
Assertions.assertEquals(GiftSendType.Active, event2.getComboState());
|
Assertions.assertEquals(GiftComboStateType.Active, event2.getComboState());
|
||||||
Assertions.assertEquals(GiftSendType.Finished, event3.getComboState());
|
Assertions.assertEquals(GiftComboStateType.Finished, event3.getComboState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -118,7 +117,7 @@ class TikTokGiftEventHandlerTest {
|
|||||||
|
|
||||||
giftBuilder.setId(giftId);
|
giftBuilder.setId(giftId);
|
||||||
giftBuilder.setName(giftName);
|
giftBuilder.setName(giftName);
|
||||||
giftBuilder.setImage(Image.newBuilder().addUrlList(giftImage).build());
|
giftBuilder.setImage(Image.newBuilder().addUrl(giftImage).build());
|
||||||
giftBuilder.setType(streakable ? 1 : 0);
|
giftBuilder.setType(streakable ? 1 : 0);
|
||||||
userBuilder.setId(userId);
|
userBuilder.setId(userId);
|
||||||
|
|
||||||
@@ -130,4 +129,4 @@ class TikTokGiftEventHandlerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
<artifactId>TikTokLiveJava</artifactId>
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<version>1.3.0-Release</version>
|
<version>1.6.0-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<artifactId>extension-collector</artifactId>
|
<artifactId>extension-collector</artifactId>
|
||||||
<version>1.3.0-Release</version>
|
<version>1.6.0-Release</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
public class ChatMessageExample {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
|
|
||||||
var roomData = TikTokLive.requests()
|
|
||||||
.fetchLiveData("X");
|
|
||||||
|
|
||||||
var gifts = TikTokLive.requests().fetchGiftsData();
|
|
||||||
|
|
||||||
|
|
||||||
var user = TikTokLive.requests()
|
|
||||||
.fetchLiveUserData("mark");
|
|
||||||
|
|
||||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
|
||||||
.configure(clientSettings ->
|
|
||||||
{
|
|
||||||
clientSettings.setPrintToConsole(true);
|
|
||||||
clientSettings.getHttpSettings().setTimeout(Duration.ofSeconds(21));
|
|
||||||
})
|
|
||||||
.onComment((liveClient, event) ->
|
|
||||||
{
|
|
||||||
System.out.println("Chat message: " + event.getUser().getName() + " " + event.getText());
|
|
||||||
})
|
|
||||||
.onWebsocketUnhandledMessage((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info(event.getMessage().getMethod());
|
|
||||||
}).buildAndConnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,27 +25,20 @@ package io.github.jwdeveloper.tiktok;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.extension.collector.TikTokLiveCollector;
|
import io.github.jwdeveloper.tiktok.extension.collector.TikTokLiveCollector;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class CollectorExample {
|
public class CollectorExample {
|
||||||
|
|
||||||
|
|
||||||
private static String mongoUser;
|
|
||||||
|
|
||||||
private static String mongoPassword;
|
|
||||||
|
|
||||||
private static String mongoDatabase;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
var collector = TikTokLiveCollector.use(settings ->
|
var path = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Examples\\src\\main\\resources";
|
||||||
|
var collector = TikTokLiveCollector.useFile(settings ->
|
||||||
{
|
{
|
||||||
settings.setConnectionUrl("mongodb+srv://" + mongoUser + ":" + mongoPassword + "@" + mongoDatabase + "/?retryWrites=true&w=majority");
|
settings.setParentFile(new File(path));
|
||||||
settings.setDatabaseName("tiktok");
|
|
||||||
});
|
});
|
||||||
collector.connectDatabase();
|
collector.connect();
|
||||||
|
|
||||||
var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live");
|
var users = List.of("tehila_723", "dino123597", "domaxyzx", "dash4214", "obserwacje_live");
|
||||||
Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag");
|
Map<String, Object> additionalDataFields = Map.of("sessionTag", "ExampleTag");
|
||||||
@@ -59,18 +52,11 @@ public class CollectorExample {
|
|||||||
{
|
{
|
||||||
event.getException().printStackTrace();
|
event.getException().printStackTrace();
|
||||||
})
|
})
|
||||||
.addListener(collector.newListener(additionalDataFields, document ->
|
.addListener(collector.newListener(additionalDataFields))
|
||||||
{
|
|
||||||
//filtering document data before it is inserted to database
|
|
||||||
if (document.get("dataType") == "message") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}))
|
|
||||||
.buildAndConnectAsync();
|
.buildAndConnectAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.in.read();
|
System.in.read();
|
||||||
collector.disconnectDatabase();
|
collector.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ import java.io.IOException;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class SimpleExample {
|
public class ConnectionExample {
|
||||||
public static String TIKTOK_HOSTNAME = "kvadromama_marina1";
|
public static String TIKTOK_HOSTNAME = "kvadromama_marina1";
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
@@ -40,10 +40,10 @@ public class SimpleExample {
|
|||||||
|
|
||||||
var gifts = TikTokLive.gifts();
|
var gifts = TikTokLive.gifts();
|
||||||
|
|
||||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
.configure(clientSettings ->
|
.configure(clientSettings ->
|
||||||
{
|
{
|
||||||
clientSettings.setHostName(SimpleExample.TIKTOK_HOSTNAME); // This method is useful in case you want change hostname later
|
clientSettings.setHostName(ConnectionExample.TIKTOK_HOSTNAME); // This method is useful in case you want change hostname later
|
||||||
clientSettings.setClientLanguage("en"); // Language
|
clientSettings.setClientLanguage("en"); // Language
|
||||||
clientSettings.setLogLevel(Level.ALL); // Log level
|
clientSettings.setLogLevel(Level.ALL); // Log level
|
||||||
clientSettings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
clientSettings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||||
@@ -39,7 +39,7 @@ public class CustomEventExample {
|
|||||||
|
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
.configure(clientSettings ->
|
.configure(clientSettings ->
|
||||||
{
|
{
|
||||||
clientSettings.setPrintToConsole(true);
|
clientSettings.setPrintToConsole(true);
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.TikTokSubscribeEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.social.TikTokFollowEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.social.TikTokJoinEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.models.gifts.GiftComboStateType;
|
||||||
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
|
|
||||||
|
public class Events_And_Gifts_Testing_Example
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
LiveClient client = TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
|
.configure(liveClientSettings ->
|
||||||
|
{
|
||||||
|
liveClientSettings.setOffline(true);
|
||||||
|
liveClientSettings.setPrintToConsole(true);
|
||||||
|
})
|
||||||
|
.onConnected((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("Connected");
|
||||||
|
})
|
||||||
|
.onDisconnected((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("Disconnected");
|
||||||
|
})
|
||||||
|
.onGiftCombo((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("New fake combo Gift: " + event.getGift());
|
||||||
|
})
|
||||||
|
.onGift((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("New fake Gift: " + event.getGift());
|
||||||
|
})
|
||||||
|
.onLike((liveClient, event) ->
|
||||||
|
{
|
||||||
|
liveClient.getLogger().info("New fake Like event: " + event.getLikes());
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
var gifts = TikTokLive.gifts();
|
||||||
|
var roseGift = gifts.getByName("Rose");
|
||||||
|
|
||||||
|
var fakeGift = TikTokGiftEvent.of(roseGift);
|
||||||
|
var fakeComboGift = TikTokGiftComboEvent.of(roseGift, 12, GiftComboStateType.Begin);
|
||||||
|
|
||||||
|
var fakeMessage = TikTokCommentEvent.of("Mark", "Hello world");
|
||||||
|
|
||||||
|
var fakeSubscriber = TikTokSubscribeEvent.of("Mark");
|
||||||
|
var fakeFollow = TikTokFollowEvent.of("Mark");
|
||||||
|
var fakeLike = TikTokLikeEvent.of("Mark", 12);
|
||||||
|
var fakeJoin = TikTokJoinEvent.of("Mark");
|
||||||
|
|
||||||
|
client.connect();
|
||||||
|
|
||||||
|
client.publishEvent(fakeGift);
|
||||||
|
client.publishEvent(fakeComboGift);
|
||||||
|
client.publishEvent(fakeMessage);
|
||||||
|
client.publishEvent(fakeSubscriber);
|
||||||
|
client.publishEvent(fakeFollow);
|
||||||
|
client.publishEvent(fakeJoin);
|
||||||
|
|
||||||
|
client.publishEvent(fakeLike);
|
||||||
|
client.publishMessage("WebcastLikeMessage", webcastLikeMessageBase64);
|
||||||
|
|
||||||
|
client.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String webcastLikeMessageBase64 = "SAFSBRABGKwCUgcIAhABGKwCCv8BUAFYAbABA7gBARCflqWWo8Ha72UgzoPZhd8xQrwBGg4gkAMKCSNmZmZmZmZmZiJ/qgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXoICwoQcG1fbXRfbXNnX3ZpZXdlchIXezA6dXNlcn0gbGlrZWQgdGhlIExJVkVIAQoSV2ViY2FzdExpa2VNZXNzYWdlGIaWvY+RhdjvZTABwAEBEA8Y+Voq7RCyAQYImwEQjwK6AQCCAgDyAkxNUzR3TGpBQkFBQUF1Ml9tSzRMOFhiWGt5TWlBb2cyVE5zZlY5OTdPVjNraUNzQk5DY2FpMHFsSHFLdENwdFBlNTdkS2FYcW9MVkl6ggTqCLoBnwUqBggBEAEYIFoNCgASCSNCMzQ3N0VGRoABDwgEEtgEEix3ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZzrpAnNzbG9jYWw6Ly93ZWJjYXN0X2x5bnh2aWV3X3BvcHVwP3VzZV9zcGFyaz0xJnVybD1odHRwcyUzQSUyRiUyRmxmMTYtZ2Vja28tc291cmNlLnRpa3Rva2Nkbi5jb20lMkZvYmolMkZieXRlLWd1cmQtc291cmNlLXNnJTJGdGlrdG9rJTJGZmUlMkZsaXZlJTJGdGlrdG9rX2xpdmVfcmV2ZW51ZV91c2VyX2xldmVsX21haW4lMkZzcmMlMkZwYWdlcyUyRnByaXZpbGVnZSUyRnBhbmVsJTJGdGVtcGxhdGUuanMmaGlkZV9zdGF0dXNfYmFyPTAmaGlkZV9uYXZfYmFyPTEmY29udGFpbmVyX2JnX2NvbG9yPTAwMDAwMDAwJmhlaWdodD05MCUyNSZiZGhtX2JpZD10aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiZ1c2VfZm9yZXN0PTEKXWh0dHBzOi8vcDE2LXdlYmNhc3QudGlrdG9rY2RuLmNvbS93ZWJjYXN0LXZhL2dyYWRlX2JhZGdlX2ljb25fbGl0ZV9sdjE1X3YyLnBuZ350cGx2LW9iai5pbWFnZQpdaHR0cHM6Ly9wMTktd2ViY2FzdC50aWt0b2tjZG4uY29tL3dlYmNhc3QtdmEvZ3JhZGVfYmFkZ2VfaWNvbl9saXRlX2x2MTVfdjIucG5nfnRwbHYtb2JqLmltYWdlIgIxNTIAOgYaAhIAIgBiDQoAEgkjQjM0NzdFRkZ4DqIBBggBEAEYIAgEEBQYCCABUukCc3Nsb2NhbDovL3dlYmNhc3RfbHlueHZpZXdfcG9wdXA/dXNlX3NwYXJrPTEmdXJsPWh0dHBzJTNBJTJGJTJGbGYxNi1nZWNrby1zb3VyY2UudGlrdG9rY2RuLmNvbSUyRm9iaiUyRmJ5dGUtZ3VyZC1zb3VyY2Utc2clMkZ0aWt0b2slMkZmZSUyRmxpdmUlMkZ0aWt0b2tfbGl2ZV9yZXZlbnVlX3VzZXJfbGV2ZWxfbWFpbiUyRnNyYyUyRnBhZ2VzJTJGcHJpdmlsZWdlJTJGcGFuZWwlMkZ0ZW1wbGF0ZS5qcyZoaWRlX3N0YXR1c19iYXI9MCZoaWRlX25hdl9iYXI9MSZjb250YWluZXJfYmdfY29sb3I9MDAwMDAwMDAmaGVpZ2h0PTkwJTI1JmJkaG1fYmlkPXRpa3Rva19saXZlX3JldmVudWVfdXNlcl9sZXZlbF9tYWluJnVzZV9mb3Jlc3Q9MVgBYk8qAjE1CgEyEhM3MTM4MzgxNzQ3MjkyNTQyNzU2GgEwIi5tb2NrX2ZpeF93aWR0aF90cmFuc3BhcmVudF83MTM4MzgxNzQ3MjkyNTQyNzU2CIWI44D1ib+0YBoQ8J2SpvCdk47wnZOO8JOFk0r1BhJBMTAweDEwMC90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzEK0gFodHRwczovL3AxOS1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1VMlNEbUk3Z3R5RW9rMlBlWFdmeTNsM1F6NlElM0QKyAFodHRwczovL3AxNi1wdS1zaWduLXVzZWFzdDgudGlrdG9rY2RuLXVzLmNvbS90b3MtdXNlYXN0OC1hdnQtMDA2OC10eDIvNjY0NmM4NjZjMzI1MWEwOTY3NjhiYjY4OTUyODVjMzF+YzVfMTAweDEwMC53ZWJwP2xrM3M9YTVkNDgwNzgmeC1leHBpcmVzPTE3MDkzMTI0MDAmeC1zaWduYXR1cmU9aWNWZEVZa0FnWkYlMkZ2WU5OTSUyRlVNMzE2eG9HdyUzRArGAWh0dHBzOi8vcDE5LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLndlYnA/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT1PQzdBQ3htQUklMkJsYlp4RkVuWktJT1RyRExGUSUzRArGAWh0dHBzOi8vcDE2LXB1LXNpZ24tdXNlYXN0OC50aWt0b2tjZG4tdXMuY29tL3Rvcy11c2Vhc3Q4LWF2dC0wMDY4LXR4Mi82NjQ2Yzg2NmMzMjUxYTA5Njc2OGJiNjg5NTI4NWMzMX5jNV8xMDB4MTAwLmpwZWc/bGszcz1hNWQ0ODA3OCZ4LWV4cGlyZXM9MTcwOTMxMjQwMCZ4LXNpZ25hdHVyZT02YUwlMkZNZWtOeHg5NXlvVTVLOTZON0xwRUlNdyUzRLICCmt5bGxlZWhhbGxCyQEIgojG1pKb0clgErwBChBwbV9tdF9tc2dfdmlld2VyEhd7MDp1c2VyfSBsaWtlZCB0aGUgTElWRRoOCgkjZmZmZmZmZmYgkAMifwgLqgF6CngIhYjjgPWJv7RgGhDwnZKm8J2TjvCdk47wk4WTsgIKa3lsbGVlaGFsbPICTE1TNHdMakFCQUFBQXUyX21LNEw4WGJYa3lNaUFvZzJUTnNmVjk5N09WM2tpQ3NCTkNjYWkwcWxIcUt0Q3B0UGU1N2RLYVhxb0xWSXo=";
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ public class ListenerExample
|
|||||||
showLogo();
|
showLogo();
|
||||||
CustomListener customListener = new CustomListener();
|
CustomListener customListener = new CustomListener();
|
||||||
|
|
||||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
.addListener(customListener)
|
.addListener(customListener)
|
||||||
.buildAndConnect();
|
.buildAndConnect();
|
||||||
System.in.read();
|
System.in.read();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import java.net.Proxy;
|
|||||||
|
|
||||||
public class ProxyExample {
|
public class ProxyExample {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
|
TikTokLive.newClient(ConnectionExample.TIKTOK_HOSTNAME)
|
||||||
.configure(clientSettings -> {
|
.configure(clientSettings -> {
|
||||||
clientSettings.setPrintToConsole(true);
|
clientSettings.setPrintToConsole(true);
|
||||||
clientSettings.getHttpSettings().configureProxy(proxySettings -> {
|
clientSettings.getHttpSettings().configureProxy(proxySettings -> {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ Maven
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||||
<artifactId>Client</artifactId>
|
<artifactId>Client</artifactId>
|
||||||
<version>1.3.0-Release</version>
|
<version>1.6.0-Release</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -87,7 +87,7 @@ dependencyResolutionManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.jwdeveloper.TikTok-Live-Java:Client:1.1.0-Release'
|
implementation 'com.github.jwdeveloper.TikTok-Live-Java:Client:1.5.0-Release'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
|
||||||
<version>1.3.0-Release</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>Tools-EventsCollector</artifactId>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>16</maven.compiler.source>
|
|
||||||
<maven.compiler.target>16</maven.compiler.target>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.xerial</groupId>
|
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
|
||||||
<version>3.34.0</version> <!-- Use the latest version available -->
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jdbi</groupId>
|
|
||||||
<artifactId>jdbi3-core</artifactId>
|
|
||||||
<version>3.23.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.googlecode.protobuf-java-format</groupId>
|
|
||||||
<artifactId>protobuf-java-format</artifactId>
|
|
||||||
<version>1.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jdbi</groupId>
|
|
||||||
<artifactId>jdbi3-sqlobject</artifactId>
|
|
||||||
<version>3.23.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>1.7.32</version> <!-- Use the latest version available -->
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
|
||||||
<artifactId>Client</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
|
||||||
<artifactId>Tools-ReadmeGenerator</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.client.TikTokDataCollectorBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollectorBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.TikTokDataTesterBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTesterBuilder;
|
|
||||||
|
|
||||||
public class TikTokLiveTools
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param databaseName dataCollector use sql-lite database to store message
|
|
||||||
* if database not exits it creates new one
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static DataCollectorBuilder createCollector(String databaseName)
|
|
||||||
{
|
|
||||||
return new TikTokDataCollectorBuilder(databaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param databaseName dataTester will read messages for database
|
|
||||||
* before using dataTester, use dataCollector to create database
|
|
||||||
* if database not exits exception will be thrown
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static DataTesterBuilder createTester(String databaseName)
|
|
||||||
{
|
|
||||||
return new TikTokDataTesterBuilder(databaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Returns browser application that collects and display Events, Messages, WebcastResponses
|
|
||||||
* in online web editor so it's easier to read and analyze data structures
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static void createWebViewer()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.api;
|
|
||||||
|
|
||||||
public interface DataCollector {
|
|
||||||
|
|
||||||
void connect();
|
|
||||||
|
|
||||||
|
|
||||||
void disconnect();
|
|
||||||
|
|
||||||
void disconnect(boolean keepDatabase);
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.api;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface DataCollectorBuilder extends DataFilters<DataCollectorBuilder> {
|
|
||||||
DataCollectorBuilder setOutputPath(String path);
|
|
||||||
DataCollectorBuilder setSessionTag(String sessionTimestamp);
|
|
||||||
|
|
||||||
DataCollectorBuilder setDatabase(TikTokDatabase database);
|
|
||||||
|
|
||||||
DataCollectorBuilder configureLiveClient(Consumer<LiveClientBuilder> consumer);
|
|
||||||
|
|
||||||
DataCollectorBuilder addUser(String user);
|
|
||||||
|
|
||||||
DataCollector buildAndRun();
|
|
||||||
|
|
||||||
DataCollector build();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.api;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
|
||||||
|
|
||||||
public interface DataFilters<T> {
|
|
||||||
T addMessageFilter(Class<? extends com.google.protobuf.GeneratedMessageV3> message);
|
|
||||||
|
|
||||||
T addMessageFilter(String message);
|
|
||||||
|
|
||||||
T addEventFilter(Class<? extends TikTokEvent> event);
|
|
||||||
|
|
||||||
T addEventFilter(String event);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.api;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TikTokDataCollectorModel {
|
|
||||||
private List<String> users;
|
|
||||||
private String outputPath;
|
|
||||||
private String outputName;
|
|
||||||
private Set<String> eventsFilter;
|
|
||||||
private Set<String> messagesFilter;
|
|
||||||
private String sessionTag ="";
|
|
||||||
private Consumer<LiveClientBuilder> onConfigureLiveClient;
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.client;
|
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import io.github.jwdeveloper.tiktok.FilesUtility;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class MessagesManager {
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
Map<String, Queue<MessageData>> messages;
|
|
||||||
String outputName;
|
|
||||||
|
|
||||||
int limit = 20;
|
|
||||||
public MessagesManager(String outputName) {
|
|
||||||
this.messages = new TreeMap<>();
|
|
||||||
this.outputName = outputName;
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMessage(Logger logger, String host, WebcastResponse.Message message) {
|
|
||||||
var name = message.getMethod();
|
|
||||||
var payload = message.getPayload().toByteArray();
|
|
||||||
var base64 = Base64.getEncoder().encodeToString(payload);
|
|
||||||
|
|
||||||
if (!messages.containsKey(name)) {
|
|
||||||
logger.info("New Message found! " + name);
|
|
||||||
messages.put(name, new LinkedList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
var queue = messages.get(name);
|
|
||||||
if (queue.size() > limit) {
|
|
||||||
queue.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.add(new MessageData(base64, host, LocalDateTime.now().toString()));
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toJson() {
|
|
||||||
return JsonUtil.toJson(messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load() {
|
|
||||||
var file = new File(path());
|
|
||||||
Type type = new TypeToken<Map<String, Queue<MessageData>>>() {}.getType();
|
|
||||||
|
|
||||||
if (file.exists()) {
|
|
||||||
var content = FilesUtility.loadFileContent(path());
|
|
||||||
var gson = new GsonBuilder().create();
|
|
||||||
messages = gson.fromJson(content,type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save() {
|
|
||||||
|
|
||||||
FilesUtility.saveFile(path(), toJson());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String path() {
|
|
||||||
return Paths.get("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-EventsCollector\\src\\main\\resources", outputName + ".json").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public class MessageData {
|
|
||||||
String eventData;
|
|
||||||
String uniqueId;
|
|
||||||
String ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.client;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
|
|
||||||
public class TikTokClientFactory {
|
|
||||||
private final MessagesManager messageCollector;
|
|
||||||
private final TikTokDatabase tikTokDatabase;
|
|
||||||
|
|
||||||
public TikTokClientFactory(MessagesManager messageCollector, TikTokDatabase tikTokDatabase) {
|
|
||||||
this.messageCollector = messageCollector;
|
|
||||||
this.tikTokDatabase = tikTokDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.client;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLive;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.http.TikTokHttpResponseEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketMessageEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollector;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.TikTokDataCollectorModel;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.ExceptionInfoModel;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokErrorModel;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TikTokDataCollector implements DataCollector {
|
|
||||||
private final TikTokDataCollectorModel dataCollectorModel;
|
|
||||||
private final TikTokDatabase tikTokDatabase;
|
|
||||||
private final List<LiveClient> tiktokClients;
|
|
||||||
|
|
||||||
public TikTokDataCollector(TikTokDataCollectorModel dataCollectorModel, TikTokDatabase tikTokDatabase) {
|
|
||||||
this.dataCollectorModel = dataCollectorModel;
|
|
||||||
this.tikTokDatabase = tikTokDatabase;
|
|
||||||
this.tiktokClients = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect() {
|
|
||||||
try {
|
|
||||||
if (!tikTokDatabase.isConnected()) {
|
|
||||||
tikTokDatabase.connect();
|
|
||||||
}
|
|
||||||
for (var user : dataCollectorModel.getUsers()) {
|
|
||||||
var client = createLiveClient(user);
|
|
||||||
tiktokClients.add(client);
|
|
||||||
client.connectAsync();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to start tiktok connector", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void disconnect() {
|
|
||||||
disconnect(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disconnect(boolean keepDatabase) {
|
|
||||||
try {
|
|
||||||
for (var client : tiktokClients) {
|
|
||||||
client.disconnect();
|
|
||||||
}
|
|
||||||
if (!keepDatabase) {
|
|
||||||
tikTokDatabase.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to stop tiktok connector", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveClient createLiveClient(String tiktokUser) {
|
|
||||||
var builder = TikTokLive.newClient(tiktokUser);
|
|
||||||
builder.onConnected((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Connected to " + liveClient.getRoomInfo().getHostName());
|
|
||||||
})
|
|
||||||
.onDisconnected((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Disconnected " + liveClient.getRoomInfo().getHostName());
|
|
||||||
})
|
|
||||||
.onWebsocketResponse(this::handleResponseAndMessages)
|
|
||||||
.onWebsocketMessage(this::handleMappedEvent)
|
|
||||||
.onHttpResponse((liveClient, event) ->
|
|
||||||
{
|
|
||||||
var data = createHttpResponseData(event, tiktokUser);
|
|
||||||
tikTokDatabase.insertData(data);
|
|
||||||
})
|
|
||||||
.onError(this::handleError);
|
|
||||||
dataCollectorModel.getOnConfigureLiveClient().accept(builder);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleResponseAndMessages(LiveClient client, TikTokWebsocketResponseEvent event) {
|
|
||||||
var responseData = createResponseData(event.getResponse(), client.getRoomInfo().getHostName());
|
|
||||||
tikTokDatabase.insertData(responseData);
|
|
||||||
|
|
||||||
var filter = dataCollectorModel.getMessagesFilter();
|
|
||||||
for (var message : event.getResponse().getMessagesList()) {
|
|
||||||
if (filter.isEmpty()) {
|
|
||||||
var data = createMessageData(message, client.getRoomInfo().getHostName());
|
|
||||||
tikTokDatabase.insertData(data);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!filter.contains(message.getMethod())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var data = createMessageData(message, client.getRoomInfo().getHostName());
|
|
||||||
tikTokDatabase.insertData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMappedEvent(LiveClient client, TikTokWebsocketMessageEvent messageEvent) {
|
|
||||||
var event = messageEvent.getEvent();
|
|
||||||
var eventName = event.getClass().getSimpleName();
|
|
||||||
|
|
||||||
var filter = dataCollectorModel.getEventsFilter();
|
|
||||||
|
|
||||||
if (filter.isEmpty()) {
|
|
||||||
var data = createEventData(event, client.getRoomInfo().getHostName());
|
|
||||||
tikTokDatabase.insertData(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filter.contains(eventName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var data = createEventData(event, client.getRoomInfo().getHostName());
|
|
||||||
tikTokDatabase.insertData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleError(LiveClient client, TikTokErrorEvent event) {
|
|
||||||
var exception = event.getException();
|
|
||||||
var userName = client.getRoomInfo().getHostName();
|
|
||||||
var exceptionContent = ExceptionInfoModel.getStackTraceAsString(exception);
|
|
||||||
var errorModel = new TikTokErrorModel();
|
|
||||||
if (exception instanceof TikTokLiveMessageException ex) {
|
|
||||||
errorModel.setHostName(userName);
|
|
||||||
errorModel.setErrorName(ex.messageMethod());
|
|
||||||
errorModel.setErrorType("error-message");
|
|
||||||
errorModel.setExceptionContent(exceptionContent);
|
|
||||||
errorModel.setMessage(ex.messageToBase64());
|
|
||||||
errorModel.setResponse(ex.webcastResponseToBase64());
|
|
||||||
} else {
|
|
||||||
errorModel.setHostName(userName);
|
|
||||||
errorModel.setErrorName(exception.getClass().getSimpleName());
|
|
||||||
errorModel.setErrorType("error-system");
|
|
||||||
errorModel.setExceptionContent(exceptionContent);
|
|
||||||
errorModel.setMessage("");
|
|
||||||
errorModel.setResponse("");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tikTokDatabase.insertError(errorModel);
|
|
||||||
client.getLogger().info("ERROR: " + errorModel.getErrorName());
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TikTokDataTable createHttpResponseData(TikTokHttpResponseEvent response, String tiktokUser) {
|
|
||||||
var base64 = JsonUtil.toJson(response);
|
|
||||||
var data = new TikTokDataTable();
|
|
||||||
data.setSessionTag(dataCollectorModel.getSessionTag());
|
|
||||||
data.setTiktokUser(tiktokUser);
|
|
||||||
data.setDataType("response");
|
|
||||||
data.setDataTypeName("Http");
|
|
||||||
data.setContent(base64);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private TikTokDataTable createResponseData(WebcastResponse response, String tiktokUser) {
|
|
||||||
var base64 = Base64.getEncoder().encodeToString(response.toByteArray());
|
|
||||||
var data = new TikTokDataTable();
|
|
||||||
data.setSessionTag(dataCollectorModel.getSessionTag());
|
|
||||||
data.setTiktokUser(tiktokUser);
|
|
||||||
data.setDataType("response");
|
|
||||||
data.setDataTypeName("WebcastResponse");
|
|
||||||
data.setContent(base64);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TikTokDataTable createMessageData(WebcastResponse.Message message, String tiktokUser) {
|
|
||||||
var base64 = Base64.getEncoder().encodeToString(message.getPayload().toByteArray());
|
|
||||||
var data = new TikTokDataTable();
|
|
||||||
data.setSessionTag(dataCollectorModel.getSessionTag());
|
|
||||||
data.setTiktokUser(tiktokUser);
|
|
||||||
data.setDataType("message");
|
|
||||||
data.setDataTypeName(message.getMethod());
|
|
||||||
data.setContent(base64);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TikTokDataTable createEventData(TikTokEvent event, String tiktokUser) {
|
|
||||||
var base64 = JsonUtil.toJson(event);
|
|
||||||
var data = new TikTokDataTable();
|
|
||||||
data.setSessionTag(dataCollectorModel.getSessionTag());
|
|
||||||
data.setTiktokUser(tiktokUser);
|
|
||||||
data.setDataType("event");
|
|
||||||
data.setDataTypeName(event.getClass().getSimpleName());
|
|
||||||
data.setContent(base64);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.collector.client;
|
|
||||||
|
|
||||||
import com.google.protobuf.GeneratedMessageV3;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollectorBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollector;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.TikTokDataCollectorModel;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class TikTokDataCollectorBuilder implements DataCollectorBuilder {
|
|
||||||
|
|
||||||
|
|
||||||
TikTokDataCollectorModel dataModel;
|
|
||||||
|
|
||||||
TikTokDatabase database;
|
|
||||||
|
|
||||||
public TikTokDataCollectorBuilder(String outputName) {
|
|
||||||
|
|
||||||
dataModel = new TikTokDataCollectorModel();
|
|
||||||
dataModel.setOutputName(outputName);
|
|
||||||
dataModel.setUsers(new ArrayList<>());
|
|
||||||
dataModel.setEventsFilter(new HashSet<>());
|
|
||||||
dataModel.setMessagesFilter(new HashSet<>());
|
|
||||||
dataModel.setOutputPath("...");
|
|
||||||
dataModel.setOnConfigureLiveClient((e) -> {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollectorBuilder addUser(String user) {
|
|
||||||
dataModel.getUsers().add(user);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TikTokDataCollectorBuilder addMessageFilter(Class<? extends GeneratedMessageV3> message) {
|
|
||||||
dataModel.getMessagesFilter().add(message.getSimpleName());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TikTokDataCollectorBuilder addMessageFilter(String message) {
|
|
||||||
dataModel.getMessagesFilter().add(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TikTokDataCollectorBuilder addEventFilter(Class<? extends TikTokEvent> event) {
|
|
||||||
dataModel.getEventsFilter().add(event.getSimpleName());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TikTokDataCollectorBuilder addEventFilter(String event) {
|
|
||||||
dataModel.getEventsFilter().add(event);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollectorBuilder setOutputPath(String path) {
|
|
||||||
dataModel.setOutputPath(path);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollectorBuilder setSessionTag(String sessionTimestamp) {
|
|
||||||
dataModel.setSessionTag(sessionTimestamp);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollectorBuilder setDatabase(TikTokDatabase database)
|
|
||||||
{
|
|
||||||
this.database =database;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollectorBuilder configureLiveClient(Consumer<LiveClientBuilder> consumer) {
|
|
||||||
dataModel.setOnConfigureLiveClient(consumer);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollector buildAndRun() {
|
|
||||||
|
|
||||||
var collector = build();
|
|
||||||
collector.connect();
|
|
||||||
return collector;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataCollector build() {
|
|
||||||
|
|
||||||
if (dataModel.getSessionTag().isEmpty()) {
|
|
||||||
dataModel.setSessionTag(UUID.randomUUID().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(database == null)
|
|
||||||
{
|
|
||||||
database = new TikTokDatabase(dataModel.getOutputName());
|
|
||||||
}
|
|
||||||
var dataCollector = new TikTokDataCollector(dataModel, database);
|
|
||||||
return dataCollector;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db;
|
|
||||||
|
|
||||||
public class SqlConsts
|
|
||||||
{
|
|
||||||
|
|
||||||
public static String CREATE_DATA_TABLE = """
|
|
||||||
CREATE TABLE IF NOT EXISTS TikTokData (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
sessionTag TEXT,
|
|
||||||
tiktokUser TEXT,
|
|
||||||
dataType TEXT,
|
|
||||||
dataTypeName TEXT,
|
|
||||||
content TEXT,
|
|
||||||
createdAt TEXT
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
public static String CREATE_ERROR_TABLE = """
|
|
||||||
CREATE TABLE IF NOT EXISTS TikTokErrorModel (
|
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
hostName VARCHAR(255),
|
|
||||||
errorName VARCHAR(255),
|
|
||||||
errorType VARCHAR(255),
|
|
||||||
exceptionContent TEXT,
|
|
||||||
message TEXT,
|
|
||||||
response TEXT,
|
|
||||||
createdAt DATETIME
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
public static String CREATE_RESPONSE_MODEL = """
|
|
||||||
CREATE TABLE IF NOT EXISTS TikTokResponseModel (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
hostName TEXT,
|
|
||||||
response TEXT,
|
|
||||||
createdAt TEXT
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
|
||||||
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
|
|
||||||
import org.jdbi.v3.sqlobject.customizer.Bind;
|
|
||||||
import org.jdbi.v3.sqlobject.customizer.BindBean;
|
|
||||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
|
||||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@RegisterBeanMapper(TikTokDataTable.class)
|
|
||||||
public interface TikTokDataTableDAO {
|
|
||||||
String query = """
|
|
||||||
INSERT INTO TikTokData (sessionTag, tiktokUser, dataType, dataTypeName, content, createdAt) VALUES (:sessionTag, :tiktokUser, :dataType, :dataTypeName, :content, :createdAt)
|
|
||||||
""";
|
|
||||||
|
|
||||||
@SqlUpdate(query)
|
|
||||||
void insertData(@BindBean TikTokDataTable data);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokData WHERE sessionTag = :sessionTag")
|
|
||||||
List<TikTokDataTable> selectBySession(@Bind("sessionTag") String sessionTag);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokData WHERE dataType = :dataType AND sessionTag = :sessionTag AND tiktokUser = :tiktokUser")
|
|
||||||
List<TikTokDataTable> selectSessionData(@Bind("dataType") String dataType,
|
|
||||||
@Bind("sessionTag") String sessionTag,
|
|
||||||
@Bind("tiktokUser") String user);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokData WHERE sessionTag = :sessionTag AND tiktokUser = :tiktokUser AND dataType = \"response\"")
|
|
||||||
List<TikTokDataTable> selectResponces(@Bind("sessionTag") String sessionTag, @Bind("tiktokUser") String user);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokData WHERE sessionTag = :sessionTag AND tiktokUser = :tiktokUser AND dataType = \"event\"")
|
|
||||||
List<TikTokDataTable> selectBySessionEvents(@Bind("sessionTag") String sessionTag, @Bind("tiktokUser") String userName);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokData WHERE sessionTag = :sessionTag AND tiktokUser = :tiktokUser AND dataType = \"message\"")
|
|
||||||
List<TikTokDataTable> selectBySessionMessages(@Bind("sessionTag") String sessionTag, @Bind("tiktokUser") String userName);
|
|
||||||
|
|
||||||
|
|
||||||
@SqlQuery("SELECT tiktokUser FROM TikTokData GROUP BY tiktokUser")
|
|
||||||
List<String> getUsers();
|
|
||||||
|
|
||||||
|
|
||||||
@SqlQuery("SELECT sessionTag FROM TikTokData WHERE tiktokUser = :tiktokUser GROUP BY sessionTag")
|
|
||||||
List<String> getSessionTagByUser(@Bind("tiktokUser") String tiktokUser);
|
|
||||||
|
|
||||||
String groupByDataTypeNameQuery = """
|
|
||||||
SELECT dataTypeName, COUNT(*) as count
|
|
||||||
FROM TikTokData
|
|
||||||
WHERE dataType = 'message' AND sessionTag = :sessionTag AND tiktokUser = :userName
|
|
||||||
GROUP BY dataTypeName
|
|
||||||
""";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokErrorModel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.jdbi.v3.core.Jdbi;
|
|
||||||
import org.jdbi.v3.sqlobject.SqlObjectPlugin;
|
|
||||||
import org.sqlite.SQLiteConfig;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TikTokDatabase {
|
|
||||||
private final String database;
|
|
||||||
|
|
||||||
private TikTokErrorModelDAO errorTable;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private TikTokDataTableDAO dataTableDAO;
|
|
||||||
|
|
||||||
private Connection connection;
|
|
||||||
|
|
||||||
|
|
||||||
public TikTokDatabase(String database) {
|
|
||||||
this.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConnected()
|
|
||||||
{
|
|
||||||
return connection != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect() throws SQLException {
|
|
||||||
var jdbcUrl = "jdbc:sqlite:" + database + ".db";
|
|
||||||
var config = new SQLiteConfig();
|
|
||||||
config.setEncoding(SQLiteConfig.Encoding.UTF8);
|
|
||||||
connection = DriverManager.getConnection(jdbcUrl, config.toProperties());
|
|
||||||
var jdbi = Jdbi.create(jdbcUrl).installPlugin(new SqlObjectPlugin());
|
|
||||||
jdbi.useHandle(handle -> {
|
|
||||||
handle.execute(SqlConsts.CREATE_DATA_TABLE);
|
|
||||||
handle.execute(SqlConsts.CREATE_ERROR_TABLE);
|
|
||||||
});
|
|
||||||
dataTableDAO = jdbi.onDemand(TikTokDataTableDAO.class);
|
|
||||||
errorTable = jdbi.onDemand(TikTokErrorModelDAO.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws SQLException {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertData(TikTokDataTable tikTokDataTable) {
|
|
||||||
tikTokDataTable.setCreatedAt(getTime());
|
|
||||||
dataTableDAO.insertData(tikTokDataTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TikTokDataTable> getSessionResponces(String sessionTag, String userName) {
|
|
||||||
return dataTableDAO.selectResponces(sessionTag, userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getDataNames(String dataType, String sessionTag, String userName) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.append("""
|
|
||||||
SELECT dataTypeName, COUNT(*) as count
|
|
||||||
FROM TikTokData
|
|
||||||
""");
|
|
||||||
sb.append(" WHERE dataType = \""+dataType+"\" ");
|
|
||||||
sb.append(" AND tiktokUser = \"" + userName + "\" ");
|
|
||||||
sb.append(" AND sessionTag = \"" + sessionTag + "\" ");
|
|
||||||
sb.append("GROUP BY dataTypeName");
|
|
||||||
var statement = connection.prepareStatement(sb.toString());
|
|
||||||
var resultSet = statement.executeQuery();
|
|
||||||
List<String> dataTypeCounts = new ArrayList<>();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
var dataTypeName = resultSet.getString("dataTypeName");
|
|
||||||
dataTypeCounts.add(dataTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
resultSet.close();
|
|
||||||
statement.close();
|
|
||||||
|
|
||||||
return dataTypeCounts;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return List.of("error");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<TikTokDataTable> getSessionMessages(String sessionTag, String userName, int count) {
|
|
||||||
return dataTableDAO.selectBySessionMessages(sessionTag, userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertError(TikTokErrorModel message) {
|
|
||||||
message.setCreatedAt(getTime());
|
|
||||||
errorTable.insertTikTokMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<TikTokErrorModel> selectErrors() {
|
|
||||||
return errorTable.selectErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTime() {
|
|
||||||
return new SimpleDateFormat("dd:MM:yyyy HH:mm:ss.SSS").format(new Date());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokErrorModel;
|
|
||||||
|
|
||||||
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
|
|
||||||
import org.jdbi.v3.sqlobject.customizer.BindBean;
|
|
||||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
|
||||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
@RegisterBeanMapper(TikTokErrorModel.class)
|
|
||||||
public interface TikTokErrorModelDAO
|
|
||||||
{
|
|
||||||
@SqlUpdate("INSERT INTO TikTokErrorModel (hostName, errorName, errorType, exceptionContent, message, response, createdAt) " +
|
|
||||||
"VALUES (:hostName, :errorName, :errorType, :exceptionContent, :message, :response, :createdAt)")
|
|
||||||
void insertTikTokMessage(@BindBean TikTokErrorModel message);
|
|
||||||
|
|
||||||
@SqlQuery("SELECT * FROM TikTokErrorModel")
|
|
||||||
List<TikTokErrorModel> selectErrors();
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db.tables;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
public class ExceptionInfoModel
|
|
||||||
{
|
|
||||||
private String message;
|
|
||||||
private String stackTrace;
|
|
||||||
|
|
||||||
public ExceptionInfoModel(Throwable throwable) {
|
|
||||||
this.message = throwable.getMessage();
|
|
||||||
this.stackTrace = getStackTraceAsString(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getStackTraceAsString(Throwable throwable) {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
throwable.printStackTrace(pw);
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters for message and stackTrace
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStackTrace() {
|
|
||||||
return stackTrace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.db.tables;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class TikTokErrorModel
|
|
||||||
{
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
private String hostName;
|
|
||||||
|
|
||||||
private String errorName;
|
|
||||||
|
|
||||||
private String errorType;
|
|
||||||
|
|
||||||
private String exceptionContent;
|
|
||||||
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
private String response;
|
|
||||||
|
|
||||||
private String createdAt;
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester;
|
|
||||||
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.TikTokLiveMock;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks.LiveClientMock;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.util.MessageUtil;
|
|
||||||
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class RunJsonTester {
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
var messages = getMessages();
|
|
||||||
var client =(LiveClientMock) TikTokLiveMock.create()
|
|
||||||
.onWebsocketUnhandledMessage((liveClient, event) ->
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.append("Unhandled Message! " );
|
|
||||||
sb.append(event.getData().getMethod());
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append(MessageUtil.getContent(event.getData()));
|
|
||||||
|
|
||||||
|
|
||||||
// liveClient.getLogger().info(sb.toString());
|
|
||||||
}).
|
|
||||||
onGift((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Gift event: "+event.toJson());
|
|
||||||
})
|
|
||||||
.onGiftCombo((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("GiftCombo event"+event.toJson());
|
|
||||||
})
|
|
||||||
.onError((liveClient, event) ->
|
|
||||||
{
|
|
||||||
event.getException().printStackTrace();
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
for(var msg : messages.entrySet())
|
|
||||||
{
|
|
||||||
for(var content : msg.getValue())
|
|
||||||
{
|
|
||||||
client.publishMessage(msg.getKey(),content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
client.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Map<String, List<String>> getMessages() throws IOException {
|
|
||||||
var path = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-EventsCollector\\src\\main\\resources\\log.json";
|
|
||||||
var jsonElement = JsonParser.parseReader(new FileReader(path, Charset.defaultCharset()));
|
|
||||||
|
|
||||||
var res = new HashMap<String, List<String>>();
|
|
||||||
if (jsonElement.isJsonObject()) {
|
|
||||||
var jsonObject = jsonElement.getAsJsonObject();
|
|
||||||
var keys = jsonObject.keySet();
|
|
||||||
for (String key : keys) {
|
|
||||||
var messages = jsonObject.get(key).getAsJsonArray();
|
|
||||||
for (var msg : messages) {
|
|
||||||
var data = msg.getAsJsonObject().get("eventData").getAsString();
|
|
||||||
res.computeIfAbsent(key, s -> new ArrayList<>()).add(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTester;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTesterModel;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.TikTokLiveMock;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks.LiveClientMock;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
public class TikTokDataTester implements DataTester {
|
|
||||||
private DataTesterModel model;
|
|
||||||
|
|
||||||
private LiveClientMock client;
|
|
||||||
|
|
||||||
private Queue<TikTokDataTable> data;
|
|
||||||
|
|
||||||
private TikTokDatabase database;
|
|
||||||
|
|
||||||
public TikTokDataTester(DataTesterModel model) {
|
|
||||||
this.model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect() {
|
|
||||||
|
|
||||||
try {
|
|
||||||
database = new TikTokDatabase(model.getDatabaseName());
|
|
||||||
database.connect();
|
|
||||||
var mockBuilder = TikTokLiveMock.create();
|
|
||||||
model.getBuilderConsumer().accept(mockBuilder);
|
|
||||||
client = mockBuilder.build();
|
|
||||||
var respocnes = database.getSessionResponces(model.getSessionTag(), model.getUser());
|
|
||||||
data = new LinkedList<>(respocnes);
|
|
||||||
client.connect();
|
|
||||||
while (!data.isEmpty()) {
|
|
||||||
nextResponse();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error while running tester", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void nextResponse() {
|
|
||||||
try {
|
|
||||||
var responce = data.poll();
|
|
||||||
client.publishResponse(responce.getContent());
|
|
||||||
Thread.sleep(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to run response!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disconnect() {
|
|
||||||
|
|
||||||
try {
|
|
||||||
client.disconnect();
|
|
||||||
database.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTester;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTesterBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.api.DataTesterModel;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class TikTokDataTesterBuilder implements DataTesterBuilder {
|
|
||||||
private final DataTesterModel model;
|
|
||||||
|
|
||||||
public TikTokDataTesterBuilder(String databaseName) {
|
|
||||||
this.model = new DataTesterModel();
|
|
||||||
this.model.setDatabaseName(databaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataTesterBuilder setSessionTag(String sessionTag) {
|
|
||||||
model.setSessionTag(sessionTag);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataTesterBuilder setUser(String user) {
|
|
||||||
model.setUser(user);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataTesterBuilder configureLiveClient(Consumer<LiveClientBuilder> builderConsumer) {
|
|
||||||
model.setBuilderConsumer(builderConsumer);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataTester build() {
|
|
||||||
return new TikTokDataTester(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataTester buildAndRun()
|
|
||||||
{
|
|
||||||
var tester = build();
|
|
||||||
tester.connect();
|
|
||||||
return tester;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.api;
|
|
||||||
|
|
||||||
public interface DataTester
|
|
||||||
{
|
|
||||||
void connect();
|
|
||||||
|
|
||||||
void nextResponse();
|
|
||||||
|
|
||||||
void disconnect();
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.api;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface DataTesterBuilder {
|
|
||||||
|
|
||||||
DataTesterBuilder setSessionTag(String sessionTag);
|
|
||||||
|
|
||||||
DataTesterBuilder setUser(String user);
|
|
||||||
|
|
||||||
DataTesterBuilder configureLiveClient(Consumer<LiveClientBuilder> builderConsumer);
|
|
||||||
|
|
||||||
DataTester build();
|
|
||||||
|
|
||||||
DataTester buildAndRun();
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.api;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class DataTesterModel {
|
|
||||||
|
|
||||||
|
|
||||||
String databaseName;
|
|
||||||
String sessionTag;
|
|
||||||
String user;
|
|
||||||
Consumer<LiveClientBuilder> builderConsumer = (a) -> {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.mockClient;
|
|
||||||
|
|
||||||
public class TikTokLiveMock
|
|
||||||
{
|
|
||||||
public static TikTokMockBuilder create(String host)
|
|
||||||
{
|
|
||||||
return new TikTokMockBuilder(host);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TikTokMockBuilder create()
|
|
||||||
{
|
|
||||||
return create("MockHostName");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.mockClient;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveClientBuilder;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
|
||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveMessageHandler;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveHttpClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks.LiveClientMock;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks.WebsocketClientMock;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
|
|
||||||
public class TikTokMockBuilder extends TikTokLiveClientBuilder {
|
|
||||||
|
|
||||||
Stack<WebcastResponse> responses;
|
|
||||||
|
|
||||||
public TikTokMockBuilder(String userName) {
|
|
||||||
super(userName);
|
|
||||||
responses = new Stack<>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokMockBuilder addResponse(String value) {
|
|
||||||
var bytes = Base64.getDecoder().decode(value);
|
|
||||||
return addResponse(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokMockBuilder addResponses(List<String> values) {
|
|
||||||
for (var value : values) {
|
|
||||||
try {
|
|
||||||
addResponse(value);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new TikTokLiveException(value, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokMockBuilder addResponse(byte[] bytes) {
|
|
||||||
try {
|
|
||||||
var response = WebcastResponse.parseFrom(bytes);
|
|
||||||
return addResponse(response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to parse response from bytes", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TikTokMockBuilder addResponse(WebcastResponse message) {
|
|
||||||
responses.push(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LiveClientMock build() {
|
|
||||||
validate();
|
|
||||||
|
|
||||||
var tiktokRoomInfo = new TikTokRoomInfo();
|
|
||||||
tiktokRoomInfo.setHostName(clientSettings.getHostName());
|
|
||||||
|
|
||||||
var listenerManager = new TikTokListenersManager(listeners, tikTokEventHandler);
|
|
||||||
var mapper = createMapper(new TikTokGiftsManager(List.of()), tiktokRoomInfo);
|
|
||||||
var handler = new TikTokLiveMessageHandler(tikTokEventHandler, mapper);
|
|
||||||
var webSocketClient = new WebsocketClientMock(logger, responses, handler);
|
|
||||||
|
|
||||||
return new LiveClientMock(tiktokRoomInfo,
|
|
||||||
new TikTokLiveHttpClient(),
|
|
||||||
webSocketClient,
|
|
||||||
tikTokEventHandler,
|
|
||||||
clientSettings,
|
|
||||||
listenerManager,
|
|
||||||
logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LiveClientMock buildAndConnect() {
|
|
||||||
var client = build();
|
|
||||||
client.connect();
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveEventHandler;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveHttpClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class LiveClientMock extends TikTokLiveClient {
|
|
||||||
|
|
||||||
private final WebsocketClientMock websocketClientMock;
|
|
||||||
|
|
||||||
public LiveClientMock(
|
|
||||||
TikTokRoomInfo tikTokLiveMeta,
|
|
||||||
TikTokLiveHttpClient httpClient,
|
|
||||||
WebsocketClientMock webSocketClient,
|
|
||||||
TikTokLiveEventHandler tikTokEventHandler,
|
|
||||||
LiveClientSettings clientSettings,
|
|
||||||
TikTokListenersManager listenersManager,
|
|
||||||
Logger logger) {
|
|
||||||
super(
|
|
||||||
new TikTokGiftsManager(List.of()),
|
|
||||||
tikTokLiveMeta,
|
|
||||||
httpClient,
|
|
||||||
webSocketClient,
|
|
||||||
tikTokEventHandler,
|
|
||||||
clientSettings,
|
|
||||||
listenersManager,
|
|
||||||
logger);
|
|
||||||
this.websocketClientMock = webSocketClient;
|
|
||||||
websocketClientMock.setClient(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void publishMessage(String type, String base64) {
|
|
||||||
websocketClientMock.addMessage(type, base64);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publishMessage(Class<?> clazz, String base64) {
|
|
||||||
websocketClientMock.addMessage(clazz.getSimpleName(), base64);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publishResponse(String value) {
|
|
||||||
websocketClientMock.addResponse(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publishResponse(byte[] bytes) {
|
|
||||||
websocketClientMock.addResponse(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publishResponse(WebcastResponse message) {
|
|
||||||
websocketClientMock.addResponse(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.tester.mockClient.mocks;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLiveMessageHandler;
|
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
public class WebsocketClientMock implements SocketClient {
|
|
||||||
Logger logger;
|
|
||||||
Stack<WebcastResponse> responses;
|
|
||||||
Stack<MsgStruct> messages;
|
|
||||||
TikTokLiveMessageHandler messageHandler;
|
|
||||||
|
|
||||||
LiveClient client;
|
|
||||||
|
|
||||||
Thread thread;
|
|
||||||
|
|
||||||
private boolean isRunning;
|
|
||||||
|
|
||||||
public void setClient(LiveClientMock liveClientMock) {
|
|
||||||
this.client = liveClientMock;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public static class MsgStruct {
|
|
||||||
String messageType;
|
|
||||||
byte[] messageValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebsocketClientMock(Logger logger, Stack<WebcastResponse> responses, TikTokLiveMessageHandler messageHandler) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.responses = responses;
|
|
||||||
this.messageHandler = messageHandler;
|
|
||||||
messages = new Stack<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebsocketClientMock addMessage(String type, String value) {
|
|
||||||
var bytes = Base64.getDecoder().decode(value);
|
|
||||||
messages.push(new MsgStruct(type, bytes));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebsocketClientMock addResponse(String value) {
|
|
||||||
var bytes = Base64.getDecoder().decode(value);
|
|
||||||
return addResponse(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebsocketClientMock addResponse(byte[] bytes) {
|
|
||||||
try {
|
|
||||||
var response = WebcastResponse.parseFrom(bytes);
|
|
||||||
return addResponse(response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unable to parse response from bytes", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebsocketClientMock addResponse(WebcastResponse message) {
|
|
||||||
responses.push(message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(LiveConnectionData.Response webcastResponse, LiveClient tikTokLiveClient) {
|
|
||||||
logger.info("Running message: " + responses.size());
|
|
||||||
|
|
||||||
|
|
||||||
thread = new Thread(() ->
|
|
||||||
{
|
|
||||||
|
|
||||||
while (isRunning)
|
|
||||||
{
|
|
||||||
while (!responses.isEmpty()) {
|
|
||||||
var response = responses.pop();
|
|
||||||
messageHandler.handle(client, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
isRunning = true;
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() {
|
|
||||||
isRunning = false;
|
|
||||||
thread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.tools.util;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.ProtocolUtils;
|
|
||||||
|
|
||||||
public class MessageUtil {
|
|
||||||
public static String getContent(WebcastResponse.Message message) {
|
|
||||||
try {
|
|
||||||
var methodName = message.getMethod();
|
|
||||||
var inputClazz = Class.forName("io.github.jwdeveloper.tiktok.messages.webcast." + methodName);
|
|
||||||
var parseMethod = inputClazz.getDeclaredMethod("parseFrom", ByteString.class);
|
|
||||||
var webcastObject = parseMethod.invoke(null, message.getPayload());
|
|
||||||
return JsonUtil.messageToJson(webcastObject);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
|
|
||||||
return ConsoleColors.RED + "Can not find mapper for " + message.getMethod();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getContent(String messageName, byte[] bytes) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
var inputClazz = Class.forName("io.github.jwdeveloper.tiktok.messages.webcast." + messageName);
|
|
||||||
var parseMethod = inputClazz.getDeclaredMethod("parseFrom", byte[].class);
|
|
||||||
var deserialized = parseMethod.invoke(null, bytes);
|
|
||||||
|
|
||||||
return JsonUtil.messageToJson(deserialized);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.append("Can not find protocol-buffer file message representation for " + messageName);
|
|
||||||
sb.append("\n");
|
|
||||||
var structure = ProtocolUtils.getProtocolBufferStructure(bytes);
|
|
||||||
var json =structure.toJson();
|
|
||||||
sb.append(json);
|
|
||||||
//String jsonString = JsonFormat.printToString(protobufData);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,264 +0,0 @@
|
|||||||
{
|
|
||||||
"RoomMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQmofs1NO1z8sXGKGW59iz55WpZSDxhpnNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:06:35.153694400"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQjPTq1re3z8sXGKGW59iz55WpZSCI5ZzNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:07:36.360859900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQocTpm8nCz8sXGKGW59iz55WpZSDSkrTNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:13:58.969658600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CioKDVN5c3RlbU1lc3NhZ2UQ8a6h9abiz8sXGKGW59iz55WpZSDS2PbNvDESuQFXZWxjb21lIHRvIFRpa1RvayBMSVZFISBIYXZlIGZ1biBpbnRlcmFjdGluZyB3aXRoIHRoZSBMSVZFIGNyZWF0b3IgYW5kIG90aGVyIHZpZXdlcnMgaW4gcmVhbCB0aW1lIGFuZCByZW1lbWJlciB0byBjcmVhdGUgYSBzYWZlIHZpZXdpbmcgZXhwZXJpZW5jZSBieSBmb2xsb3dpbmcgb3VyIENvbW11bml0eSBHdWlkZWxpbmVzLjgB",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:32:09.427463"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"WebcastChatMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglqWQ1+2VqWUYoZbn2LPnlallIMjgmc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAerYmc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ8LqSkbvBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ4/2WkbvBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDw5/SVu8GCA5oBGgoOdGltZXN0YW1wX2Rlc2MQkMWV28rtzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkdSYkbvBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7S95W7wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ8Jv+qLvBggOaARYKC3YxM19yNzEyMDg4EPCb/qi7wYIDmgEWCgt2MTJfcjcwMjA3NRDwm/6ou8GCA5oBFgoLdjEzX3I3NjUxNjYQ8Jv+qLvBggOaARYKC3YxM19yNzY1MTY3EPCb/qi7wYIDmgEWCgt2MTNfcjc2NTE2ORDwm/6ou8GCA5oBFgoLdjEzX3I3NjcxMjIQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA0EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwNRDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MDYQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA3EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwOBDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MTAQ8Jv+qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDwm/6ou8GCA6IBAQA=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:06:47.126429700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglqWQ1+2VqWUYoZbn2LPnlallIMjgmc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAerYmc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ8LqSkbvBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ4/2WkbvBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDw5/SVu8GCA5oBGgoOdGltZXN0YW1wX2Rlc2MQkMWV28rtzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkdSYkbvBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7S95W7wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ8Jv+qLvBggOaARYKC3YxM19yNzEyMDg4EPCb/qi7wYIDmgEWCgt2MTJfcjcwMjA3NRDwm/6ou8GCA5oBFgoLdjEzX3I3NjUxNjYQ8Jv+qLvBggOaARYKC3YxM19yNzY1MTY3EPCb/qi7wYIDmgEWCgt2MTNfcjc2NTE2ORDwm/6ou8GCA5oBFgoLdjEzX3I3NjcxMjIQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA0EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwNRDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MDYQ8Jv+qLvBggOaARYKC3YxM19yNzcwODA3EPCb/qi7wYIDmgEWCgt2MTNfcjc3MDgwOBDwm/6ou8GCA5oBFgoLdjEzX3I3NzA4MTAQ8Jv+qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDwm/6ou8GCA6IBAQA=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:07:36.364450900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglp7Ix/SVqWUYoZbn2LPnlallIOvxm828MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAfPqm828MRKVCgiFiMi2nP/V4l0aDG5vdGlmaWNhdGlvbkr+BQq6AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPSUyQmRnaCUyRmxmVDNmUm4zZWZtQjMlMkZCSXU0NHJXUSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XRkNLeXMyTVAyMlclMkZGR0lRdzFCMHpIQ1l6RSUzRAqqAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT0lMkZITVJNaEFYQ3lFbXZkbyUyRnB6aVRDNjQ0c2hNJTNECqgBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvODM5MTkxYWVkMjMzNGMxODIxMjVjYzRhMDMzMDRjY2F+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWt2V3FUWmFOclBsTSUyRkVlV2hKakJ5TzkxUG5nJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvODM5MTkxYWVkMjMzNGMxODIxMjVjYzRhMDMzMDRjY2FSjAMKwgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC84MzkxOTFhZWQyMzM0YzE4MjEyNWNjNGEwMzMwNGNjYX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPU5vMWN2RXB2Yno1QXFtTnZmQzh1ZDl0d3hKTSUzRArEAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzgzOTE5MWFlZDIzMzRjMTgyMTI1Y2M0YTAzMzA0Y2NhfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLmpwZWc/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9eEduYkFuVUFFckZKUzFTcW1OME5vJTJGOUVRM1UlM0SyAQgI3QwQ1BEYAboBAIICALICCm5pZXRvcGVyejDyAkxNUzR3TGpBQkFBQUF6emlzM0d0blI4bUJsVEIwQjZCY3RDVHBEd0NrMV9lc1hLckJTZkZOVTRCM0hkYXVESEkxUzl6QTM4TGR0cklWGgVzaWVtYXICcGySAQIgAZoBFAoOdXNlcl90eXBlX3J1bGUQwJoMmgEXChFjb21tdW5pdHktZmxhZ2dlZBCorRqaARoKDmNvbW1lbnRhdG9yX2lkEIWIyLac/9XiXZoBEgoHZGVmYXVsdBDg2uShu8GCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDjsaCku8GCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEMiPx6a7wYIDmgEaCg50aW1lc3RhbXBfZGVzYxC4ncPKyu3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORDhz6Wku8GCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQn7/9qLvBggOaARoKD2lkY19ydWxlX3JlcmFuaxDIw9C5u8GCA5oBFgoLdjEzX3I3MTIwODgQyMPQubvBggOaARYKC3YxMl9yNzAyMDc1EMjD0Lm7wYIDmgEWCgt2MTNfcjc2NTE2NhDIw9C5u8GCA5oBFgoLdjEzX3I3NjUxNjcQyMPQubvBggOaARYKC3YxM19yNzY1MTY5EMjD0Lm7wYIDmgEWCgt2MTNfcjc2NzEyMhDIw9C5u8GCA5oBFgoLdjEzX3I3NzA4MDQQyMPQubvBggOaARYKC3YxM19yNzcwODA1EMjD0Lm7wYIDmgEWCgt2MTNfcjc3MDgwNhDIw9C5u8GCA5oBFgoLdjEzX3I3NzA4MDcQyMPQubvBggOaARYKC3YxM19yNzcwODA4EMjD0Lm7wYIDmgEWCgt2MTNfcjc3MDgxMBDIw9C5u8GCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEMjD0Lm7wYIDogEBAA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:07:36.364951"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlqfexJ+WqWUYoZbn2LPnlallINPCsc28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAcy+sc28MRKfCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvoFCrgBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9eWRWc0c3JTJCYTRUbU9XRXFPSGd6JTJCQmVRU1k2YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT02TVhuNmV6WVQzNHFVY3N1TXFRMUcxMFExZVklM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9ODE0Sk91T0M4ZHlvVGQ5U1Y5TkI3UjZSYjY0JTNECqwBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVhFM0toMjVCeXMwRFUlMkYlMkZVa3JlZCUyQkxadUJ4VSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxUo4DCsIBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIud2VicD94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1DVEs2Ukw2dWVOSlJ6Ujl0cEtKNUYzQW90cEklM0QKxgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi5qcGVnP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPUhUbSUyRjdYQUxBMnNKWSUyQkgxanQxM3pBR0ZzTTAlM0SyAQYIhAUQqBW6AQCCAgCyAg1kb3N0YXdjYXZpZGVv8gJMTVM0d0xqQUJBQUFBcWtGdC1FSmZHNERIVXVZeW1RQnNTX2o2ZHJVaXl0WjMzdEVNeWJ1YUdGLWlYejdfV1lJcF9qRDRwSUNWTWp3ZBoDYXNkcgJ6aJIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkENm32gGaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCwxunKvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj2JLLvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEJj7y8+8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxDosb6hye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCRr5TLvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ7q3zz7zBggOaARoKD2lkY19ydWxlX3JlcmFuaxCYr9XivMGCA5oBFgoLdjEzX3I3MTIwODgQmK/V4rzBggOaARYKC3YxMl9yNzAyMDc1EJiv1eK8wYIDmgEWCgt2MTNfcjc2NTE2NhCYr9XivMGCA5oBFgoLdjEzX3I3NjUxNjcQmK/V4rzBggOaARYKC3YxM19yNzY1MTY5EJiv1eK8wYIDmgEWCgt2MTNfcjc2NzEyMhCYr9XivMGCA5oBFgoLdjEzX3I3NzA4MDQQmK/V4rzBggOaARYKC3YxM19yNzcwODA1EJiv1eK8wYIDmgEWCgt2MTNfcjc3MDgwNhCYr9XivMGCA5oBFgoLdjEzX3I3NzA4MDcQmK/V4rzBggOaARYKC3YxM19yNzcwODA4EJiv1eK8wYIDmgEWCgt2MTNfcjc3MDgxMBCYr9XivMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEJiv1eK8wYIDogEBAA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:13:58.973166900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlt6SlaOWqWUYoZbn2LPnlallIMLsss28MTABSAJQAnoIdXNlYXN0MmGwAQG4AQLAAQLIAY7pss28MRKZCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvQFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9ODE0Sk91T0M4ZHlvVGQ5U1Y5TkI3UjZSYjY0JTNECqYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTZNWG42ZXpZVDM0cVVjc3VNcVExRzEwUTFlWSUzRAqoAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YTll0ZU5yaXVjcjJSeGZDVEdZR1JHJTJGNXZTYyUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxUo4DCsIBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIud2VicD94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1DVEs2Ukw2dWVOSlJ6Ujl0cEtKNUYzQW90cEklM0QKxgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX50cGx2LXRpa3Rva3gtY29tcHJlc3NfcXVhbGl0eV8zMDo3Mjo3Mi5qcGVnP3gtZXhwaXJlcz0xNjk5OTE2NDAwJngtc2lnbmF0dXJlPUhUbSUyRjdYQUxBMnNKWSUyQkgxanQxM3pBR0ZzTTAlM0SyAQYIhAUQqBW6AQCCAgCyAg1kb3N0YXdjYXZpZGVv8gJMTVM0d0xqQUJBQUFBcWtGdC1FSmZHNERIVXVZeW1RQnNTX2o2ZHJVaXl0WjMzdEVNeWJ1YUdGLWlYejdfV1lJcF9qRDRwSUNWTWp3ZBoDYXNkcgJ6aJIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkENm32gGaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCY3pnVvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj37nZvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEICT/Nm8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxCAmo6Xye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCRtrvZvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ7rSa3rzBggOaARoKD2lkY19ydWxlX3JlcmFuaxCAx4XtvMGCA5oBFgoLdjEzX3I3MTIwODgQgMeF7bzBggOaARYKC3YxMl9yNzAyMDc1EIDHhe28wYIDmgEWCgt2MTNfcjc2NTE2NhCAx4XtvMGCA5oBFgoLdjEzX3I3NjUxNjcQgMeF7bzBggOaARYKC3YxM19yNzY1MTY5EIDHhe28wYIDmgEWCgt2MTNfcjc2NzEyMhCAx4XtvMGCA5oBFgoLdjEzX3I3NzA4MDQQgMeF7bzBggOaARYKC3YxM19yNzcwODA1EIDHhe28wYIDmgEWCgt2MTNfcjc3MDgwNhCAx4XtvMGCA5oBFgoLdjEzX3I3NzA4MDcQgMeF7bzBggOaARYKC3YxM19yNzcwODA4EIDHhe28wYIDmgEWCgt2MTNfcjc3MDgxMBCAx4XtvMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEIDHhe28wYIDogEBAA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:13:58.974165"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRCglq+yx6aWqWUYoZbn2LPnlallIIPXtM28MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAa7StM28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaCGFkYXNkYXNkcgJ0cpIBAjABmgEUCg51c2VyX3R5cGVfcnVsZRCgwh6aARgKEWNvbW11bml0eS1mbGFnZ2VkEPzApwOaARoKDmNvbW1lbnRhdG9yX2lkEIWIpfSAjYWWYJoBEgoHZGVmYXVsdBCIjsPjvMGCA5oBEAoLZGVmYXVsdF9hcHAQkE6aAREKBnJhbmtWMxDj5uDnvMGCA5oBGgoPdHRwX3J1bGVfcmVyYW5rEIi7pei8wYIDmgEaCg50aW1lc3RhbXBfZGVzYxD48eSIye3OrgGaATUKKnRpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2ORCam+PnvMGCA5oBOgovdGlrY2FzdF9jb21tdW5pdHlfY29tbWVudF8xODg2Nl92N19yNjU1MDY5X2Rlc2MQ5d3A7LzBggOaARoKD2lkY19ydWxlX3JlcmFuaxCI7677vMGCA5oBFgoLdjEzX3I3MTIwODgQiO+u+7zBggOaARYKC3YxMl9yNzAyMDc1EIjvrvu8wYIDmgEWCgt2MTNfcjc2NTE2NhCI7677vMGCA5oBFgoLdjEzX3I3NjUxNjcQiO+u+7zBggOaARYKC3YxM19yNzY1MTY5EIjvrvu8wYIDmgEWCgt2MTNfcjc2NzEyMhCI7677vMGCA5oBFgoLdjEzX3I3NzA4MDQQiO+u+7zBggOaARYKC3YxM19yNzcwODA1EIjvrvu8wYIDmgEWCgt2MTNfcjc3MDgwNhCI7677vMGCA5oBFgoLdjEzX3I3NzA4MDcQiO+u+7zBggOaARYKC3YxM19yNzcwODA4EIjvrvu8wYIDmgEWCgt2MTNfcjc3MDgxMBCI7677vMGCA5oBGgoPaWRjX3J1bGVfcmVyYW5rEPD2rvu8wYIDogEBAA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:14:07.736142"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "ClAKEldlYmNhc3RDaGF0TWVzc2FnZRChlqWizKeWqWUYoZbn2LPnlallIN7Htc28MTABSAJQAnoIdXNlYXN0MmGwAQK4AQLAAQLIAafEtc28MRKdCgiFiKX0gI2FlmAaF/CfkoAgUG9yYSB1bWllcmHEhyDwn5KASvgFCrYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9dklLVGljWFYwZEdmZmdNa0QzYzJvU1BEJTJGbjAlM0QKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMVKOAwrCAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfnRwbHYtdGlrdG9reC1jb21wcmVzc19xdWFsaXR5XzMwOjcyOjcyLndlYnA/eC1leHBpcmVzPTE2OTk5MTY0MDAmeC1zaWduYXR1cmU9Q1RLNlJMNnVlTkpSelI5dHBLSjVGM0FvdHBJJTNECsYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+dHBsdi10aWt0b2t4LWNvbXByZXNzX3F1YWxpdHlfMzA6NzI6NzIuanBlZz94LWV4cGlyZXM9MTY5OTkxNjQwMCZ4LXNpZ25hdHVyZT1IVG0lMkY3WEFMQTJzSlklMkJIMWp0MTN6QUdGc00wJTNEsgEGCIQFEKgVugEAggIAsgINZG9zdGF3Y2F2aWRlb/ICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QaA2FzZHICemiSAQIwAZoBFAoOdXNlcl90eXBlX3J1bGUQoMIemgEYChFjb21tdW5pdHktZmxhZ2dlZBDZt9oBmgEaCg5jb21tZW50YXRvcl9pZBCFiKX0gI2FlmCaARIKB2RlZmF1bHQQ+K2z6rzBggOaARAKC2RlZmF1bHRfYXBwEJBOmgERCgZyYW5rVjMQ45PD7LzBggOaARoKD3R0cF9ydWxlX3JlcmFuaxDg4pXvvMGCA5oBGgoOdGltZXN0YW1wX2Rlc2MQoMr0gcntzq4BmgE1Cip0aWtjYXN0X2NvbW11bml0eV9jb21tZW50XzE4ODY2X3Y3X3I2NTUwNjkQkerE7LzBggOaAToKL3Rpa2Nhc3RfY29tbXVuaXR5X2NvbW1lbnRfMTg4NjZfdjdfcjY1NTA2OV9kZXNjEO7oo/G8wYIDmgEaCg9pZGNfcnVsZV9yZXJhbmsQ4Jafgr3BggOaARYKC3YxM19yNzEyMDg4EOCWn4K9wYIDmgEWCgt2MTJfcjcwMjA3NRDglp+CvcGCA5oBFgoLdjEzX3I3NjUxNjYQ4Jafgr3BggOaARYKC3YxM19yNzY1MTY3EOCWn4K9wYIDmgEWCgt2MTNfcjc2NTE2ORDglp+CvcGCA5oBFgoLdjEzX3I3NjcxMjIQ4Jafgr3BggOaARYKC3YxM19yNzcwODA0EOCWn4K9wYIDmgEWCgt2MTNfcjc3MDgwNRDglp+CvcGCA5oBFgoLdjEzX3I3NzA4MDYQ4Jafgr3BggOaARYKC3YxM19yNzcwODA3EOCWn4K9wYIDmgEWCgt2MTNfcjc3MDgwOBDglp+CvcGCA5oBFgoLdjEzX3I3NzA4MTAQ4Jafgr3BggOaARoKD2lkY19ydWxlX3JlcmFuaxDglp+CvcGCA6IBAQA=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:14:22.037528800"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"WebcastLiveIntroMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:06:35.159195800"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:07:36.363450600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:13:58.972664900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CiMKF1dlYmNhc3RMaXZlSW50cm9NZXNzYWdlEKGWofjy+rWEZRChlqH48vq1hGUYASIJR3JhbSB3IE1DKrcFCIWIpfSAjYWWYBoX8J+SgCBQb3JhIHVtaWVyYcSHIPCfkoBKvwQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Nk1YbjZlellUMzRxVWNzdU1xUTFHMTBRMWVZJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvYzJjYzgwOGQ5YmJjYTlmNTVjMzM4NzQwZDIyYzM0MjF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTgxNEpPdU9DOGR5b1RkOVNWOU5CN1I2UmI2NCUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4L2MyY2M4MDhkOWJiY2E5ZjU1YzMzODc0MGQyMmMzNDIxfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YRTNLaDI1QnlzMERVJTJGJTJGVWtyZWQlMkJMWnVCeFUlM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC9jMmNjODA4ZDliYmNhOWY1NWMzMzg3NDBkMjJjMzQyMYICAPICTE1TNHdMakFCQUFBQXFrRnQtRUpmRzRESFV1WXltUUJzU19qNmRyVWl5dFozM3RFTXlidWFHRi1pWHo3X1dZSXBfakQ0cElDVk1qd2QwAToeCAKqARkIAhIPcG1fbXRfaG9zdGxhYmVsGgRIb3N0QgJlbg==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:32:09.430963500"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"WebcastRoomUserSeqMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZafuvz/lallGKGW59iz55WpZSDshp/NvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAESngUSmQUIhoiO8qqbjuBiGgttYW5pdG91MTIyMUqDBAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0ugEAggIAqAIBsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxokATNzExNTc0OTkyMzEyMzA2OTk1OBgCGAI4AQ==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:13.650764700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaf2OeClqllGKGW59iz55WpZSDStaDNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgC",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:36.238853400"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZavypSElqllGKGW59iz55WpZSCJi6HNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgC",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:46.700698300"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZabh4KFlqllGKGW59iz55WpZSC1wKHNvDESogQSnQQIoIidor7Iw/BkGgVBbGVrc0qPAwqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLoBAIICAKgCAbICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqiQBM3MjY5MTA2OTU4MzA4MTY0NjQwGAEYATgD",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:53.950839200"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaq0vC6l6llGKGW59iz55WpZSD/p/rNvDEYATgK",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:08.727200600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaTwq67l6llGKGW59iz55WpZSCzw/rNvDEYATgL",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:11.956418700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaYnoa8l6llGKGW59iz55WpZSDG7/rNvDEYAjgM",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:17.383803400"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZanrPO9l6llGKGW59iz55WpZSCU5PvNvDEYATgM",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:32.712808600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJah8LnJl6llGKGW59iz55WpZSCks4HOvDES0QQSzAQIhoiJ4Nqz7rtjGglkb21pbmlrNTRKtQMKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTQzTmhEU3h4cExKVlNPYmpWOWNUakVQJTJCR25vJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XZkxXRm5ha0EzWjc0a3hIa1N3Zm9IRmVTJTJGSSUzRBJDMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYboBAIICAKgCAbICDmRvbWluaWt3YXNpbHVr8gJMTVM0d0xqQUJBQUFBaVpaMlpDQl94TjZlYUJwc0wyLU9xMy1yRTdmajV5ZkRWTnotZmZUUmUyWnlLd3dMdlh2ajF2all5RnJ6WXBzN6JAEzcxNjc0MDE0MTg4MzAyNjczOTgYARgCOA0=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:35:05.042649"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJa7+vLPl6llGKGW59iz55WpZSDEyITOvDES2gQS1QQIhoirsOTthPleGhBCcmFqYW4gb2tvbmVyIFhESroDCrgBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9em1nSEN4OXVSZXNYQ1hWaDZoZEJQJTJGMCUyRldMQSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJWQjNYM0N3Y1VDMkFJejIlMkZ3cFVqRDBhbjVNJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNroBAIICAKgCAbICC2FudGVrMTI0NTcx8gJMTVM0d0xqQUJBQUFBM3M2akdBak5wbzFFdTdnWnV0Y3FPZWhIMkFzdGdYOWQwcFBJWHFYSG9KTnRDX29BcTJ5ZXNsb2tVVEpaazBUSKJAEzY4NDE1NTIxNDgyNzE2NDU3MDIYARgCOA4=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:35:56.425306600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbtiITbl6llGKGW59iz55WpZSDw/4nOvDEYATgO",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:37:25.577177500"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaKs9fsl6llGKGW59iz55WpZSCa0ZLOvDESxgQSwQQIgICw8vjIy/wDGgTwn6ugSrgDCrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RnFGTERxVWE0V0dLYUklMkJYc0Q3RklWQ3dsYkUlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1idEFla3VPR1NmJTJCZ282RFFwU05GNDNFM3lnUSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNza6AQCCAgCoAgGyAgYxanVsYWfyAkxNUzR3TGpBQkFBQUFydEh0azg5SV9HWTktUlZQc3E3VmtDV2s3SDJ4WmJLUVpoWmEwY2o0a3RxWE5uVHhhQm0zNENwV1FvWWxwT251okASMjg2MzEwOTM2MTc5NjM4MjcyGAEYATgO",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:39:46.883152900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbI6NLtl6llGKGW59iz55WpZSCqipPOvDEYATgP",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:39:54.132292500"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaukoXzl6llGKGW59iz55WpZSDt25XOvDESxQQSwAQIhoimzuOSnqdiGgNPTE9KtgMKtAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SYlZHdjVReHdwWW4zUDE2VW5lMlRJTG9wOTAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1uN3FjRm1HYUsyTyUyQnFsNXBiNmF5VDc4eG4ybyUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTC6AQCCAgCoAgGyAgdvbG9fdjEy8gJMTVM0d0xqQUJBQUFBalFUeHpRcEZXS0RNaHdDQ3QtWWpIQ1dIM3gxRlI4UW82bm4yVkNyRjFKZlVacTFEcnZNclF4Y0VRUF9lWnAzRaJAEzcwODM3MzE4NTA1MTAzMDQyNjIYARgCOBA=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:40:37.563873900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZaS0rvzl6llGKGW59iz55WpZSC89pXOvDEYATgQ",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:40:40.781947100"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaSot/9l6llGKGW59iz55WpZSCe+JrOvDESzwUSygUIhoDrtqn685FcGgNlbG9KvQQKpgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9akdJc1VBbGxESmNmbWkwaHVzME9PNHVhT0xRJTNECqYBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdsMTh0V0tCeXA1NUVBNU1oQ1Nhd0pIaVF3dyUzRAqqAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JWUo1ZVVabEJnN0MlMkZEVk1pbkttbCUyRno0MDFJJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGK6AQCCAgCoAgGyAgpyYW5kb21tZW1q8gJMTVM0d0xqQUJBQUFBWlZsSldueTFLQ0l6T1c2bW4xcmZBOG0yNHhLd2VKRXlHS2g4SDFVclFnZ2hoTm1zaXZxTTV4Y21nSm14ZEFuY6JAEzY2MzkzNzg3NzkwNTUyNDMyNzAYARgCOBE=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:03.040632200"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJbMro3+l6llGKGW59iz55WpZSCskJvOvDEYATgR",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:06.280761800"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoZbzooKEmKllGKGW59iz55WpZSD0/p3OvDES1QQS0AQIhoiD8tXni7lfGgZUb21zb25KuAMKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLoBAIICAKgCAbICEnVzZXIxNzA4ODEwNzM0MDUwMvICTE1TNHdMakFCQUFBQXY4T1B0OWlNaFkzSWFFTlJoZThjOXE2RkdDOFg5cDJMbmhmSnZWSm5HOWlWelZ6VnhtUnlDUi1wZFNOaFFVV1aiQBM2ODc3NjExNTIxNTY4OTgyMDIyGAEYAjgS",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:52.821875300"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJbr0sSEmKllGKGW59iz55WpZSDwn57OvDEYATgS",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:57.643174900"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJaQheGVmKllGKGW59iz55WpZSDv1abOvDESyQQSxAQImoji2K2D5aVkGgEuSrYDCrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5ugEAggIAqAIBsgINbGl0dGxlX2JveTAyMvICTE1TNHdMakFCQUFBQXc1TWtxMWxMazNvQ2ZidGVobnk0SlY1UkJfR3k5V3pYT3RaVmRrcVhXZXVoUzNRcjZycXBSdEtkazE5am1pcnOiQBM3MjI3MDMyODcwMTExOTcwMzMwGAEYATgS",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:45:15.031268700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjYKGVdlYmNhc3RSb29tVXNlclNlcU1lc3NhZ2UQoJauqP6VmKllGKGW59iz55WpZSDe5KbOvDEYATgT",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:45:17.450676400"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"WebcastMemberMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "CtgGChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlrumyf6VqWUYoZbn2LPnlallILC4ns28MTABQpUGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi2gUICxIMCgcjOENFN0ZGIJADqgHGBQrDBQigiJ2ivsjD8GQaBUFsZWtzSscECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdnVUhmTHhYeVpLTkNwa2IwTkt4aERPQU5RMCUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLIBBAgaEAO6AQCCAgCyAglhbGVrczg0NTnyAkxNUzR3TGpBQkFBQUFENFlSMEtTMUVYXzZVN2dZNGhqMlc5WjEyLVVIbWF2eGtpUEdiLVdJSGMxc252cmJ3eVdpb0l2NzVYNVc0ZVRKSAFQAbABArgBAcABARLDBQigiJ2ivsjD8GQaBUFsZWtzSscECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUdnVUhmTHhYeVpLTkNwa2IwTkt4aERPQU5RMCUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SWpFYno1WnBmbVJxOUI0TXBnNWQxOVhNclRjJTNECqkBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1yVFlybXNoeElXdzVOWGh4Smk3JTJGSm5FbjF2OCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI2OTEwNzQ4Nzk4NTg2MDY0MLIBBAgaEAO6AQCCAgCyAglhbGVrczg0NTnyAkxNUzR3TGpBQkFBQUFENFlSMEtTMUVYXzZVN2dZNGhqMlc5WjEyLVVIbWF2eGtpUEdiLVdJSGMxc252cmJ3eVdpb0l2NzVYNVc0ZVRKGAFQAZIBlQYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyLaBQgLEgwKByM4Q0U3RkYgkAOqAcYFCsMFCKCInaK+yMPwZBoFQWxla3NKxwQKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyNjkxMDc0ODc5ODU4NjA2NDB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2dVSGZMeFh5WktOQ3BrYjBOS3hoRE9BTlEwJTNECqcBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JakViejVacGZtUnE5QjRNcGc1ZDE5WE1yVGMlM0QKqQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyNjkxMDc0ODc5ODU4NjA2NDB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPXJUWXJtc2h4SVd3NU5YaHhKaTclMkZKbkVuMXY4JTNEEjcxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83MjY5MTA3NDg3OTg1ODYwNjQwsgEECBoQA7oBAIICALICCWFsZWtzODQ1OfICTE1TNHdMakFCQUFBQUQ0WVIwS1MxRVhfNlU3Z1k0aGoyVzlaMTItVUhtYXZ4a2lQR2ItV0lIYzFzbnZyYnd5V2lvSXY3NVg1VzRlVEqaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:03.396935200"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CsoHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlsfK8v+VqWUYoZbn2LPnlallIJ+Ln828MTABQocHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMizAYICxIMCgcjOENFN0ZGIJADqgG4Bgq1BgiGiI7yqpuO4GIaC21hbml0b3UxMjIxSq8FCqkBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SUQlMkJvMVJHJTJCdkpPbENQWGNjUHQ1RkZCUUs1cyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0sgEGCAcQChgBugEAggIAsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxSAFQAbABArgBAcABARK1BgiGiI7yqpuO4GIaC21hbml0b3UxMjIxSq8FCqkBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SUQlMkJvMVJHJTJCdkpPbENQWGNjUHQ1RkZCUUs1cyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqbAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1CUDJDUnd4JTJGM3VUJTJGVHlpUkRycTIzakY1c09zJTNECpcBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPU14ekJvbWpDRWM0RGJNeVdud3N1dWtjYXFFayUzRBItMTAweDEwMC9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0sgEGCAcQChgBugEAggIAsgILbWFuaXRvdTEyMjHyAkxNUzR3TGpBQkFBQUFDUlhtN2d5WHpqdnJOVzhiQVgwMWRIYjRQQ0JmcHBoUUJsTFlsN3QzaVYzNjN6Qi1mOXY2djZJMVByX2UtSjNxGAJQAZIBhwcKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyLMBggLEgwKByM4Q0U3RkYgkAOqAbgGCrUGCIaIjvKqm47gYhoLbWFuaXRvdTEyMjFKrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpkBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVhYJTJCdmVXenVvWDJPTUttSlBGY2lKNXVPQ1ZjJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKlwFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9TXh6Qm9takNFYzREYk15V253c3V1a2NhcUVrJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQYIBxAKGAG6AQCCAgCyAgttYW5pdG91MTIyMfICTE1TNHdMakFCQUFBQUNSWG03Z3lYemp2ck5XOGJBWDAxZEhiNFBDQmZwcGhRQmxMWWw3dDNpVjM2M3pCLWY5djZ2NkkxUHJfZS1KM3GaAQlwdXNoLXB1c2iiAQVjbGljaw==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:13.651263600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CpwIChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglsOaiYSWqWUYoZbn2LPnlallIOuPoc28MTABQtkHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMingcICxIMCgcjOENFN0ZGIJADqgGKBwqHBwiGiKyWl8PO8mIaBnBvbGFuZEqEBgq6AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTRNQ2hwNlBQRlUlMkIwJTJCNHhQUzBtJTJGY2hLU2ZCVSUzRAqsAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1IWVFuJTJCMUV4Zkw1QmglMkIyU0hQbUM4TEolMkZoZnclM0QKrAFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9M01rSllpVE5iVVFyR2dOZSUyRiUyQnZhJTJGZ1FQN3ZJJTNECqgBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJuemRyWkQlMkJCZVVUenpUellWSGRoSURsb3lZJTNEEjwxMDB4MTAwL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmOyAQcI8QwQDxgBugEAggIAsgIMYW50b25pa3Vyenlu8gJMTVM0d0xqQUJBQUFBd3lVV0FUT2RHNC1QdUYtenhhbFdoLUZzVE1YVzVScGpINzJJLUhtUjVYbzQ2OWVSTm15WFp5SDhLS2FvR1FVRkgBUAKwAQG4AQHAAQEShwcIhoislpfDzvJiGgZwb2xhbmRKhAYKugFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY350cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00TUNocDZQUEZVJTJCMCUyQjR4UFMwbSUyRmNoS1NmQlUlM0QKrAFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SFlRbiUyQjFFeGZMNUJoJTJCMlNIUG1DOExKJTJGaGZ3JTNECqwBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNNa0pZaVROYlVRckdnTmUlMkYlMkJ2YSUyRmdRUDd2SSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SbnpkclpEJTJCQmVVVHp6VHpZVkhkaElEbG95WSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjsgEHCPEMEA8YAboBAIICALICDGFudG9uaWt1cnp5bvICTE1TNHdMakFCQUFBQXd5VVdBVE9kRzQtUHVGLXp4YWxXaC1Gc1RNWFc1UnBqSDcySS1IbVI1WG80NjllUk5teVhaeUg4S0thb0dRVUYYAlABkgHZBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIp4HCAsSDAoHIzhDRTdGRiCQA6oBigcKhwcIhoislpfDzvJiGgZwb2xhbmRKhAYKugFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY350cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00TUNocDZQUEZVJTJCMCUyQjR4UFMwbSUyRmNoS1NmQlUlM0QKrAFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC8yZTg2M2E2OTU1MDI2NThjOTU3NzNjMTVmZmI1OTBiY35jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SFlRbiUyQjFFeGZMNUJoJTJCMlNIUG1DOExKJTJGaGZ3JTNECqwBaHR0cHM6Ly9wMTYtc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvMmU4NjNhNjk1NTAyNjU4Yzk1NzczYzE1ZmZiNTkwYmN+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNNa0pZaVROYlVRckdnTmUlMkYlMkJ2YSUyRmdRUDd2SSUzRAqoAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SbnpkclpEJTJCQmVVVHp6VHpZVkhkaElEbG95WSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzJlODYzYTY5NTUwMjY1OGM5NTc3M2MxNWZmYjU5MGJjsgEHCPEMEA8YAboBAIICALICDGFudG9uaWt1cnp5bvICTE1TNHdMakFCQUFBQXd5VVdBVE9kRzQtUHVGLXp4YWxXaC1Gc1RNWFc1UnBqSDcySS1IbVI1WG80NjllUk5teVhaeUg4S0thb0dRVUaaARVpbm5lcl9wdXNoLWlubmVyX3B1c2iiAQVjbGljaw==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:08:47.493168800"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CuIGChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglqbQ8LqXqWUYoZbn2LPnlallIM6r+s28MTABQp8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi5AUICxIMCgcjOENFN0ZGIJADqgHQBQrNBQiFiJeU282M42EaCUxlbnVzaWExMUrLBAq3AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1jYW5ZZTNZU3h1em9GNXVHbHJUV25lU3clMkJMRSUzRAqnAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlBzcEVkREtVMmFWTVlDWlRpSVR2QkRpSlprJTNECqsBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83Mjk5MzQ2NTE0MTA1NTk3OTg1fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1KeGw4Y29DcHhlSXZja3o3MWFSbHl0eHAlMkYlMkY4JTNEEjcxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC83Mjk5MzQ2NTE0MTA1NTk3OTg1sgEECAsQA7oBAIICALICC2p1c3R5bmFzeXN68gJMTVM0d0xqQUJBQUFBcXJWQkViS1RTWXVFZmVJeE5PSGx6WjhYLXVseDNIYVJYZnJZbmFtYl85Y1pOdW44R295ZWJFSXI4c2phRnE0dEgBUAKwAQG4AQHAAQESzQUIhYiXlNvNjONhGglMZW51c2lhMTFKywQKtwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Y2FuWWUzWVN4dXpvRjV1R2xyVFduZVN3JTJCTEUlM0QKpwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJQc3BFZERLVTJhVk1ZQ1pUaUlUdkJEaUpaayUzRAqrAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SnhsOGNvQ3B4ZUl2Y2t6NzFhUmx5dHhwJTJGJTJGOCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NbIBBAgLEAO6AQCCAgCyAgtqdXN0eW5hc3lzevICTE1TNHdMakFCQUFBQXFyVkJFYktUU1l1RWZlSXhOT0hselo4WC11bHgzSGFSWGZyWW5hbWJfOWNaTnVuOEdveWViRUlyOHNqYUZxNHQYAlABkgGfBgoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIuQFCAsSDAoHIzhDRTdGRiCQA6oB0AUKzQUIhYiXlNvNjONhGglMZW51c2lhMTFKywQKtwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9Y2FuWWUzWVN4dXpvRjV1R2xyVFduZVN3JTJCTEUlM0QKpwFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzcyOTkzNDY1MTQxMDU1OTc5ODV+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJQc3BFZERLVTJhVk1ZQ1pUaUlUdkJEaUpaayUzRAqrAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SnhsOGNvQ3B4ZUl2Y2t6NzFhUmx5dHhwJTJGJTJGOCUzRBI3MTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvNzI5OTM0NjUxNDEwNTU5Nzk4NbIBBAgLEAO6AQCCAgCyAgtqdXN0eW5hc3lzevICTE1TNHdMakFCQUFBQXFyVkJFYktUU1l1RWZlSXhOT0hselo4WC11bHgzSGFSWGZyWW5hbWJfOWNaTnVuOEdveWViRUlyOHNqYUZxNHSaARNsaXZlX2VuZC1saXZlX2NvdmVyogEFY2xpY2s=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:09.521317400"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CukHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlsyE97uXqWUYoZbn2LPnlallIK3z+s28MTABQqYHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMi6wYICxIMCgcjOENFN0ZGIJADqgHXBgrUBgiGiMS6yfvm6l0aJ/CfpKbigI3imYLvuI/wn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j0qvBQqpAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlEJTJCbzFSRyUyQnZKT2xDUFhjY1B0NUZGQlFLNXMlM0QKmwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9QlAyQ1J3eCUyRjN1VCUyRlR5aVJEcnEyM2pGNXNPcyUzRAqZAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1YWCUyQnZlV3p1b1gyT01LbUpQRmNpSjV1T0NWYyUzRAqXAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS9tdXNpY2FsbHktbWFsaXZhLW9iai8xNTk0ODA1MjU4MjE2NDU0fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1HbGh4d3A3WjY0b2VLU1ZpcEFzbTk5ZU1RajAlM0QSLTEwMHgxMDAvbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NLIBBQiLARBjugEAggIAsgIPc2lrZS55b3UudG91Z2h08gJMTVM0d0xqQUJBQUFBTWhrZ1JtcWxNNlhQeW1LSEZHOEU0OVVUMXFEV2RzVUxRdG45bHh2VjhDS1ZhczZKaHhWeHhDOGdIaU4xWm10aEgBUAKwAQG4AQHAAQES1AYIhojEusn75updGifwn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j/CfpKbigI3imYLvuI9KrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKmQFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9WFglMkJ2ZVd6dW9YMk9NS21KUEZjaUo1dU9DVmMlM0QKlwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2xoeHdwN1o2NG9lS1NWaXBBc205OWVNUWowJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQUIiwEQY7oBAIICALICD3Npa2UueW91LnRvdWdodPICTE1TNHdMakFCQUFBQU1oa2dSbXFsTTZYUHltS0hGRzhFNDlVVDFxRFdkc1VMUXRuOWx4dlY4Q0tWYXM2Smh4Vnh4QzhnSGlOMVptdGgYAlABkgGmBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIusGCAsSDAoHIzhDRTdGRiCQA6oB1wYK1AYIhojEusn75updGifwn6Sm4oCN4pmC77iP8J+kpuKAjeKZgu+4j/CfpKbigI3imYLvuI9KrwUKqQFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1JRCUyQm8xUkclMkJ2Sk9sQ1BYY2NQdDVGRkJRSzVzJTNECpsBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUJQMkNSd3glMkYzdVQlMkZUeWlSRHJxMjNqRjVzT3MlM0QKmQFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9WFglMkJ2ZVd6dW9YMk9NS21KUEZjaUo1dU9DVmMlM0QKlwFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vbXVzaWNhbGx5LW1hbGl2YS1vYmovMTU5NDgwNTI1ODIxNjQ1NH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2xoeHdwN1o2NG9lS1NWaXBBc205OWVNUWowJTNEEi0xMDB4MTAwL211c2ljYWxseS1tYWxpdmEtb2JqLzE1OTQ4MDUyNTgyMTY0NTSyAQUIiwEQY7oBAIICALICD3Npa2UueW91LnRvdWdodPICTE1TNHdMakFCQUFBQU1oa2dSbXFsTTZYUHltS0hGRzhFNDlVVDFxRFdkc1VMUXRuOWx4dlY4Q0tWYXM2Smh4Vnh4QzhnSGlOMVptdGiaARVsaXZlX21lcmdlLWxpdmVfY292ZXKiAQRkcmF3",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:33:18.203136100"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CpkHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChltn8pMmXqWUYoZbn2LPnlallIIK0gc68MTABQtYGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMimwYICxIMCgcjOENFN0ZGIJADqgGHBgqEBgiGiIng2rPuu2MaCWRvbWluaWs1NEr9BArFAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hJTJCdmp3VWc1JTJCRkg4NGpwT1dFMDFIb3FMVGdZJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00M05oRFN4eHBMSlZTT2JqVjljVGpFUCUyQkdubyUzRAq1AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9V2ZMV0ZuYWtBM1o3NGt4SGtTd2ZvSEZlUyUyRkklM0QSQzEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmGyAQYIZRA7GAG6AQCCAgCyAg5kb21pbmlrd2FzaWx1a/ICTE1TNHdMakFCQUFBQWlaWjJaQ0JfeE42ZWFCcHNMMi1PcTMtckU3Zmo1eWZEVk56LWZmVFJlMlp5S3d3THZYdmoxdmpZeUZyellwczdIAVACsAEBuAEBwAEBEoQGCIaIieDas+67YxoJZG9taW5pazU0Sv0ECsUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWElMkJ2andVZzUlMkJGSDg0anBPV0UwMUhvcUxUZ1klM0QKtQFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmF+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTQzTmhEU3h4cExKVlNPYmpWOWNUakVQJTJCR25vJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1XZkxXRm5ha0EzWjc0a3hIa1N3Zm9IRmVTJTJGSSUzRBJDMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYbIBBghlEDsYAboBAIICALICDmRvbWluaWt3YXNpbHVr8gJMTVM0d0xqQUJBQUFBaVpaMlpDQl94TjZlYUJwc0wyLU9xMy1yRTdmajV5ZkRWTnotZmZUUmUyWnlLd3dMdlh2ajF2all5RnJ6WXBzNxgCUAGSAdYGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMimwYICxIMCgcjOENFN0ZGIJADqgGHBgqEBgiGiIng2rPuu2MaCWRvbWluaWs1NEr9BArFAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hJTJCdmp3VWc1JTJCRkg4NGpwT1dFMDFIb3FMVGdZJTNECrUBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1naXNvL2RkMzYyN2U1ZWE0ZjEyM2M5OWI4MDA3M2ZkMjNiYWJhfmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT00M05oRFN4eHBMSlZTT2JqVjljVGpFUCUyQkdubyUzRAq1AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZ2lzby9kZDM2MjdlNWVhNGYxMjNjOTliODAwNzNmZDIzYmFiYX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9V2ZMV0ZuYWtBM1o3NGt4SGtTd2ZvSEZlUyUyRkklM0QSQzEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWdpc28vZGQzNjI3ZTVlYTRmMTIzYzk5YjgwMDczZmQyM2JhYmGyAQYIZRA7GAG6AQCCAgCyAg5kb21pbmlrd2FzaWx1a/ICTE1TNHdMakFCQUFBQWlaWjJaQ0JfeE42ZWFCcHNMMi1PcTMtckU3Zmo1eWZEVk56LWZmVFJlMlp5S3d3THZYdmoxdmpZeUZyellwczeaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:35:05.044148700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CqIHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlpaS8c+XqWUYoZbn2LPnlallIKrMhM68MTABQt8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMipAYICxIMCgcjOENFN0ZGIJADqgGQBgqNBgiGiKuw5O2E+V4aEEJyYWphbiBva29uZXIgWERKgwUKxgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNseVhFJTJGNWtVa0Npdlhab1YlMkZlS2lSeXliVGMlM0QKuAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT16bWdIQ3g5dVJlc1hDWFZoNmhkQlAlMkYwJTJGV0xBJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlZCM1gzQ3djVUMyQUl6MiUyRndwVWpEMGFuNU0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2sgEFCKkBEEe6AQCCAgCyAgthbnRlazEyNDU3MfICTE1TNHdMakFCQUFBQTNzNmpHQWpOcG8xRXU3Z1p1dGNxT2VoSDJBc3RnWDlkMHBQSVhxWEhvSk50Q19vQXEyeWVzbG9rVVRKWmswVEhIAVACsAEBuAEBwAEBEo0GCIaIq7Dk7YT5XhoQQnJhamFuIG9rb25lciBYREqDBQrGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9M2x5WEUlMkY1a1VrQ2l2WFpvViUyRmVLaVJ5eWJUYyUzRAq4AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPXptZ0hDeDl1UmVzWENYVmg2aGRCUCUyRjAlMkZXTEElM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1SVkIzWDNDd2NVQzJBSXoyJTJGd3BVakQwYW41TSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvOTVmMDc4NGQ5YzBkNGRmNWUyNmM0ZjVjYzc1N2JlYzayAQUIqQEQR7oBAIICALICC2FudGVrMTI0NTcx8gJMTVM0d0xqQUJBQUFBM3M2akdBak5wbzFFdTdnWnV0Y3FPZWhIMkFzdGdYOWQwcFBJWHFYSG9KTnRDX29BcTJ5ZXNsb2tVVEpaazBUSBgCUAGSAd8GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMipAYICxIMCgcjOENFN0ZGIJADqgGQBgqNBgiGiKuw5O2E+V4aEEJyYWphbiBva29uZXIgWERKgwUKxgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTNseVhFJTJGNWtVa0Npdlhab1YlMkZlS2lSeXliVGMlM0QKuAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT16bWdIQ3g5dVJlc1hDWFZoNmhkQlAlMkYwJTJGV0xBJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC85NWYwNzg0ZDljMGQ0ZGY1ZTI2YzRmNWNjNzU3YmVjNn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UlZCM1gzQ3djVUMyQUl6MiUyRndwVWpEMGFuNU0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzk1ZjA3ODRkOWMwZDRkZjVlMjZjNGY1Y2M3NTdiZWM2sgEFCKkBEEe6AQCCAgCyAgthbnRlazEyNDU3MfICTE1TNHdMakFCQUFBQTNzNmpHQWpOcG8xRXU3Z1p1dGNxT2VoSDJBc3RnWDlkMHBQSVhxWEhvSk50Q19vQXEyeWVzbG9rVVRKWmswVEiaARdzZWFyY2hfcmVzdWx0LWxpdmVfY2VsbA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:35:57.223255400"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CooHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCgls2G0+yXqWUYoZbn2LPnlallINXUks68MTABQscGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMijAYICxIMCgcjOENFN0ZGIJADqgH4BQr1BQiAgLDy+MjL/AMaBPCfq6BK/QQKwgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWJiSTlobVJlZzVsOE1zSkcwTzl3MDJIc2YyUSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUZxRkxEcVVhNFdHS2FJJTJCWHNEN0ZJVkN3bGJFJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YnRBZWt1T0dTZiUyQmdvNkRRcFNORjQzRTN5Z1ElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2sgEECDgQc7oBAIICALICBjFqdWxhZ/ICTE1TNHdMakFCQUFBQXJ0SHRrODlJX0dZOS1SVlBzcTdWa0NXazdIMnhaYktRWmhaYTBjajRrdHFYTm5UeGFCbTM0Q3BXUW9ZbHBPbnVIAVACsAEBuAEBwAEBEvUFCICAsPL4yMv8AxoE8J+roEr9BArCAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YmJJOWhtUmVnNWw4TXNKRzBPOXcwMkhzZjJRJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RnFGTERxVWE0V0dLYUklMkJYc0Q3RklWQ3dsYkUlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1idEFla3VPR1NmJTJCZ282RFFwU05GNDNFM3lnUSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzayAQQIOBBzugEAggIAsgIGMWp1bGFn8gJMTVM0d0xqQUJBQUFBcnRIdGs4OUlfR1k5LVJWUHNxN1ZrQ1drN0gyeFpiS1FaaFphMGNqNGt0cVhOblR4YUJtMzRDcFdRb1lscE9udRgCUAGSAccGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMijAYICxIMCgcjOENFN0ZGIJADqgH4BQr1BQiAgLDy+MjL/AMaBPCfq6BK/QQKwgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWJiSTlobVJlZzVsOE1zSkcwTzl3MDJIc2YyUSUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvMjM2MGY5Nzg1YmFiN2YxZTIwYWEzMGI2ZTMwODNhNzZ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUZxRkxEcVVhNFdHS2FJJTJCWHNEN0ZJVkN3bGJFJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC8yMzYwZjk3ODViYWI3ZjFlMjBhYTMwYjZlMzA4M2E3Nn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9YnRBZWt1T0dTZiUyQmdvNkRRcFNORjQzRTN5Z1ElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwLzIzNjBmOTc4NWJhYjdmMWUyMGFhMzBiNmUzMDgzYTc2sgEECDgQc7oBAIICALICBjFqdWxhZ/ICTE1TNHdMakFCQUFBQXJ0SHRrODlJX0dZOS1SVlBzcTdWa0NXazdIMnhaYktRWmhaYTBjajRrdHFYTm5UeGFCbTM0Q3BXUW9ZbHBPbnWaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:39:47.676401600"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "Co4HChRXZWJjYXN0TWVtYmVyTWVzc2FnZRChlrmo+vKXqWUYoZbn2LPnlallIIfelc68MTABQssGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMikAYICxIMCgcjOENFN0ZGIJADqgH8BQr5BQiGiKbO45Kep2IaA09MT0r/BArGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bXlwMzBkJTJCUzNCRmRPZm4xV1ElMkZpbXA4WGdrMCUzRAq0AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJiVkd2NVF4d3BZbjNQMTZVbmUyVElMb3A5MCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPW43cWNGbUdhSzJPJTJCcWw1cGI2YXlUNzh4bjJvJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MLIBBgjUExDJBroBAIICALICB29sb192MTLyAkxNUzR3TGpBQkFBQUFqUVR4elFwRldLRE1od0NDdC1ZakhDV0gzeDFGUjhRbzZubjJWQ3JGMUpmVVpxMURydk1yUXhjRVFQX2VacDNFSAFQArABAbgBAcABARL5BQiGiKbO45Kep2IaA09MT0r/BArGAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bXlwMzBkJTJCUzNCRmRPZm4xV1ElMkZpbXA4WGdrMCUzRAq0AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVJiVkd2NVF4d3BZbjNQMTZVbmUyVElMb3A5MCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZDkxMWE2OTE0OTdmZTMzYzkyZDA5NTE0ZWU5MGFiOTB+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPW43cWNGbUdhSzJPJTJCcWw1cGI2YXlUNzh4bjJvJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MLIBBgjUExDJBroBAIICALICB29sb192MTLyAkxNUzR3TGpBQkFBQUFqUVR4elFwRldLRE1od0NDdC1ZakhDV0gzeDFGUjhRbzZubjJWQ3JGMUpmVVpxMURydk1yUXhjRVFQX2VacDNFGAJQAZIBywYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKQBggLEgwKByM4Q0U3RkYgkAOqAfwFCvkFCIaIps7jkp6nYhoDT0xPSv8ECsYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1teXAzMGQlMkJTM0JGZE9mbjFXUSUyRmltcDhYZ2swJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9UmJWR3Y1UXh3cFluM1AxNlVuZTJUSUxvcDkwJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kOTExYTY5MTQ5N2ZlMzNjOTJkMDk1MTRlZTkwYWI5MH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9bjdxY0ZtR2FLMk8lMkJxbDVwYjZheVQ3OHhuMm8lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2Q5MTFhNjkxNDk3ZmUzM2M5MmQwOTUxNGVlOTBhYjkwsgEGCNQTEMkGugEAggIAsgIHb2xvX3YxMvICTE1TNHdMakFCQUFBQWpRVHh6UXBGV0tETWh3Q0N0LVlqSENXSDN4MUZSOFFvNm5uMlZDckYxSmZVWnExRHJ2TXJReGNFUVBfZVpwM0WaARlnZW5lcmFsX3NlYXJjaC12aWRlb19oZWFkogEFY2xpY2s=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:40:37.565374200"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CoQIChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglpuE1f2XqWUYoZbn2LPnlallIJn6ms68MTABQsEHChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMihgcICxIMCgcjOENFN0ZGIJADqgHyBgrvBgiGgOu2qfrzkVwaA2Vsb0r2BQq2AWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPVYzM1ozJTJGRDFjcFBMbkI5Y3QxbHgyRVYxaXRjJTNECqYBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWpHSXNVQWxsREpjZm1pMGh1czBPTzR1YU9MUSUzRAqmAWh0dHBzOi8vcDE2LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1HbDE4dFdLQnlwNTVFQTVNaENTYXdKSGlRd3clM0QKqgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9SVlKNWVVWmxCZzdDJTJGRFZNaW5LbWwlMkZ6NDAxSSUzRBI8MTAweDEwMC90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRisgECEAO6AQCCAgCyAgpyYW5kb21tZW1q8gJMTVM0d0xqQUJBQUFBWlZsSldueTFLQ0l6T1c2bW4xcmZBOG0yNHhLd2VKRXlHS2g4SDFVclFnZ2hoTm1zaXZxTTV4Y21nSm14ZEFuY0gBUAKwAQG4AQHAAQES7wYIhoDrtqn685FcGgNlbG9K9gUKtgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1WMzNaMyUyRkQxY3BQTG5COWN0MWx4MkVWMWl0YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1qR0lzVUFsbERKY2ZtaTBodXMwT080dWFPTFElM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2wxOHRXS0J5cDU1RUE1TWhDU2F3SkhpUXd3JTNECqoBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlZSjVlVVpsQmc3QyUyRkRWTWluS21sJTJGejQwMUklM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYrIBAhADugEAggIAsgIKcmFuZG9tbWVtavICTE1TNHdMakFCQUFBQVpWbEpXbnkxS0NJek9XNm1uMXJmQThtMjR4S3dlSkV5R0toOEgxVXJRZ2doaE5tc2l2cU01eGNtZ0pteGRBbmMYAlABkgHBBwoVbGl2ZV9yb29tX2VudGVyX3RvYXN0Eg97MDp1c2VyfSBqb2luZWQaDgoJI2I4ZmZmZmZmIJADIoYHCAsSDAoHIzhDRTdGRiCQA6oB8gYK7wYIhoDrtqn685FcGgNlbG9K9gUKtgFodHRwczovL3A3Ny1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1WMzNaMyUyRkQxY3BQTG5COWN0MWx4MkVWMWl0YyUzRAqmAWh0dHBzOi8vcDc3LXNpZ24tdmEudGlrdG9rY2RuLmNvbS90b3MtbWFsaXZhLWF2dC0wMDY4LzY5MmI4OTdiYTNjNTA1M2IzMTI1YWZlMzFjYTlhNGRifmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1qR0lzVUFsbERKY2ZtaTBodXMwT080dWFPTFElM0QKpgFodHRwczovL3AxNi1zaWduLXZhLnRpa3Rva2Nkbi5jb20vdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYn5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9R2wxOHRXS0J5cDU1RUE1TWhDU2F3SkhpUXd3JTNECqoBaHR0cHM6Ly9wNzctc2lnbi12YS50aWt0b2tjZG4uY29tL3Rvcy1tYWxpdmEtYXZ0LTAwNjgvNjkyYjg5N2JhM2M1MDUzYjMxMjVhZmUzMWNhOWE0ZGJ+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPUlZSjVlVVpsQmc3QyUyRkRWTWluS21sJTJGejQwMUklM0QSPDEwMHgxMDAvdG9zLW1hbGl2YS1hdnQtMDA2OC82OTJiODk3YmEzYzUwNTNiMzEyNWFmZTMxY2E5YTRkYrIBAhADugEAggIAsgIKcmFuZG9tbWVtavICTE1TNHdMakFCQUFBQVpWbEpXbnkxS0NJek9XNm1uMXJmQThtMjR4S3dlSkV5R0toOEgxVXJRZ2doaE5tc2l2cU01eGNtZ0pteGRBbmOaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:03.041132700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CqAHChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglp+O8oOYqWUYoZbn2LPnlallIPqCns68MTABQt0GChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMiogYICxIMCgcjOENFN0ZGIJADqgGOBgqLBgiGiIPy1eeLuV8aBlRvbXNvbkqFBQrKAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9VGo3JTJCblhBeiUyRndEdSUyQm1iblhyaHBlWFNXJTJCajAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLIBBAhDEBC6AQCCAgCyAhJ1c2VyMTcwODgxMDczNDA1MDLyAkxNUzR3TGpBQkFBQUF2OE9QdDlpTWhZM0lhRU5SaGU4YzlxNkZHQzhYOXAyTG5oZkp2VkpuRzlpVnpWelZ4bVJ5Q1ItcGRTTmhRVVdWSAFQArABAbgBAcABARKLBgiGiIPy1eeLuV8aBlRvbXNvbkqFBQrKAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9VGo3JTJCblhBeiUyRndEdSUyQm1iblhyaHBlWFNXJTJCajAlM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1hREYlMkJrb2tQQ0dKRjV5cDVTTnJCNVA3MjlJOCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC5qcGVnP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPTYxZ0Y3VFFVSUpqWDYlMkJ6aHRJcVpjOUdRUXlBJTNEEkQxMDB4MTAwL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNLIBBAhDEBC6AQCCAgCyAhJ1c2VyMTcwODgxMDczNDA1MDLyAkxNUzR3TGpBQkFBQUF2OE9QdDlpTWhZM0lhRU5SaGU4YzlxNkZHQzhYOXAyTG5oZkp2VkpuRzlpVnpWelZ4bVJ5Q1ItcGRTTmhRVVdWGAJQAZIB3QYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKiBggLEgwKByM4Q0U3RkYgkAOqAY4GCosGCIaIg/LV54u5XxoGVG9tc29uSoUFCsoBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNH50cGx2LXRpa3Rvay1zaHJpbms6NzI6NzIud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1UajclMkJuWEF6JTJGd0R1JTJCbWJuWHJocGVYU1clMkJqMCUzRAq2AWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvYjBhYjY3ZDg4YWE3YmEwMGZjZGVkZTliM2U2ZDE1YTR+YzVfMTAweDEwMC53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWFERiUyQmtva1BDR0pGNXlwNVNOckI1UDcyOUk4JTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9iMGFiNjdkODhhYTdiYTAwZmNkZWRlOWIzZTZkMTVhNH5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9NjFnRjdUUVVJSmpYNiUyQnpodElxWmM5R1FReUElM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2IwYWI2N2Q4OGFhN2JhMDBmY2RlZGU5YjNlNmQxNWE0sgEECEMQELoBAIICALICEnVzZXIxNzA4ODEwNzM0MDUwMvICTE1TNHdMakFCQUFBQXY4T1B0OWlNaFkzSWFFTlJoZThjOXE2RkdDOFg5cDJMbmhmSnZWSm5HOWlWelZ6VnhtUnlDUi1wZFNOaFFVV1aaARZob21lcGFnZV9ob3QtbGl2ZV9jZWxs",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:42:53.616185700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "Co4HChRXZWJjYXN0TWVtYmVyTWVzc2FnZRCglonZ0JWYqWUYoZbn2LPnlallIJbZps68MTABQssGChVsaXZlX3Jvb21fZW50ZXJfdG9hc3QSD3swOnVzZXJ9IGpvaW5lZBoOCgkjYjhmZmZmZmYgkAMikAYICxIMCgcjOENFN0ZGIJADqgH8BQr5BQiaiOLYrYPlpWQaAS5K/QQKxAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWlHSFByTnludTh3aTJNUSUyRmZBV1JQREc0ZURRJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5sgEECBEQWLoBAIICALICDWxpdHRsZV9ib3kwMjLyAkxNUzR3TGpBQkFBQUF3NU1rcTFsTGszb0NmYnRlaG55NEpWNVJCX0d5OVd6WE90WlZka3FYV2V1aFMzUXI2cnFwUnRLZGsxOWptaXJzSAFQArABAbgBAcABARL5BQiaiOLYrYPlpWQaAS5K/QQKxAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fnRwbHYtdGlrdG9rLXNocmluazo3Mjo3Mi53ZWJwP3gtZXhwaXJlcz0xNzAwMDY3NjAwJngtc2lnbmF0dXJlPWlHSFByTnludTh3aTJNUSUyRmZBV1JQREc0ZURRJTNECrQBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9cDdqVExCMFNvUEhJeWxta3dRMVE0eXBsOTZZJTNECrYBaHR0cHM6Ly9wMTYtc2lnbi11c2Vhc3QyYS50aWt0b2tjZG4uY29tL3Rvcy11c2Vhc3QyYS1hdnQtMDA2OC1ldXR0cC9kY2IzZjYyYTg4NzFlZWY2OWViZTdjZDFiZGQ1YzM1OX5jNV8xMDB4MTAwLmpwZWc/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9RHIlMkZmRVYzMm5jdnB5dXFoRTJxcVZ5WUpQTE0lM0QSRDEwMHgxMDAvdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5sgEECBEQWLoBAIICALICDWxpdHRsZV9ib3kwMjLyAkxNUzR3TGpBQkFBQUF3NU1rcTFsTGszb0NmYnRlaG55NEpWNVJCX0d5OVd6WE90WlZka3FYV2V1aFMzUXI2cnFwUnRLZGsxOWptaXJzGAJQAZIBywYKFWxpdmVfcm9vbV9lbnRlcl90b2FzdBIPezA6dXNlcn0gam9pbmVkGg4KCSNiOGZmZmZmZiCQAyKQBggLEgwKByM4Q0U3RkYgkAOqAfwFCvkFCJqI4titg+WlZBoBLkr9BArEAWh0dHBzOi8vcDE2LXNpZ24tdXNlYXN0MmEudGlrdG9rY2RuLmNvbS90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZGNiM2Y2MmE4ODcxZWVmNjllYmU3Y2QxYmRkNWMzNTl+dHBsdi10aWt0b2stc2hyaW5rOjcyOjcyLndlYnA/eC1leHBpcmVzPTE3MDAwNjc2MDAmeC1zaWduYXR1cmU9aUdIUHJOeW51OHdpMk1RJTJGZkFXUlBERzRlRFElM0QKtAFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fmM1XzEwMHgxMDAud2VicD94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1wN2pUTEIwU29QSEl5bG1rd1ExUTR5cGw5NlklM0QKtgFodHRwczovL3AxNi1zaWduLXVzZWFzdDJhLnRpa3Rva2Nkbi5jb20vdG9zLXVzZWFzdDJhLWF2dC0wMDY4LWV1dHRwL2RjYjNmNjJhODg3MWVlZjY5ZWJlN2NkMWJkZDVjMzU5fmM1XzEwMHgxMDAuanBlZz94LWV4cGlyZXM9MTcwMDA2NzYwMCZ4LXNpZ25hdHVyZT1EciUyRmZFVjMybmN2cHl1cWhFMnFxVnlZSlBMTSUzRBJEMTAweDEwMC90b3MtdXNlYXN0MmEtYXZ0LTAwNjgtZXV0dHAvZGNiM2Y2MmE4ODcxZWVmNjllYmU3Y2QxYmRkNWMzNTmyAQQIERBYugEAggIAsgINbGl0dGxlX2JveTAyMvICTE1TNHdMakFCQUFBQXc1TWtxMWxMazNvQ2ZidGVobnk0SlY1UkJfR3k5V3pYT3RaVmRrcVhXZXVoUzNRcjZycXBSdEtkazE5am1pcnOaARVsaXZlX21lcmdlLWxpdmVfY292ZXKiAQRkcmF3",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:45:15.827938300"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"WebcastControlMessage": [
|
|
||||||
{
|
|
||||||
"eventData": "CjQKFVdlYmNhc3RDb250cm9sTWVzc2FnZRCglq+Gv7yWqWUYoZbn2LPnlallINDPvM28MTABEAEiAA==",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:16:17.730662700"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"eventData": "CjQKFVdlYmNhc3RDb250cm9sTWVzc2FnZRCgluru472WqWUYoZbn2LPnlallIJujvc28MTABEAI=",
|
|
||||||
"uniqueId": "dostawcavideo",
|
|
||||||
"ts": "2023-11-13T18:16:28.978931500"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
|
||||||
<version>1.3.0-Release</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>Tools-EventsWebViewer</artifactId>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.javalin</groupId>
|
|
||||||
<artifactId>javalin</artifactId>
|
|
||||||
<version>5.6.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>2.0.7</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
|
||||||
<artifactId>Tools-EventsCollector</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.handlers.TikTokHandler;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokCollectorService;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokDatabaseService;
|
|
||||||
import io.javalin.Javalin;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) throws SQLException
|
|
||||||
{
|
|
||||||
var settings = new Settings();
|
|
||||||
settings.setUserName("szalonamoniaxx");
|
|
||||||
settings.setSessionTag("battle");
|
|
||||||
settings.setDbName("db-battle");
|
|
||||||
settings.setPort(8002);
|
|
||||||
|
|
||||||
var db = new TikTokDatabase(settings.getDbName());
|
|
||||||
db.connect();
|
|
||||||
|
|
||||||
var service = new TikTokDatabaseService(db);
|
|
||||||
var collectorService = new TikTokCollectorService(settings, db);
|
|
||||||
var handler = new TikTokHandler(service, settings, collectorService);
|
|
||||||
// var manager = new TikTokManager(service);
|
|
||||||
var app = Javalin.create(config ->
|
|
||||||
{
|
|
||||||
config.plugins.enableCors(corsContainer ->
|
|
||||||
{
|
|
||||||
corsContainer.add(corsPluginConfig ->
|
|
||||||
{
|
|
||||||
corsPluginConfig.allowHost("http://localhost:5500");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
config.staticFiles.add("/public");
|
|
||||||
}).start(settings.getPort());
|
|
||||||
|
|
||||||
app.get("/tiktok/status", handler::connectionStatus);
|
|
||||||
app.get("/tiktok/connect", handler::connect);
|
|
||||||
app.get("/tiktok/disconnect", handler::disconnect);
|
|
||||||
|
|
||||||
app.get("/tiktok/data/pages", handler::getDataPages);
|
|
||||||
app.get("/tiktok/data/names", handler::getDataNames);
|
|
||||||
app.get("/tiktok/data", handler::getData);
|
|
||||||
|
|
||||||
app.get("/tiktok/update", handler::updateSearch);
|
|
||||||
app.get("/tiktok/sessions", handler::getUserSessionTags);
|
|
||||||
app.get("/tiktok/users", handler::getUsers);
|
|
||||||
app.get("/tiktok/data-types", handler::getDataTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class Settings
|
|
||||||
{
|
|
||||||
|
|
||||||
private int port;
|
|
||||||
private String dbName;
|
|
||||||
private String userName;
|
|
||||||
private String sessionTag;
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.TikTokLiveTools;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ToolsExamples {
|
|
||||||
|
|
||||||
private static final String tiktokUser = "k.peaks";
|
|
||||||
|
|
||||||
private static final String db = "a";
|
|
||||||
|
|
||||||
private static final String sessionTag = "a";
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
// runCollector();
|
|
||||||
runCollector();
|
|
||||||
//runTester();
|
|
||||||
System.in.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
WebcastLinkMicArmies
|
|
||||||
WebcastLinkMicBattle
|
|
||||||
*/
|
|
||||||
//WebcastLinkMicArmies battle data?
|
|
||||||
//WebcastLinkMicBattlePunishFinish end of battle?
|
|
||||||
//WebcastLinkLayerMessage send after end of battle
|
|
||||||
// send after LinkLayer -> WebcastLinkMessage
|
|
||||||
|
|
||||||
private static void runCollector() {
|
|
||||||
TikTokLiveTools.createCollector(db)
|
|
||||||
.addUser(tiktokUser)
|
|
||||||
.setSessionTag(sessionTag)
|
|
||||||
.configureLiveClient(liveClientBuilder ->
|
|
||||||
{
|
|
||||||
liveClientBuilder.configure(clientSettings ->
|
|
||||||
{
|
|
||||||
clientSettings.setPrintToConsole(true);
|
|
||||||
})
|
|
||||||
.onComment((liveClient, event) ->
|
|
||||||
{
|
|
||||||
System.out.println("Chat message: " + event.getUser().getName() + " " + event.getText());
|
|
||||||
})
|
|
||||||
.onWebsocketUnhandledMessage((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info(event.getMessage().getMethod());
|
|
||||||
});
|
|
||||||
liveClientBuilder.onConnected((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Connected");
|
|
||||||
});
|
|
||||||
}).buildAndRun();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void runTester() {
|
|
||||||
TikTokLiveTools.createTester(db)
|
|
||||||
.setSessionTag(sessionTag)
|
|
||||||
.setUser(tiktokUser)
|
|
||||||
.configureLiveClient(liveClientBuilder ->
|
|
||||||
{
|
|
||||||
liveClientBuilder.onError((liveClient, event) ->
|
|
||||||
{
|
|
||||||
event.getException().printStackTrace();
|
|
||||||
;
|
|
||||||
});
|
|
||||||
|
|
||||||
liveClientBuilder.onWebsocketResponse((liveClient, event) ->
|
|
||||||
{
|
|
||||||
System.out.println("Response =====================================");
|
|
||||||
for (var msg : event.getResponse().getMessagesList()) {
|
|
||||||
System.out.println("Message -> " + msg.getMethod());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
liveClientBuilder.onEvent((liveClient, event) ->
|
|
||||||
{
|
|
||||||
System.out.println("Event -> " + event.getClass().getSimpleName());
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.buildAndRun();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer.handlers;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.Settings;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokCollectorService;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.services.TikTokDatabaseService;
|
|
||||||
import io.javalin.http.Context;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class TikTokHandler {
|
|
||||||
private final TikTokDatabaseService databaseService;
|
|
||||||
private final Settings settings;
|
|
||||||
private final TikTokCollectorService collectorService;
|
|
||||||
|
|
||||||
public TikTokHandler(TikTokDatabaseService databaseService,
|
|
||||||
Settings settings,
|
|
||||||
TikTokCollectorService collectorService) {
|
|
||||||
this.databaseService = databaseService;
|
|
||||||
this.settings = settings;
|
|
||||||
this.collectorService = collectorService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void connect(Context context) {
|
|
||||||
var name = context.queryParam("name");
|
|
||||||
var sessionTag = context.queryParam("session");
|
|
||||||
System.out.println("Session tag" + sessionTag);
|
|
||||||
collectorService.start(name, sessionTag);
|
|
||||||
settings.setUserName(name);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connectionStatus(Context context) {
|
|
||||||
var isWorking = collectorService.isRunning();
|
|
||||||
var result = getGson().toJson(isWorking);
|
|
||||||
context.result(result);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disconnect(Context context) {
|
|
||||||
|
|
||||||
collectorService.stop();
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getUsers(Context context) {
|
|
||||||
var users = databaseService.getUsers();
|
|
||||||
var result = getGson().toJson(users);
|
|
||||||
context.result(result);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getUserSessionTags(Context context) {
|
|
||||||
var dataType = context.queryParam("user");
|
|
||||||
var sessionsTags = databaseService.getSessionTag(dataType);
|
|
||||||
|
|
||||||
var result = getGson().toJson(sessionsTags);
|
|
||||||
context.result(result);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getDataTypes(Context context) {
|
|
||||||
var result = getGson().toJson(List.of("event", "message", "response"));
|
|
||||||
context.result(result);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void updateSearch(Context context) {
|
|
||||||
var userName = context.queryParam("user");
|
|
||||||
var sessionTag = context.queryParam("session");
|
|
||||||
|
|
||||||
settings.setUserName(userName);
|
|
||||||
settings.setSessionTag(sessionTag);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getDataNames(Context context) {
|
|
||||||
var dataType = context.queryParam("type");
|
|
||||||
var dataNames = databaseService.getDataNames(dataType, settings.getUserName(), settings.getSessionTag());
|
|
||||||
var gson = getGson();
|
|
||||||
|
|
||||||
|
|
||||||
var result = gson.toJson(dataNames);
|
|
||||||
context.result(result);
|
|
||||||
context.status(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getData(Context context) {
|
|
||||||
var page = context.queryParam("page");
|
|
||||||
var dataType = context.queryParam("type");
|
|
||||||
var dataName = context.queryParam("name");
|
|
||||||
if (page == null) {
|
|
||||||
page = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var asProto = context.queryParam("asProto");
|
|
||||||
var asJson = asProto == null;
|
|
||||||
var dto = new TikTokDatabaseService.DatabaseDataDto(dataType, dataName, settings.getUserName(), settings.getSessionTag(), asJson);
|
|
||||||
var result = databaseService.getData(dto);
|
|
||||||
var content = result.get(Integer.parseInt(page));
|
|
||||||
|
|
||||||
var response = new MessageDto(content, "", dataName);
|
|
||||||
var gson = getGson();
|
|
||||||
context.result(gson.toJson(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getDataPages(Context context) throws InvalidProtocolBufferException {
|
|
||||||
var dataType = context.queryParam("type");
|
|
||||||
var dataName = context.queryParam("name");
|
|
||||||
|
|
||||||
var asJson = true;
|
|
||||||
var dto = new TikTokDatabaseService.DatabaseDataDto(dataType, dataName, settings.getUserName(), settings.getSessionTag(), asJson);
|
|
||||||
var result = databaseService.getData(dto);
|
|
||||||
var counter = new AtomicInteger(-1);
|
|
||||||
var pages = result.stream().map(e ->
|
|
||||||
{
|
|
||||||
return "http://localhost:" + settings.getPort() + "/tiktok/data?type=" + dataType + "&page=" + counter.incrementAndGet() + "&name=" + dataName;
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
var response = new PagesDto(dataName, counter.get(), pages);
|
|
||||||
var gson = getGson();
|
|
||||||
context.result(gson.toJson(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Gson getGson() {
|
|
||||||
return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class PagesDto {
|
|
||||||
String eventName;
|
|
||||||
int pages;
|
|
||||||
List<String> links;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class MessageDto {
|
|
||||||
String content;
|
|
||||||
String base64;
|
|
||||||
String eventName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer.services;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.TikTokLiveTools;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.collector.api.DataCollector;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
import io.github.jwdeveloper.tiktok.webviewer.Settings;
|
|
||||||
|
|
||||||
public class TikTokCollectorService {
|
|
||||||
private final Settings settings;
|
|
||||||
private final TikTokDatabase database;
|
|
||||||
|
|
||||||
private boolean isConnected = false;
|
|
||||||
|
|
||||||
private DataCollector collector;
|
|
||||||
|
|
||||||
public TikTokCollectorService(Settings settings, TikTokDatabase database) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(String user, String sessionTag) {
|
|
||||||
stop();
|
|
||||||
collector = createClient(user, sessionTag);
|
|
||||||
|
|
||||||
collector.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRunning()
|
|
||||||
{
|
|
||||||
if(collector == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
if (collector != null) {
|
|
||||||
collector.disconnect(true);
|
|
||||||
}
|
|
||||||
isConnected =false;
|
|
||||||
collector = null;
|
|
||||||
try {
|
|
||||||
database.close();
|
|
||||||
database.connect();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private DataCollector createClient(String user, String sessionTag) {
|
|
||||||
return TikTokLiveTools.createCollector("dupa")
|
|
||||||
.addUser(user)
|
|
||||||
.setSessionTag(sessionTag)
|
|
||||||
.setDatabase(database)
|
|
||||||
.configureLiveClient(liveClientBuilder ->
|
|
||||||
{
|
|
||||||
liveClientBuilder.configure(clientSettings ->
|
|
||||||
{
|
|
||||||
clientSettings.setPrintToConsole(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
liveClientBuilder.onWebsocketResponse((liveClient, event) ->
|
|
||||||
{
|
|
||||||
for (var msg : event.getResponse().getMessagesList()) {
|
|
||||||
System.out.println(msg.getMethod());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
liveClientBuilder.onDisconnected((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Disconnected");
|
|
||||||
isConnected = false;
|
|
||||||
});
|
|
||||||
liveClientBuilder.onError((liveClient, event) ->
|
|
||||||
{
|
|
||||||
event.getException().printStackTrace();
|
|
||||||
});
|
|
||||||
liveClientBuilder.onConnected((liveClient, event) ->
|
|
||||||
{
|
|
||||||
liveClient.getLogger().info("Connected");
|
|
||||||
isConnected = true;
|
|
||||||
});
|
|
||||||
}).build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package io.github.jwdeveloper.tiktok.webviewer.services;
|
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDataTableDAO;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.TikTokDatabase;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.db.tables.TikTokDataTable;
|
|
||||||
import io.github.jwdeveloper.tiktok.tools.util.MessageUtil;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.JsonUtil;
|
|
||||||
import io.github.jwdeveloper.tiktok.utils.ProtocolUtils;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TikTokDatabaseService {
|
|
||||||
public TikTokDatabase tikTokDatabase;
|
|
||||||
private TikTokDataTableDAO table;
|
|
||||||
|
|
||||||
|
|
||||||
public record DatabaseDataDto(String dataType, String dataName, String user, String sessionTag, boolean asJson) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public TikTokDatabaseService(TikTokDatabase databaseName) {
|
|
||||||
tikTokDatabase = databaseName;
|
|
||||||
table = tikTokDatabase.getDataTableDAO();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getUsers() {
|
|
||||||
return table.getUsers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getSessionTag(String user) {
|
|
||||||
return table.getSessionTagByUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getDataNames(String dataType, String user, String sessionTag) {
|
|
||||||
|
|
||||||
return tikTokDatabase.getDataNames(dataType, sessionTag, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getData(DatabaseDataDto dataDto) {
|
|
||||||
var data = tikTokDatabase.getDataTableDAO().selectSessionData(dataDto.dataType(), dataDto.sessionTag(), dataDto.user());
|
|
||||||
switch (dataDto.dataType()) {
|
|
||||||
case "message" -> {
|
|
||||||
return getMessages(dataDto.dataName(), data, dataDto.asJson);
|
|
||||||
}
|
|
||||||
case "event" -> {
|
|
||||||
return getEvents(dataDto.dataName(), data);
|
|
||||||
}
|
|
||||||
case "response" -> {
|
|
||||||
return getResponse(data,dataDto.dataName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return List.of("unknown dataType");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private List<String> getMessages(String messageName, List<TikTokDataTable> data, boolean asJson) {
|
|
||||||
|
|
||||||
var messages = data.stream()
|
|
||||||
.filter(e -> e.getDataTypeName().equals(messageName))
|
|
||||||
.map(e ->
|
|
||||||
{
|
|
||||||
|
|
||||||
try {
|
|
||||||
var bytes = Base64.getDecoder().decode(e.getContent());
|
|
||||||
if (asJson == false) {
|
|
||||||
return ProtocolUtils.getProtocolBufferStructure(bytes).toJson();
|
|
||||||
}
|
|
||||||
var parsedMessage = MessageUtil.getContent(messageName, bytes);
|
|
||||||
return parsedMessage;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getResponse(List<TikTokDataTable> data,String dataTypeName)
|
|
||||||
{
|
|
||||||
var messages = data.stream()
|
|
||||||
.filter(e -> e.getDataTypeName().equals(dataTypeName))
|
|
||||||
.map(e ->
|
|
||||||
{
|
|
||||||
if(e.getDataTypeName().equals("Http"))
|
|
||||||
{
|
|
||||||
return e.getContent();
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var bytes = Base64.getDecoder().decode(e.getContent());
|
|
||||||
var parsedMessage = WebcastResponse.parseFrom(bytes);
|
|
||||||
var json = JsonUtil.toJson(parsedMessage);
|
|
||||||
return json;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return "error";
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getEvents(String dataName, List<TikTokDataTable> data) {
|
|
||||||
var messages = data.stream()
|
|
||||||
.filter(e -> e.getDataTypeName().equals(dataName))
|
|
||||||
.map(TikTokDataTable::getContent)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,135 +0,0 @@
|
|||||||
body, html {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-btn
|
|
||||||
{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.dropdown
|
|
||||||
{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.dropdown-toggle
|
|
||||||
{
|
|
||||||
background-color: #2c2c2c;
|
|
||||||
border-color: #2c2c2c;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary
|
|
||||||
{
|
|
||||||
background-color: #2c2c2c;
|
|
||||||
border-color: #2c2c2c;
|
|
||||||
}
|
|
||||||
.btn-primary:hover
|
|
||||||
{
|
|
||||||
background-color: #474747;
|
|
||||||
border-color: #474747;
|
|
||||||
}
|
|
||||||
.margin
|
|
||||||
{
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
.form
|
|
||||||
{
|
|
||||||
|
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
border-bottom: 2px solid #676767
|
|
||||||
}
|
|
||||||
.form-label
|
|
||||||
{
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
.editor-parent
|
|
||||||
{
|
|
||||||
height: 2000px;
|
|
||||||
}
|
|
||||||
.editor-container
|
|
||||||
{
|
|
||||||
resize: vertical;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
.list-group-item:hover
|
|
||||||
{
|
|
||||||
background-color: #474747;
|
|
||||||
color: azure;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.list-group-item
|
|
||||||
{
|
|
||||||
background-color: #2c2c2c;
|
|
||||||
color: azure;
|
|
||||||
border-color: #252424;
|
|
||||||
}
|
|
||||||
.margin-left
|
|
||||||
{
|
|
||||||
margin-right: 0.2em;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
flex-grow: 1; /* Takes up the remaining space */
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.col-md-10, .col-md-2 {
|
|
||||||
padding: 0; /* Remove default padding */
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.scrollable-element {
|
|
||||||
|
|
||||||
overflow-y: scroll; /* Enable vertical scrollbar */
|
|
||||||
/* Other styles as needed */
|
|
||||||
scrollbar-width: thin;
|
|
||||||
height: 800px;
|
|
||||||
scrollbar-color: #275c9c #000000; /* thumb and track color */
|
|
||||||
}
|
|
||||||
.dropdown-menu
|
|
||||||
{
|
|
||||||
width: 100%;
|
|
||||||
background-color: #414040;
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
.dropdown-item
|
|
||||||
{
|
|
||||||
-webkit-user-select: none; /* For webkit browsers */
|
|
||||||
-moz-user-select: none; /* For Firefox */
|
|
||||||
-ms-user-select: none; /* For Microsoft browsers */
|
|
||||||
user-select: none; /* Standard syntax */
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item:hover
|
|
||||||
{
|
|
||||||
background-color: #696868;
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item:hover
|
|
||||||
{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 10px; /* Set width of the scrollbar */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: #1e1e23; /* Track color */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: #123054; /* Thumb color */
|
|
||||||
border-radius: 5px; /* Rounded corners */
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user