mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
Changes:
- Implementation on all features in `clientSettings` - Code optimization - More detail exceptions - Downloading gifts
This commit is contained in:
@@ -12,16 +12,7 @@ public class ClientSettings {
|
||||
/// <summary>
|
||||
/// Timeout for Connections
|
||||
/// </summary>
|
||||
|
||||
private Duration timeout;
|
||||
/// <summary>
|
||||
/// Polling-Interval for Socket-Connection
|
||||
/// </summary
|
||||
|
||||
private Duration pollingInterval;
|
||||
/// <summary>
|
||||
/// Proxy for Connection
|
||||
/// </summary>
|
||||
|
||||
// public RotatingProxy Proxy;
|
||||
/// <summary>
|
||||
@@ -35,6 +26,11 @@ public class ClientSettings {
|
||||
/// </summary>
|
||||
private boolean retryOnConnectionFailure;
|
||||
|
||||
/// <summary>
|
||||
/// Wait to connect again for selected amount of time
|
||||
/// </summary>
|
||||
private Duration retryConnectionTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to handle Messages received from Room when Connecting
|
||||
/// </summary>
|
||||
@@ -59,12 +55,6 @@ public class ClientSettings {
|
||||
/// </summary>
|
||||
private boolean printMessageData;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to check Messages for Unparsed Data
|
||||
/// </summary>
|
||||
private boolean checkForUnparsedData;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tiktok user name
|
||||
/// </summary>
|
||||
|
||||
@@ -40,14 +40,13 @@ public class Constants {
|
||||
public static ClientSettings DefaultClientSettings() {
|
||||
var clientSettings = new ClientSettings();
|
||||
clientSettings.setTimeout(Duration.ofSeconds(DEFAULT_TIMEOUT));
|
||||
clientSettings.setPollingInterval(Duration.ofSeconds(DEFAULT_POLLTIME));
|
||||
clientSettings.setClientLanguage("en-US");
|
||||
clientSettings.setHandleExistingMessagesOnConnect(true);
|
||||
clientSettings.setDownloadGiftInfo(true);
|
||||
clientSettings.setRetryOnConnectionFailure(true);
|
||||
clientSettings.setPrintToConsole(true);
|
||||
clientSettings.setRetryOnConnectionFailure(false);
|
||||
clientSettings.setRetryConnectionTimeout(Duration.ofSeconds(1));
|
||||
clientSettings.setPrintToConsole(false);
|
||||
clientSettings.setLogLevel(Level.ALL);
|
||||
clientSettings.setCheckForUnparsedData(false);
|
||||
clientSettings.setPrintMessageData(false);
|
||||
clientSettings.setClientParameters(Constants.DefaultClientParams());
|
||||
return clientSettings;
|
||||
|
||||
@@ -1,95 +1,94 @@
|
||||
package io.github.jwdeveloper.tiktok.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
|
||||
public interface TikTokEventBuilder<T> {
|
||||
T onUnhandledSocial(Consumer<TikTokUnhandledSocialEvent> event);
|
||||
T onUnhandledSocial(TikTokEventConsumer<TikTokUnhandledSocialEvent> event);
|
||||
|
||||
T onLinkMicFanTicket(Consumer<TikTokLinkMicFanTicketEvent> event);
|
||||
T onLinkMicFanTicket(TikTokEventConsumer<TikTokLinkMicFanTicketEvent> event);
|
||||
|
||||
T onEnvelope(Consumer<TikTokEnvelopeEvent> event);
|
||||
T onEnvelope(TikTokEventConsumer<TikTokEnvelopeEvent> event);
|
||||
|
||||
T onShopMessage(Consumer<TikTokShopMessageEvent> event);
|
||||
T onShopMessage(TikTokEventConsumer<TikTokShopMessageEvent> event);
|
||||
|
||||
T onDetectMessage(Consumer<TikTokDetectMessageEvent> event);
|
||||
T onDetectMessage(TikTokEventConsumer<TikTokDetectMessageEvent> event);
|
||||
|
||||
T onLinkLayerMessage(Consumer<TikTokLinkLayerMessageEvent> event);
|
||||
T onLinkLayerMessage(TikTokEventConsumer<TikTokLinkLayerMessageEvent> event);
|
||||
|
||||
T onConnected(Consumer<TikTokConnectedEvent> event);
|
||||
T onConnected(TikTokEventConsumer<TikTokConnectedEvent> event);
|
||||
|
||||
T onCaption(Consumer<TikTokCaptionEvent> event);
|
||||
T onCaption(TikTokEventConsumer<TikTokCaptionEvent> event);
|
||||
|
||||
T onQuestion(Consumer<TikTokQuestionEvent> event);
|
||||
T onQuestion(TikTokEventConsumer<TikTokQuestionEvent> event);
|
||||
|
||||
T onRoomPinMessage(Consumer<TikTokRoomPinMessageEvent> event);
|
||||
T onRoomPinMessage(TikTokEventConsumer<TikTokRoomPinMessageEvent> event);
|
||||
|
||||
T onRoomMessage(Consumer<TikTokRoomMessageEvent> event);
|
||||
T onRoomMessage(TikTokEventConsumer<TikTokRoomMessageEvent> event);
|
||||
|
||||
T onLivePaused(Consumer<TikTokLivePausedEvent> event);
|
||||
T onLivePaused(TikTokEventConsumer<TikTokLivePausedEvent> event);
|
||||
|
||||
T onLike(Consumer<TikTokLikeEvent> event);
|
||||
T onLike(TikTokEventConsumer<TikTokLikeEvent> event);
|
||||
|
||||
T onLinkMessage(Consumer<TikTokLinkMessageEvent> event);
|
||||
T onLinkMessage(TikTokEventConsumer<TikTokLinkMessageEvent> event);
|
||||
|
||||
T onBarrageMessage(Consumer<TikTokBarrageMessageEvent> event);
|
||||
T onBarrageMessage(TikTokEventConsumer<TikTokBarrageMessageEvent> event);
|
||||
|
||||
T onGiftMessage(Consumer<TikTokGiftMessageEvent> event);
|
||||
T onGiftMessage(TikTokEventConsumer<TikTokGiftMessageEvent> event);
|
||||
|
||||
T onLinkMicArmies(Consumer<TikTokLinkMicArmiesEvent> event);
|
||||
T onLinkMicArmies(TikTokEventConsumer<TikTokLinkMicArmiesEvent> event);
|
||||
|
||||
T onEmote(Consumer<TikTokEmoteEvent> event);
|
||||
T onEmote(TikTokEventConsumer<TikTokEmoteEvent> event);
|
||||
|
||||
T onUnauthorizedMember(Consumer<TikTokUnauthorizedMemberEvent> event);
|
||||
T onUnauthorizedMember(TikTokEventConsumer<TikTokUnauthorizedMemberEvent> event);
|
||||
|
||||
T onInRoomBanner(Consumer<TikTokInRoomBannerEvent> event);
|
||||
T onInRoomBanner(TikTokEventConsumer<TikTokInRoomBannerEvent> event);
|
||||
|
||||
T onLinkMicMethod(Consumer<TikTokLinkMicMethodEvent> event);
|
||||
T onLinkMicMethod(TikTokEventConsumer<TikTokLinkMicMethodEvent> event);
|
||||
|
||||
T onSubscribe(Consumer<TikTokSubscribeEvent> event);
|
||||
T onSubscribe(TikTokEventConsumer<TikTokSubscribeEvent> event);
|
||||
|
||||
T onPollMessage(Consumer<TikTokPollMessageEvent> event);
|
||||
T onPollMessage(TikTokEventConsumer<TikTokPollMessageEvent> event);
|
||||
|
||||
T onFollow(Consumer<TikTokFollowEvent> event);
|
||||
T onFollow(TikTokEventConsumer<TikTokFollowEvent> event);
|
||||
|
||||
T onRoomViewerData(Consumer<TikTokRoomViewerDataEvent> event);
|
||||
T onRoomViewerData(TikTokEventConsumer<TikTokRoomViewerDataEvent> event);
|
||||
|
||||
T onGoalUpdate(Consumer<TikTokGoalUpdateEvent> event);
|
||||
T onGoalUpdate(TikTokEventConsumer<TikTokGoalUpdateEvent> event);
|
||||
|
||||
T onComment(Consumer<TikTokCommentEvent> event);
|
||||
T onComment(TikTokEventConsumer<TikTokCommentEvent> event);
|
||||
|
||||
T onRankUpdate(Consumer<TikTokRankUpdateEvent> event);
|
||||
T onRankUpdate(TikTokEventConsumer<TikTokRankUpdateEvent> event);
|
||||
|
||||
T onIMDelete(Consumer<TikTokIMDeleteEvent> event);
|
||||
T onIMDelete(TikTokEventConsumer<TikTokIMDeleteEvent> event);
|
||||
|
||||
T onLiveEnded(Consumer<TikTokLiveEndedEvent> event);
|
||||
T onLiveEnded(TikTokEventConsumer<TikTokLiveEndedEvent> event);
|
||||
|
||||
T onError(Consumer<TikTokErrorEvent> event);
|
||||
T onError(TikTokEventConsumer<TikTokErrorEvent> event);
|
||||
|
||||
T onUnhandled(Consumer<TikTokUnhandledEvent> event);
|
||||
T onUnhandled(TikTokEventConsumer<TikTokUnhandledEvent> event);
|
||||
|
||||
T onJoin(Consumer<TikTokJoinEvent> event);
|
||||
T onJoin(TikTokEventConsumer<TikTokJoinEvent> event);
|
||||
|
||||
T onRankText(Consumer<TikTokRankTextEvent> event);
|
||||
T onRankText(TikTokEventConsumer<TikTokRankTextEvent> event);
|
||||
|
||||
T onShare(Consumer<TikTokShareEvent> event);
|
||||
T onShare(TikTokEventConsumer<TikTokShareEvent> event);
|
||||
|
||||
T onUnhandledMember(Consumer<TikTokUnhandledMemberEvent> event);
|
||||
T onUnhandledMember(TikTokEventConsumer<TikTokUnhandledMemberEvent> event);
|
||||
|
||||
T onSubNotify(Consumer<TikTokSubNotifyEvent> event);
|
||||
T onSubNotify(TikTokEventConsumer<TikTokSubNotifyEvent> event);
|
||||
|
||||
T onLinkMicBattle(Consumer<TikTokLinkMicBattleEvent> event);
|
||||
T onLinkMicBattle(TikTokEventConsumer<TikTokLinkMicBattleEvent> event);
|
||||
|
||||
T onDisconnected(Consumer<TikTokDisconnectedEvent> event);
|
||||
T onDisconnected(TikTokEventConsumer<TikTokDisconnectedEvent> event);
|
||||
|
||||
T onGiftBroadcast(Consumer<TikTokGiftBroadcastEvent> event);
|
||||
T onGiftBroadcast(TikTokEventConsumer<TikTokGiftBroadcastEvent> event);
|
||||
|
||||
T onUnhandledControl(Consumer<TikTokUnhandledControlEvent> event);
|
||||
T onUnhandledControl(TikTokEventConsumer<TikTokUnhandledControlEvent> event);
|
||||
|
||||
T onEvent(Consumer<TikTokEvent> event);
|
||||
T onEvent(TikTokEventConsumer<TikTokEvent> event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.github.jwdeveloper.tiktok.events;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
|
||||
public interface TikTokLiveEvent<T extends TikTokEvent>
|
||||
public interface TikTokEventConsumer<T extends TikTokEvent>
|
||||
{
|
||||
void onEvent(LiveClient liveClient, T event);
|
||||
}
|
||||
@@ -3,38 +3,39 @@ package io.github.jwdeveloper.tiktok.events.messages;
|
||||
import io.github.jwdeveloper.tiktok.annotations.Nullable;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.objects.Gift;
|
||||
import io.github.jwdeveloper.tiktok.events.objects.TikTokGift;
|
||||
import io.github.jwdeveloper.tiktok.events.objects.User;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastGiftMessage;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class TikTokGiftMessageEvent extends TikTokEvent {
|
||||
private final Gift gift;
|
||||
|
||||
@Nullable
|
||||
private User sender;
|
||||
private final Gift gift;
|
||||
|
||||
private final String purchaseId;
|
||||
@Nullable
|
||||
private User sender;
|
||||
|
||||
private final String receipt;
|
||||
private final String purchaseId;
|
||||
|
||||
private final Integer amount;
|
||||
private final String receipt;
|
||||
|
||||
private final Boolean streakFinished;
|
||||
private final Integer amount;
|
||||
|
||||
private final Integer streakIndex;
|
||||
private final Boolean streakFinished;
|
||||
|
||||
public TikTokGiftMessageEvent(WebcastGiftMessage msg) {
|
||||
super(msg.getHeader());;
|
||||
gift = new Gift(msg.getGiftDetails());
|
||||
if(msg.hasSender())
|
||||
{
|
||||
sender = new User(msg.getSender());
|
||||
private final Integer streakIndex;
|
||||
|
||||
public TikTokGiftMessageEvent(WebcastGiftMessage msg) {
|
||||
super(msg.getHeader());
|
||||
gift = new Gift(msg.getGiftDetails());
|
||||
if (msg.hasSender()) {
|
||||
sender = new User(msg.getSender());
|
||||
}
|
||||
purchaseId = msg.getLogId();
|
||||
receipt = msg.getReceiptJson();
|
||||
amount = msg.getAmount();
|
||||
streakFinished = msg.getRepeatEnd();
|
||||
streakIndex = msg.getRepeatCount();
|
||||
}
|
||||
purchaseId = msg.getLogId();
|
||||
receipt = msg.getReceiptJson();
|
||||
amount = msg.getAmount();
|
||||
streakFinished = msg.getRepeatEnd();
|
||||
streakIndex = msg.getRepeatCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,15 @@ public class TikTokRankUpdateEvent extends TikTokEvent {
|
||||
var rankData = msg.getData().getRankings();
|
||||
eventType = rankData.getType();
|
||||
label = rankData.getLabel();
|
||||
rank = rankData.getDetails(0).getLabel();
|
||||
if(rankData.getDetailsList().isEmpty())
|
||||
{
|
||||
rank = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
rank = rankData.getDetails(0).getLabel();
|
||||
}
|
||||
color = rankData.getColor().getColor();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public TikTokRankUpdateEvent(WebcastRankUpdateMessage msg) {
|
||||
@@ -31,7 +36,14 @@ public class TikTokRankUpdateEvent extends TikTokEvent {
|
||||
var rankData = msg.getData().getRankData();
|
||||
eventType = rankData.getType();
|
||||
label = rankData.getLabel();
|
||||
rank = rankData.getDetails(0).getLabel();
|
||||
if(rankData.getDetailsList().isEmpty())
|
||||
{
|
||||
rank = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
rank = rankData.getDetails(0).getLabel();
|
||||
}
|
||||
color = rankData.getColor().getColor();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.github.jwdeveloper.tiktok.exceptions;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
public class TikTokLiveMessageException extends TikTokLiveException {
|
||||
|
||||
@Getter
|
||||
private final WebcastResponse.Message webcastMessage;
|
||||
@Getter
|
||||
private final WebcastResponse webcastResponse;
|
||||
|
||||
|
||||
public TikTokLiveMessageException(WebcastResponse.Message message,
|
||||
WebcastResponse webcastResponse,
|
||||
Throwable cause) {
|
||||
super("Error while handling Message: " + message.getType() + ": \n", cause);
|
||||
this.webcastMessage = message;
|
||||
this.webcastResponse = webcastResponse;
|
||||
}
|
||||
|
||||
public void messageToBase64()
|
||||
{
|
||||
var decoded = Base64.getEncoder().encodeToString(webcastMessage.getBinary().toByteArray());
|
||||
}
|
||||
|
||||
public void webcastResponseToBase64()
|
||||
{
|
||||
var decoded = Base64.getEncoder().encodeToString(webcastResponse.toByteArray());
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok.exceptions;
|
||||
|
||||
public class TikTokLiveMessageParsingException extends TikTokLiveException
|
||||
{
|
||||
public TikTokLiveMessageParsingException() {
|
||||
}
|
||||
|
||||
public TikTokLiveMessageParsingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TikTokLiveMessageParsingException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public TikTokLiveMessageParsingException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public TikTokLiveMessageParsingException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.github.jwdeveloper.tiktok.exceptions;
|
||||
|
||||
public class TikTokLiveOfflineHostException extends TikTokLiveException
|
||||
{
|
||||
public TikTokLiveOfflineHostException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.jwdeveloper.tiktok.exceptions;
|
||||
|
||||
|
||||
public class TikTokMessageMappingException extends TikTokLiveException
|
||||
{
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, Throwable throwable)
|
||||
{
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName(),throwable);
|
||||
}
|
||||
|
||||
public TikTokMessageMappingException(Class<?> inputClazz, Class<?> outputClass, String message)
|
||||
{
|
||||
super("Unable to handle mapping from class: " + inputClazz.getSimpleName() + " to class " + outputClass.getSimpleName()+": "+message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.github.jwdeveloper.tiktok.exceptions;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class TikTokProtocolBufferException extends TikTokLiveException
|
||||
{
|
||||
@Getter
|
||||
private final byte[] bytes;
|
||||
|
||||
public TikTokProtocolBufferException(String message, byte[] bytes, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
this.bytes = bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package io.github.jwdeveloper.tiktok.handler;
|
||||
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
|
||||
public interface TikTokMessageHandler
|
||||
{
|
||||
TikTokEvent handle(WebcastResponse.Message message) throws Exception;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok.http.Resource;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ClientFetchDataResponse {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.github.jwdeveloper.tiktok.live;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.objects.TikTokGift;
|
||||
import io.github.jwdeveloper.tiktok.models.GiftId;
|
||||
import io.github.jwdeveloper.tiktok.models.gifts.TikTokGiftInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface GiftManager
|
||||
{
|
||||
Map<Integer, TikTokGiftInfo> getGiftsInfo();
|
||||
|
||||
Map<GiftId, TikTokGift> getActiveGifts();
|
||||
}
|
||||
@@ -6,5 +6,6 @@ public interface LiveClient {
|
||||
|
||||
void disconnect();
|
||||
|
||||
GiftManager getGiftManager();
|
||||
LiveRoomInfo getRoomInfo();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
@AllArgsConstructor
|
||||
public class GiftId
|
||||
{
|
||||
public long Gift;
|
||||
private long giftId;
|
||||
|
||||
public String UserName;
|
||||
private String userName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package io.github.jwdeveloper.tiktok.models;
|
||||
|
||||
public enum GiftStrike
|
||||
{
|
||||
BEGIN, UPDATE, ENDED
|
||||
}
|
||||
@@ -3,14 +3,13 @@ package io.github.jwdeveloper.tiktok.models.gifts;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DefaultFormat
|
||||
{
|
||||
private boolean bold ;
|
||||
private String color ;
|
||||
private int font_size ;
|
||||
private boolean italic ;
|
||||
private int italic_angle ;
|
||||
private boolean use_highlight_color ;
|
||||
private boolean use_remote_color ;
|
||||
private int weight ;
|
||||
public class DefaultFormat {
|
||||
private boolean bold;
|
||||
private String color;
|
||||
private int font_size;
|
||||
private boolean italic;
|
||||
private int italic_angle;
|
||||
private boolean use_highlight_color;
|
||||
private boolean use_remote_color;
|
||||
private int weight;
|
||||
}
|
||||
@@ -5,10 +5,9 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class DisplayText
|
||||
{
|
||||
private DefaultFormat default_format ;
|
||||
private String default_pattern ;
|
||||
private String key ;
|
||||
private List<Object> pieces ;
|
||||
public class DisplayText {
|
||||
private DefaultFormat default_format;
|
||||
private String default_pattern;
|
||||
private String key;
|
||||
private List<Object> pieces;
|
||||
}
|
||||
@@ -5,14 +5,13 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class GiftLabelIcon
|
||||
{
|
||||
private String avg_color ;
|
||||
private int height ;
|
||||
private int image_type ;
|
||||
private boolean is_animated ;
|
||||
private String open_web_url ;
|
||||
private String uri ;
|
||||
private List<String> url_list ;
|
||||
private int width ;
|
||||
public class GiftLabelIcon {
|
||||
private String avg_color;
|
||||
private int height;
|
||||
private int image_type;
|
||||
private boolean is_animated;
|
||||
private String open_web_url;
|
||||
private String uri;
|
||||
private List<String> url_list;
|
||||
private int width;
|
||||
}
|
||||
@@ -6,10 +6,9 @@ import java.util.List;
|
||||
|
||||
|
||||
@Data
|
||||
public class GiftPanelBanner
|
||||
{
|
||||
private List<Object> bg_color_values ;
|
||||
private DisplayText display_text ;
|
||||
private LeftIcon left_icon ;
|
||||
private String schema_url ;
|
||||
public class GiftPanelBanner {
|
||||
private List<Object> bg_color_values;
|
||||
private DisplayText display_text;
|
||||
private LeftIcon left_icon;
|
||||
private String schema_url;
|
||||
}
|
||||
@@ -5,14 +5,13 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class Image
|
||||
{
|
||||
private String avg_color ;
|
||||
private int height ;
|
||||
private int image_type ;
|
||||
private boolean is_animated ;
|
||||
private String open_web_url ;
|
||||
private String uri ;
|
||||
private List<String> url_list ;
|
||||
private int width ;
|
||||
public class Image {
|
||||
private String avg_color;
|
||||
private int height;
|
||||
private int image_type;
|
||||
private boolean is_animated;
|
||||
private String open_web_url;
|
||||
private String uri;
|
||||
private List<String> url_list;
|
||||
private int width;
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class LeftIcon
|
||||
{
|
||||
private String avg_color ;
|
||||
private int height ;
|
||||
private int image_type ;
|
||||
private boolean is_animated ;
|
||||
private String open_web_url ;
|
||||
private String uri ;
|
||||
private List<String> url_list ;
|
||||
private int width ;
|
||||
public class LeftIcon {
|
||||
private String avg_color;
|
||||
private int height;
|
||||
private int image_type;
|
||||
private boolean is_animated;
|
||||
private String open_web_url;
|
||||
private String uri;
|
||||
private List<String> url_list;
|
||||
private int width;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package io.github.jwdeveloper.tiktok.models.gifts;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LockInfo
|
||||
{
|
||||
public int lock_type;
|
||||
private int lock_type;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TikTokGift
|
||||
public class TikTokGiftInfo
|
||||
{
|
||||
private int action_type;
|
||||
private int app_id;
|
||||
@@ -1,45 +1,47 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.objects.TikTokGift;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.live.GiftManager;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastGiftMessage;
|
||||
import io.github.jwdeveloper.tiktok.models.GiftId;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.models.gifts.TikTokGiftInfo;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class TikTokGiftManager {
|
||||
private Logger logger;
|
||||
private ClientSettings clientSettings;
|
||||
private TikTokApiService apiService;
|
||||
private Map<Integer, TikTokGift> gifts;
|
||||
public class TikTokGiftManager implements GiftManager {
|
||||
|
||||
@Getter
|
||||
private Map<GiftId, TikTokGift> activeGifts;
|
||||
private final Map<Integer, TikTokGiftInfo> giftsInfo;
|
||||
@Getter
|
||||
private final Map<GiftId, TikTokGift> activeGifts;
|
||||
|
||||
public TikTokGiftManager(Logger logger, TikTokApiService apiService, ClientSettings clientSettings) {
|
||||
this.logger = logger;
|
||||
this.clientSettings = clientSettings;
|
||||
this.apiService = apiService;
|
||||
this.gifts = new HashMap<>();
|
||||
public TikTokGiftManager() {
|
||||
giftsInfo = new HashMap<>();
|
||||
activeGifts = new HashMap<>();
|
||||
}
|
||||
|
||||
public void loadGifts() {
|
||||
if (!clientSettings.isDownloadGiftInfo()) {
|
||||
return;
|
||||
public TikTokGift updateActiveGift(WebcastGiftMessage giftMessage) {
|
||||
var giftId = new GiftId(giftMessage.getGiftId(), giftMessage.getSender().getUniqueId());
|
||||
if (activeGifts.containsKey(giftId)) {
|
||||
var gift = activeGifts.get(giftId);
|
||||
gift.setAmount(giftMessage.getAmount());
|
||||
} else {
|
||||
var newGift = new TikTokGift(giftMessage);
|
||||
activeGifts.put(giftId, newGift);
|
||||
}
|
||||
logger.info("Fetching gifts");
|
||||
//TODO gifts =apiService.fetchAvailableGifts();
|
||||
|
||||
var gift = activeGifts.get(giftId);
|
||||
|
||||
if (giftMessage.getRepeatEnd()) {
|
||||
gift.setStreakFinished(true);
|
||||
activeGifts.remove(giftId);
|
||||
}
|
||||
return gift;
|
||||
}
|
||||
|
||||
public List<TikTokGift> getGifts()
|
||||
{
|
||||
return gifts.values().stream().toList();
|
||||
public void loadGifsInfo(Map<Integer, TikTokGiftInfo> gifts) {
|
||||
this.giftsInfo.putAll(gifts);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,53 +1,70 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.live.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.live.GiftManager;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.live.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class TikTokLiveClient implements LiveClient {
|
||||
private final TikTokRoomInfo meta;
|
||||
private final TikTokGiftManager giftManager;
|
||||
private final TikTokRoomInfo liveRoomInfo;
|
||||
private final TikTokGiftManager tikTokGiftManager;
|
||||
private final TikTokApiService apiClient;
|
||||
private final TikTokWebSocketClient webSocketClient;
|
||||
private final TikTokEventHandler tikTokEventHandler;
|
||||
private final ClientSettings clientSettings;
|
||||
private final Logger logger;
|
||||
|
||||
|
||||
public TikTokLiveClient(TikTokRoomInfo tikTokLiveMeta,
|
||||
TikTokApiService tikTokApiService,
|
||||
TikTokWebSocketClient webSocketClient,
|
||||
TikTokGiftManager tikTokGiftManager,
|
||||
TikTokEventHandler tikTokEventHandler,
|
||||
ClientSettings clientSettings,
|
||||
Logger logger) {
|
||||
this.meta = tikTokLiveMeta;
|
||||
this.giftManager = tikTokGiftManager;
|
||||
this.liveRoomInfo = tikTokLiveMeta;
|
||||
this.tikTokGiftManager = tikTokGiftManager;
|
||||
this.apiClient = tikTokApiService;
|
||||
this.webSocketClient = webSocketClient;
|
||||
this.logger = logger;
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
this.clientSettings = clientSettings;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void connect() {
|
||||
try {
|
||||
tryConnect();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (TikTokLiveException e)
|
||||
{
|
||||
setState(ConnectionState.DISCONNECTED);
|
||||
tikTokEventHandler.publish(this, new TikTokErrorEvent(e));
|
||||
tikTokEventHandler.publish(this, new TikTokDisconnectedEvent());
|
||||
|
||||
if(e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure())
|
||||
{
|
||||
try {
|
||||
Thread.sleep(clientSettings.getRetryConnectionTimeout().toMillis());
|
||||
}
|
||||
catch (Exception ignored){}
|
||||
logger.info("Reconnecting");
|
||||
this.connect();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (!meta.hasConnectionState(ConnectionState.CONNECTED)) {
|
||||
if (!liveRoomInfo.hasConnectionState(ConnectionState.CONNECTED)) {
|
||||
return;
|
||||
}
|
||||
webSocketClient.stop();
|
||||
@@ -55,40 +72,48 @@ public class TikTokLiveClient implements LiveClient {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void tryConnect() {
|
||||
if (meta.hasConnectionState(ConnectionState.CONNECTED))
|
||||
if (liveRoomInfo.hasConnectionState(ConnectionState.CONNECTED))
|
||||
throw new TikTokLiveException("Already connected");
|
||||
if (meta.hasConnectionState(ConnectionState.CONNECTING))
|
||||
if (liveRoomInfo.hasConnectionState(ConnectionState.CONNECTING))
|
||||
throw new TikTokLiveException("Already connecting");
|
||||
|
||||
logger.info("Connecting");
|
||||
setState(ConnectionState.CONNECTING);
|
||||
|
||||
var roomId = apiClient.fetchRoomId(meta.getUserName());
|
||||
meta.setRoomId(roomId);
|
||||
var roomData =apiClient.fetchRoomInfo();
|
||||
if (roomData.getStatus() == 0 || roomData.getStatus() == 4)
|
||||
{
|
||||
throw new TikTokLiveException("LiveStream for HostID could not be found. Is the Host online?");
|
||||
var roomId = apiClient.fetchRoomId(liveRoomInfo.getUserName());
|
||||
liveRoomInfo.setRoomId(roomId);
|
||||
var roomData = apiClient.fetchRoomInfo();
|
||||
if (roomData.getStatus() == 0 || roomData.getStatus() == 4) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for HostID could not be found. Is the Host online?");
|
||||
}
|
||||
|
||||
// giftManager.loadGifts();
|
||||
if (clientSettings.isDownloadGiftInfo())
|
||||
{
|
||||
logger.info("Fetch Gift info");
|
||||
var gifts = apiClient.fetchAvailableGifts();
|
||||
tikTokGiftManager.loadGifsInfo(gifts);
|
||||
}
|
||||
var clientData = apiClient.fetchClientData();
|
||||
webSocketClient.start(clientData);
|
||||
webSocketClient.start(clientData, this);
|
||||
setState(ConnectionState.CONNECTED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public LiveRoomInfo getRoomInfo() {
|
||||
return meta;
|
||||
return liveRoomInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GiftManager getGiftManager() {
|
||||
return tikTokGiftManager;
|
||||
}
|
||||
|
||||
|
||||
private void setState(ConnectionState connectionState) {
|
||||
logger.info("TikTokLive client state: " + connectionState.name());
|
||||
meta.setConnectionState(connectionState);
|
||||
liveRoomInfo.setConnectionState(connectionState);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,19 +2,21 @@ package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEventBuilder;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
import io.github.jwdeveloper.tiktok.handlers.WebResponseHandler;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokCookieJar;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpApiClient;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpRequestFactory;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveClientBuilder> {
|
||||
@@ -40,18 +42,13 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
clientSettings.setTimeout(Duration.ofSeconds(Constants.DEFAULT_TIMEOUT));
|
||||
}
|
||||
|
||||
if (clientSettings.getPollingInterval() == null) {
|
||||
clientSettings.setPollingInterval(Duration.ofSeconds(Constants.DEFAULT_POLLTIME));
|
||||
}
|
||||
|
||||
if (clientSettings.getClientLanguage() == null || clientSettings.getClientLanguage().equals("")) {
|
||||
clientSettings.setClientLanguage(Constants.DefaultClientSettings().getClientLanguage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (clientSettings.getHostName() == null || clientSettings.getHostName() .equals("")) {
|
||||
throw new RuntimeException("HostName can not be null");
|
||||
if (clientSettings.getHostName() == null || clientSettings.getHostName().equals("")) {
|
||||
throw new TikTokLiveException("HostName can not be null");
|
||||
}
|
||||
|
||||
var params = clientSettings.getClientParameters();
|
||||
@@ -59,22 +56,27 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
params.put("webcast_language", clientSettings.getClientLanguage());
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
if(clientSettings.isPrintToConsole() && clientSettings.getLogLevel() == Level.OFF)
|
||||
{
|
||||
logger.setLevel(Level.ALL);
|
||||
}
|
||||
}
|
||||
|
||||
public LiveClient build() {
|
||||
validate();
|
||||
|
||||
|
||||
var meta = new TikTokRoomInfo();
|
||||
meta.setUserName(clientSettings.getHostName());
|
||||
var tiktokRoomInfo = new TikTokRoomInfo();
|
||||
tiktokRoomInfo.setUserName(clientSettings.getHostName());
|
||||
|
||||
|
||||
var cookieJar = new TikTokCookieJar();
|
||||
var requestFactory = new TikTokHttpRequestFactory(cookieJar);
|
||||
var apiClient = new TikTokHttpApiClient(cookieJar, requestFactory);
|
||||
var apiService = new TikTokApiService(apiClient, logger, clientSettings);
|
||||
var giftManager = new TikTokGiftManager(logger, apiService, clientSettings);
|
||||
var webResponseHandler = new WebResponseHandler(tikTokEventHandler,giftManager);
|
||||
var giftManager = new TikTokGiftManager();
|
||||
var webResponseHandler = new TikTokMessageHandlerRegistration(tikTokEventHandler, clientSettings, logger, giftManager, tiktokRoomInfo);
|
||||
var webSocketClient = new TikTokWebSocketClient(logger,
|
||||
cookieJar,
|
||||
requestFactory,
|
||||
@@ -82,7 +84,7 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
webResponseHandler,
|
||||
tikTokEventHandler);
|
||||
|
||||
return new TikTokLiveClient(meta, apiService, webSocketClient, giftManager, tikTokEventHandler, logger);
|
||||
return new TikTokLiveClient(tiktokRoomInfo, apiService, webSocketClient, giftManager, tikTokEventHandler, clientSettings, logger);
|
||||
}
|
||||
|
||||
public LiveClient buildAndRun() {
|
||||
@@ -91,214 +93,230 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
return client;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledSocial(Consumer<TikTokUnhandledSocialEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledSocialEvent.class,event);
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledSocial(
|
||||
TikTokEventConsumer<TikTokUnhandledSocialEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledSocialEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMicFanTicket(Consumer<TikTokLinkMicFanTicketEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicFanTicketEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkMicFanTicket(
|
||||
TikTokEventConsumer<TikTokLinkMicFanTicketEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicFanTicketEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onEnvelope(Consumer<TikTokEnvelopeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEnvelopeEvent.class,event);
|
||||
public TikTokLiveClientBuilder onEnvelope(TikTokEventConsumer<TikTokEnvelopeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEnvelopeEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onShopMessage(Consumer<TikTokShopMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokShopMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onShopMessage(TikTokEventConsumer<TikTokShopMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokShopMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onDetectMessage(Consumer<TikTokDetectMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokDetectMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onDetectMessage(
|
||||
TikTokEventConsumer<TikTokDetectMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokDetectMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkLayerMessage(Consumer<TikTokLinkLayerMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkLayerMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkLayerMessage(
|
||||
TikTokEventConsumer<TikTokLinkLayerMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkLayerMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onConnected(Consumer<TikTokConnectedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokConnectedEvent.class,event);
|
||||
public TikTokLiveClientBuilder onConnected(TikTokEventConsumer<TikTokConnectedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokConnectedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onCaption(Consumer<TikTokCaptionEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCaptionEvent.class,event);
|
||||
public TikTokLiveClientBuilder onCaption(TikTokEventConsumer<TikTokCaptionEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCaptionEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onQuestion(Consumer<TikTokQuestionEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokQuestionEvent.class,event);
|
||||
public TikTokLiveClientBuilder onQuestion(TikTokEventConsumer<TikTokQuestionEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokQuestionEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRoomPinMessage(Consumer<TikTokRoomPinMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomPinMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onRoomPinMessage(
|
||||
TikTokEventConsumer<TikTokRoomPinMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomPinMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRoomMessage(Consumer<TikTokRoomMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onRoomMessage(TikTokEventConsumer<TikTokRoomMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLivePaused(Consumer<TikTokLivePausedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLivePausedEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLivePaused(TikTokEventConsumer<TikTokLivePausedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLivePausedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLike(Consumer<TikTokLikeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLikeEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLike(TikTokEventConsumer<TikTokLikeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLikeEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMessage(Consumer<TikTokLinkMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkMessage(TikTokEventConsumer<TikTokLinkMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onBarrageMessage(Consumer<TikTokBarrageMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokBarrageMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onBarrageMessage(
|
||||
TikTokEventConsumer<TikTokBarrageMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokBarrageMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onGiftMessage(Consumer<TikTokGiftMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onGiftMessage(TikTokEventConsumer<TikTokGiftMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMicArmies(Consumer<TikTokLinkMicArmiesEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicArmiesEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkMicArmies(
|
||||
TikTokEventConsumer<TikTokLinkMicArmiesEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicArmiesEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onEmote(Consumer<TikTokEmoteEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEmoteEvent.class,event);
|
||||
public TikTokLiveClientBuilder onEmote(TikTokEventConsumer<TikTokEmoteEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEmoteEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnauthorizedMember(
|
||||
Consumer<TikTokUnauthorizedMemberEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnauthorizedMemberEvent.class,event);
|
||||
TikTokEventConsumer<TikTokUnauthorizedMemberEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnauthorizedMemberEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onInRoomBanner(Consumer<TikTokInRoomBannerEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokInRoomBannerEvent.class,event);
|
||||
public TikTokLiveClientBuilder onInRoomBanner(
|
||||
TikTokEventConsumer<TikTokInRoomBannerEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokInRoomBannerEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMicMethod(Consumer<TikTokLinkMicMethodEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicMethodEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkMicMethod(
|
||||
TikTokEventConsumer<TikTokLinkMicMethodEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicMethodEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onSubscribe(Consumer<TikTokSubscribeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokSubscribeEvent.class,event);
|
||||
public TikTokLiveClientBuilder onSubscribe(TikTokEventConsumer<TikTokSubscribeEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokSubscribeEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onPollMessage(Consumer<TikTokPollMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokPollMessageEvent.class,event);
|
||||
public TikTokLiveClientBuilder onPollMessage(TikTokEventConsumer<TikTokPollMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokPollMessageEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onFollow(Consumer<TikTokFollowEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokFollowEvent.class,event);
|
||||
public TikTokLiveClientBuilder onFollow(TikTokEventConsumer<TikTokFollowEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokFollowEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRoomViewerData(Consumer<TikTokRoomViewerDataEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomViewerDataEvent.class,event);
|
||||
public TikTokLiveClientBuilder onRoomViewerData(
|
||||
TikTokEventConsumer<TikTokRoomViewerDataEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRoomViewerDataEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onGoalUpdate(Consumer<TikTokGoalUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class,event);
|
||||
public TikTokLiveClientBuilder onGoalUpdate(TikTokEventConsumer<TikTokGoalUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onComment(Consumer<TikTokCommentEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class,event);
|
||||
public TikTokLiveClientBuilder onComment(TikTokEventConsumer<TikTokCommentEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRankUpdate(Consumer<TikTokRankUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class,event);
|
||||
public TikTokLiveClientBuilder onRankUpdate(TikTokEventConsumer<TikTokRankUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onIMDelete(Consumer<TikTokIMDeleteEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokIMDeleteEvent.class,event);
|
||||
public TikTokLiveClientBuilder onIMDelete(TikTokEventConsumer<TikTokIMDeleteEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokIMDeleteEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLiveEnded(Consumer<TikTokLiveEndedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLiveEndedEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLiveEnded(TikTokEventConsumer<TikTokLiveEndedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLiveEndedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onError(Consumer<TikTokErrorEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokErrorEvent.class,event);
|
||||
public TikTokLiveClientBuilder onError(TikTokEventConsumer<TikTokErrorEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokErrorEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandled(Consumer<TikTokUnhandledEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledEvent.class,event);
|
||||
public TikTokLiveClientBuilder onUnhandled(TikTokEventConsumer<TikTokUnhandledEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onJoin(Consumer<TikTokJoinEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokJoinEvent.class,event);
|
||||
public TikTokLiveClientBuilder onJoin(TikTokEventConsumer<TikTokJoinEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokJoinEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRankText(Consumer<TikTokRankTextEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankTextEvent.class,event);
|
||||
public TikTokLiveClientBuilder onRankText(TikTokEventConsumer<TikTokRankTextEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankTextEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onShare(Consumer<TikTokShareEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokShareEvent.class,event);
|
||||
public TikTokLiveClientBuilder onShare(TikTokEventConsumer<TikTokShareEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokShareEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledMember(Consumer<TikTokUnhandledMemberEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledMemberEvent.class,event);
|
||||
public TikTokLiveClientBuilder onUnhandledMember(
|
||||
TikTokEventConsumer<TikTokUnhandledMemberEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledMemberEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onSubNotify(Consumer<TikTokSubNotifyEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokSubNotifyEvent.class,event);
|
||||
public TikTokLiveClientBuilder onSubNotify(TikTokEventConsumer<TikTokSubNotifyEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokSubNotifyEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onLinkMicBattle(Consumer<TikTokLinkMicBattleEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicBattleEvent.class,event);
|
||||
public TikTokLiveClientBuilder onLinkMicBattle(
|
||||
TikTokEventConsumer<TikTokLinkMicBattleEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokLinkMicBattleEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onDisconnected(Consumer<TikTokDisconnectedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokDisconnectedEvent.class,event);
|
||||
public TikTokLiveClientBuilder onDisconnected(
|
||||
TikTokEventConsumer<TikTokDisconnectedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokDisconnectedEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onGiftBroadcast(Consumer<TikTokGiftBroadcastEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftBroadcastEvent.class,event);
|
||||
public TikTokLiveClientBuilder onGiftBroadcast(
|
||||
TikTokEventConsumer<TikTokGiftBroadcastEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftBroadcastEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledControl(Consumer<TikTokUnhandledControlEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledControlEvent.class,event);
|
||||
public TikTokLiveClientBuilder onUnhandledControl(
|
||||
TikTokEventConsumer<TikTokUnhandledControlEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokUnhandledControlEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onEvent(Consumer<TikTokEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEvent.class,event);
|
||||
public TikTokLiveClientBuilder onEvent(TikTokEventConsumer<TikTokEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -306,3 +324,6 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.github.jwdeveloper.tiktok.live;
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.live.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@@ -1,40 +1,38 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEventConsumer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TikTokEventHandler {
|
||||
private final Map<String, Consumer> events;
|
||||
public class TikTokEventHandler {
|
||||
private final Map<String, TikTokEventConsumer> events;
|
||||
|
||||
public TikTokEventHandler()
|
||||
{
|
||||
public TikTokEventHandler() {
|
||||
events = new HashMap<>();
|
||||
}
|
||||
|
||||
public void publish(TikTokEvent tikTokEvent)
|
||||
{
|
||||
if(events.containsKey(TikTokEvent.class.getSimpleName()))
|
||||
{
|
||||
public void publish(TikTokLiveClient tikTokLiveClient, TikTokEvent tikTokEvent) {
|
||||
if (events.containsKey(TikTokEvent.class.getSimpleName())) {
|
||||
var handler = events.get(TikTokEvent.class.getSimpleName());
|
||||
handler.accept(tikTokEvent);
|
||||
handler.onEvent(tikTokLiveClient, tikTokEvent);
|
||||
}
|
||||
|
||||
var name = tikTokEvent.getClass().getSimpleName();
|
||||
if(!events.containsKey(name))
|
||||
{
|
||||
if (!events.containsKey(name)) {
|
||||
return;
|
||||
}
|
||||
var handler = events.get(name);
|
||||
handler.accept(tikTokEvent);
|
||||
handler.onEvent(tikTokLiveClient, tikTokEvent);
|
||||
}
|
||||
|
||||
public <T extends TikTokEvent> void subscribe(Class<?> clazz, Consumer<T> event)
|
||||
{
|
||||
events.put(clazz.getSimpleName(),event);
|
||||
public <T extends TikTokEvent> void subscribe(Class<?> clazz, TikTokEventConsumer<T> event) {
|
||||
events.put(clazz.getSimpleName(), event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public <T extends TikTokEvent> void unsubscribe(Class<?> clazz) {
|
||||
events.remove(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,97 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers;
|
||||
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokUnhandledEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
|
||||
public interface TikTokMessageHandler<T>
|
||||
{
|
||||
Class<T> getHandleClazz();
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
TikTokEvent handle(WebcastResponse.Message message) throws Exception;
|
||||
|
||||
public abstract class TikTokMessageHandler {
|
||||
|
||||
private final Map<String, io.github.jwdeveloper.tiktok.handler.TikTokMessageHandler> handlers;
|
||||
private final TikTokEventHandler tikTokEventHandler;
|
||||
private final ClientSettings clientSettings;
|
||||
protected final Logger logger;
|
||||
|
||||
public TikTokMessageHandler(TikTokEventHandler tikTokEventHandler,ClientSettings clientSettings, Logger logger) {
|
||||
handlers = new HashMap<>();
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
this.clientSettings = clientSettings;
|
||||
this.logger = logger;
|
||||
init();
|
||||
}
|
||||
|
||||
public abstract void init();
|
||||
|
||||
public void register(Class<?> clazz, Function<WebcastResponse.Message, TikTokEvent> func) {
|
||||
handlers.put(clazz.getSimpleName(), func::apply);
|
||||
}
|
||||
|
||||
public void register(Class<?> input, Class<?> output) {
|
||||
register(input, (e) -> mapMessageToEvent(input, output, e));
|
||||
}
|
||||
|
||||
public void handle(TikTokLiveClient client, WebcastResponse webcastResponse) {
|
||||
for (var message : webcastResponse.getMessagesList()) {
|
||||
try
|
||||
{
|
||||
if(clientSettings.isPrintMessageData())
|
||||
{
|
||||
var type= message.getType();
|
||||
var base64 = Base64.getEncoder().encodeToString(message.getBinary().toByteArray());
|
||||
logger.info(type+": \n "+base64);
|
||||
}
|
||||
handleSingleMessage(client, message);
|
||||
} catch (Exception e) {
|
||||
var exception = new TikTokLiveMessageException(message, webcastResponse, e);
|
||||
tikTokEventHandler.publish(client, new TikTokErrorEvent(exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSingleMessage(TikTokLiveClient client, WebcastResponse.Message message) throws Exception {
|
||||
if (!handlers.containsKey(message.getType())) {
|
||||
tikTokEventHandler.publish(client, new TikTokUnhandledEvent(message));
|
||||
return;
|
||||
}
|
||||
var handler = handlers.get(message.getType());
|
||||
var tiktokEvent = handler.handle(message);
|
||||
tikTokEventHandler.publish(client, tiktokEvent);
|
||||
}
|
||||
|
||||
protected TikTokEvent mapMessageToEvent(Class<?> inputClazz, Class<?> outputClass, WebcastResponse.Message message) {
|
||||
try {
|
||||
var parseMethod = inputClazz.getDeclaredMethod("parseFrom", ByteString.class);
|
||||
var deserialized = parseMethod.invoke(null, message.getBinary());
|
||||
|
||||
var constructors = Arrays.stream(outputClass.getConstructors())
|
||||
.filter(ea -> Arrays.stream(ea.getParameterTypes())
|
||||
.toList()
|
||||
.contains(inputClazz))
|
||||
.findFirst();
|
||||
|
||||
if(constructors.isEmpty())
|
||||
{
|
||||
throw new TikTokMessageMappingException(inputClazz, outputClass, "Unable to find constructor with input class type");
|
||||
}
|
||||
|
||||
var tiktokEvent = constructors.get().newInstance(deserialized);
|
||||
return (TikTokEvent) tiktokEvent;
|
||||
} catch (Exception ex) {
|
||||
throw new TikTokMessageMappingException(inputClazz, outputClass, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.TikTokGiftManager;
|
||||
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
import io.github.jwdeveloper.tiktok.events.objects.TikTokGift;
|
||||
@@ -9,15 +11,22 @@ import io.github.jwdeveloper.tiktok.models.GiftId;
|
||||
import io.github.jwdeveloper.tiktok.models.SocialTypes;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class WebResponseHandler extends WebResponseHandlerBase {
|
||||
public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
|
||||
private final TikTokGiftManager giftManager;
|
||||
private final TikTokRoomInfo roomInfo;
|
||||
|
||||
public WebResponseHandler(TikTokEventHandler tikTokEventHandler, TikTokGiftManager giftManager) {
|
||||
super(tikTokEventHandler);
|
||||
public TikTokMessageHandlerRegistration(TikTokEventHandler tikTokEventHandler,
|
||||
ClientSettings clientSettings,
|
||||
Logger logger,
|
||||
TikTokGiftManager giftManager,
|
||||
TikTokRoomInfo roomInfo) {
|
||||
super(tikTokEventHandler, clientSettings, logger);
|
||||
this.giftManager = giftManager;
|
||||
this.roomInfo = roomInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -30,7 +39,7 @@ public class WebResponseHandler extends WebResponseHandlerBase {
|
||||
|
||||
//Room status events
|
||||
register(WebcastLiveIntroMessage.class, TikTokRoomMessageEvent.class);
|
||||
register(WebcastRoomUserSeqMessage.class, TikTokRoomViewerDataEvent.class); //TODO update viewer count ViewerCount = userSeqMessage.ViewerCount;
|
||||
register(WebcastRoomUserSeqMessage.class, this::handleRoomUserSeqMessage);
|
||||
register(RoomMessage.class, TikTokRoomMessageEvent.class);
|
||||
register(WebcastRoomMessage.class, TikTokRoomMessageEvent.class);
|
||||
register(WebcastCaptionMessage.class, TikTokCaptionEvent.class);
|
||||
@@ -74,9 +83,9 @@ public class WebResponseHandler extends WebResponseHandlerBase {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private TikTokEvent handleWebcastControlMessage(WebcastResponse.Message msg)
|
||||
{
|
||||
private TikTokEvent handleWebcastControlMessage(WebcastResponse.Message msg) {
|
||||
var message = WebcastControlMessage.parseFrom(msg.getBinary());
|
||||
return switch (message.getAction()) {
|
||||
case STREAM_PAUSED -> new TikTokLivePausedEvent();
|
||||
@@ -88,29 +97,7 @@ public class WebResponseHandler extends WebResponseHandlerBase {
|
||||
@SneakyThrows
|
||||
private TikTokEvent handleGift(WebcastResponse.Message msg) {
|
||||
var giftMessage = WebcastGiftMessage.parseFrom(msg.getBinary());
|
||||
var giftId = new GiftId(giftMessage.getGiftId(), giftMessage.getSender().getUniqueId());
|
||||
|
||||
var activeGifts = giftManager.getActiveGifts();
|
||||
if (activeGifts.containsKey(giftId)) {
|
||||
// Debug.Log($"Updating Gift[{giftId.Gift}]Amount[{message.Amount}]");
|
||||
var gift = activeGifts.get(giftId);
|
||||
gift.setAmount(giftMessage.getAmount());
|
||||
} else {
|
||||
TikTokGift newGift = new TikTokGift(giftMessage);
|
||||
activeGifts.put(giftId, newGift);
|
||||
// Debug.Log($"New Gift[{giftId.Gift}]Amount[{message.Amount}]");
|
||||
// RunEvent(OnGift, newGift);
|
||||
}
|
||||
if (giftMessage.getRepeatEnd()) {
|
||||
//if (ShouldLog(LogLevel.Verbose))
|
||||
// Debug.Log($"GiftStreak Ended: [{giftId.Gift}] Amount[{message.Amount}]")
|
||||
var gift = activeGifts.get(giftId);
|
||||
gift.setStreakFinished(true);
|
||||
activeGifts.remove(gift);
|
||||
}
|
||||
|
||||
// Debug.Log($"Handling GiftMessage");
|
||||
|
||||
giftManager.updateActiveGift(giftMessage);
|
||||
return new TikTokGiftMessageEvent(giftMessage);
|
||||
}
|
||||
|
||||
@@ -146,4 +133,11 @@ public class WebResponseHandler extends WebResponseHandlerBase {
|
||||
default -> new TikTokUnhandledMemberEvent(message);
|
||||
};
|
||||
}
|
||||
|
||||
private TikTokEvent handleRoomUserSeqMessage(WebcastResponse.Message msg)
|
||||
{
|
||||
var event = (TikTokRoomViewerDataEvent)mapMessageToEvent(WebcastRoomUserSeqMessage.class, TikTokRoomViewerDataEvent.class, msg);
|
||||
roomInfo.setViewersCount(event.getViewerCount());
|
||||
return event;
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok.handlers;
|
||||
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokUnhandledEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageParsingException;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
public abstract class WebResponseHandlerBase {
|
||||
|
||||
private final Map<String, TikTokMessageHandler> handlers;
|
||||
private final TikTokEventHandler tikTokEventHandler;
|
||||
|
||||
public WebResponseHandlerBase(TikTokEventHandler tikTokEventHandler) {
|
||||
handlers = new HashMap<>();
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
init();
|
||||
}
|
||||
|
||||
public abstract void init();
|
||||
|
||||
public void register(Class<?> input, Class<?> output) {
|
||||
register(input, (e) ->
|
||||
{
|
||||
try {
|
||||
var parseMethod = input.getDeclaredMethod("parseFrom", ByteString.class);
|
||||
var deserialized = parseMethod.invoke(null, e.getBinary());
|
||||
|
||||
var constructors = Arrays.stream(output.getConstructors()).filter(ea -> Arrays.stream(ea.getParameterTypes()).toList().contains(input)).findFirst();
|
||||
|
||||
var tiktokEvent = constructors.get().newInstance(deserialized);
|
||||
return (TikTokEvent)tiktokEvent;
|
||||
} catch (Exception ex)
|
||||
{
|
||||
throw new TikTokLiveMessageParsingException("Unable to handle parsing from class: " + input.getSimpleName() + " to class " + output.getSimpleName(), ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public <T> void register(Class clazz, Function<WebcastResponse.Message, TikTokEvent> func) {
|
||||
var haandler = new TikTokMessageHandler<T>() {
|
||||
@Override
|
||||
public Class<T> getHandleClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TikTokEvent handle(WebcastResponse.Message message) throws Exception {
|
||||
return func.apply(message);
|
||||
}
|
||||
};
|
||||
|
||||
handlers.put(haandler.getHandleClazz().getSimpleName(), haandler);
|
||||
}
|
||||
|
||||
public void handle(WebcastResponse webcastResponse) {
|
||||
for (var message : webcastResponse.getMessagesList()) {
|
||||
try {
|
||||
handleSingleMessage(message);
|
||||
} catch (Exception e)
|
||||
{
|
||||
|
||||
var decoded = Base64.getEncoder().encodeToString(message.getBinary().toByteArray());
|
||||
|
||||
var exception = new TikTokLiveException("Error whilst Handling Message"+message.getType()+": \n"+decoded, e);
|
||||
tikTokEventHandler.publish(new TikTokErrorEvent(exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleSingleMessage(WebcastResponse.Message message) throws Exception {
|
||||
if (!handlers.containsKey(message.getType())) {
|
||||
tikTokEventHandler.publish(new TikTokUnhandledEvent(message));
|
||||
return;
|
||||
}
|
||||
var handler = handlers.get(message.getType());
|
||||
var tiktokEvent = handler.handle(message);
|
||||
tikTokEventHandler.publish(tiktokEvent);
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,10 @@ package io.github.jwdeveloper.tiktok.http;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.models.gifts.TikTokGift;
|
||||
import io.github.jwdeveloper.tiktok.models.gifts.TikTokGiftInfo;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -50,7 +50,7 @@ public class TikTokApiService {
|
||||
}
|
||||
|
||||
if (id.isEmpty()) {
|
||||
throw new TikTokLiveException("Unable to fetch room ID");
|
||||
throw new TikTokLiveOfflineHostException("Unable to fetch room ID, live host could be offline or name is misspelled");
|
||||
}
|
||||
|
||||
clientSettings.getClientParameters().put("room_id", id);
|
||||
@@ -99,7 +99,7 @@ public class TikTokApiService {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, TikTokGift> fetchAvailableGifts() {
|
||||
public Map<Integer, TikTokGiftInfo> fetchAvailableGifts() {
|
||||
try {
|
||||
var response = apiClient.GetJObjectFromWebcastAPI("gift/list/", clientSettings.getClientParameters());
|
||||
if(!response.has("data"))
|
||||
@@ -112,11 +112,11 @@ public class TikTokApiService {
|
||||
return new HashMap<>();
|
||||
}
|
||||
var giftsJsonList = dataJson.get("gifts").getAsJsonArray();
|
||||
var gifts = new HashMap<Integer, TikTokGift>();
|
||||
var gifts = new HashMap<Integer, TikTokGiftInfo>();
|
||||
var gson = new Gson();
|
||||
for(var jsonGift : giftsJsonList)
|
||||
{
|
||||
var gift = gson.fromJson(jsonGift, TikTokGift.class);
|
||||
var gift = gson.fromJson(jsonGift, TikTokGiftInfo.class);
|
||||
logger.info("Found Available Gift "+ gift.getName()+ " with ID "+gift.getId());
|
||||
gifts.put(gift.getId(),gift);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,10 @@ package io.github.jwdeveloper.tiktok.websocket;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.Constants;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.WebResponseHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.http.HttpUtils;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokCookieJar;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokHttpRequestFactory;
|
||||
@@ -23,18 +24,18 @@ public class TikTokWebSocketClient {
|
||||
private final ClientSettings clientSettings;
|
||||
private final TikTokCookieJar tikTokCookieJar;
|
||||
private final TikTokHttpRequestFactory factory;
|
||||
private final WebResponseHandler webResponseHandler;
|
||||
private final TikTokMessageHandlerRegistration webResponseHandler;
|
||||
private final TikTokEventHandler tikTokEventHandler;
|
||||
|
||||
private WebSocket webSocket;
|
||||
|
||||
private boolean isConnected;
|
||||
private TikTokLiveClient tikTokLiveClient;
|
||||
|
||||
public TikTokWebSocketClient(Logger logger,
|
||||
TikTokCookieJar tikTokCookieJar,
|
||||
TikTokHttpRequestFactory factory,
|
||||
ClientSettings clientSettings,
|
||||
WebResponseHandler webResponseHandler,
|
||||
TikTokMessageHandlerRegistration webResponseHandler,
|
||||
TikTokEventHandler tikTokEventHandler) {
|
||||
this.logger = logger;
|
||||
this.tikTokCookieJar = tikTokCookieJar;
|
||||
@@ -45,21 +46,22 @@ public class TikTokWebSocketClient {
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
public void start(WebcastResponse webcastResponse)
|
||||
{
|
||||
if(isConnected)
|
||||
{
|
||||
public void start(WebcastResponse webcastResponse, TikTokLiveClient tikTokLiveClient) {
|
||||
this.tikTokLiveClient = tikTokLiveClient;
|
||||
if (isConnected) {
|
||||
stop();
|
||||
}
|
||||
if (webcastResponse.getSocketUrl().isEmpty() || webcastResponse.getSocketParamsList().isEmpty()) {
|
||||
throw new TikTokLiveException("Could not find Room");
|
||||
}
|
||||
try {
|
||||
var url =getWebSocketUrl(webcastResponse);
|
||||
webSocket =startWebSocket(url);
|
||||
if (clientSettings.isHandleExistingMessagesOnConnect()) {
|
||||
// HandleWebcastMessages(webcastResponse);
|
||||
var url = getWebSocketUrl(webcastResponse);
|
||||
if (clientSettings.isHandleExistingMessagesOnConnect())
|
||||
{
|
||||
logger.info("Handling existing messages");
|
||||
webResponseHandler.handle(tikTokLiveClient, webcastResponse);
|
||||
}
|
||||
webSocket = startWebSocket(url);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveException("Failed to connect to the websocket", e);
|
||||
}
|
||||
@@ -82,23 +84,17 @@ public class TikTokWebSocketClient {
|
||||
|
||||
private WebSocket startWebSocket(String url) throws Exception {
|
||||
var cookie = tikTokCookieJar.parseCookies();
|
||||
// System.out.println("WssIP: " + url);
|
||||
// System.out.println("Cookie: " + cookie);
|
||||
|
||||
var map = new HashMap<String, String>();
|
||||
map.put("Cookie", cookie);
|
||||
|
||||
return factory.openSocket()
|
||||
return factory.openSocket()
|
||||
.subprotocols("echo-protocol")
|
||||
.connectTimeout(Duration.ofSeconds(15))
|
||||
.header("Cookie", cookie)
|
||||
.buildAsync(URI.create(url), new TikTokWebSocketListener(webResponseHandler, tikTokEventHandler)).get();
|
||||
.buildAsync(URI.create(url), new TikTokWebSocketListener(webResponseHandler, tikTokEventHandler, tikTokLiveClient)).get();
|
||||
}
|
||||
|
||||
|
||||
public void stop() {
|
||||
if(isConnected && webSocket != null)
|
||||
{
|
||||
if (isConnected && webSocket != null) {
|
||||
webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "ok");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package io.github.jwdeveloper.tiktok.websocket;
|
||||
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.github.jwdeveloper.tiktok.TikTokLiveClient;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokConnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokDisconnectedEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokErrorEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageParsingException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.WebResponseHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastWebsocketAck;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastWebsocketMessage;
|
||||
@@ -14,18 +16,23 @@ import io.github.jwdeveloper.tiktok.messages.WebcastWebsocketMessage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.http.WebSocket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
|
||||
public class TikTokWebSocketListener implements java.net.http.WebSocket.Listener {
|
||||
|
||||
private final ByteArrayOutputStream accumulatedData = new ByteArrayOutputStream();
|
||||
private final WebResponseHandler webResponseHandler;
|
||||
private final TikTokMessageHandlerRegistration webResponseHandler;
|
||||
private final TikTokEventHandler tikTokEventHandler;
|
||||
private final TikTokLiveClient tikTokLiveClient;
|
||||
|
||||
public TikTokWebSocketListener(WebResponseHandler webResponseHandler, TikTokEventHandler tikTokEventHandler) {
|
||||
public TikTokWebSocketListener(TikTokMessageHandlerRegistration webResponseHandler,
|
||||
TikTokEventHandler tikTokEventHandler,
|
||||
TikTokLiveClient tikTokLiveClient) {
|
||||
this.webResponseHandler = webResponseHandler;
|
||||
this.tikTokEventHandler = tikTokEventHandler;
|
||||
this.tikTokLiveClient = tikTokLiveClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,7 +46,7 @@ public class TikTokWebSocketListener implements java.net.http.WebSocket.Listener
|
||||
accumulatedData.reset();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
tikTokEventHandler.publish(new TikTokErrorEvent(e));
|
||||
tikTokEventHandler.publish(tikTokLiveClient, new TikTokErrorEvent(e));
|
||||
}
|
||||
webSocket.request(1);
|
||||
return null;
|
||||
@@ -47,38 +54,51 @@ public class TikTokWebSocketListener implements java.net.http.WebSocket.Listener
|
||||
|
||||
@Override
|
||||
public void onOpen(java.net.http.WebSocket webSocket) {
|
||||
tikTokEventHandler.publish(new TikTokConnectedEvent());
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokConnectedEvent());
|
||||
webSocket.request(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(java.net.http.WebSocket webSocket, Throwable error) {
|
||||
tikTokEventHandler.publish(new TikTokErrorEvent(error));
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokErrorEvent(error));
|
||||
webSocket.request(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<?> onClose(java.net.http.WebSocket webSocket, int statusCode, String reason) {
|
||||
tikTokEventHandler.publish(new TikTokDisconnectedEvent());
|
||||
tikTokEventHandler.publish(tikTokLiveClient,new TikTokDisconnectedEvent());
|
||||
return java.net.http.WebSocket.Listener.super.onClose(webSocket, statusCode, reason);
|
||||
}
|
||||
|
||||
private void handleBinary(WebSocket webSocket, byte[] buffer) {
|
||||
try {
|
||||
var websocketMessageOptional = getWebcastWebsocketMessage(buffer);
|
||||
if (websocketMessageOptional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
var websocketMessage = websocketMessageOptional.get();
|
||||
sendAckId(webSocket, websocketMessage.getId());
|
||||
|
||||
var webResponse = getWebResponseMessage(websocketMessage.getBinary());
|
||||
webResponseHandler.handle(tikTokLiveClient, webResponse);
|
||||
}
|
||||
|
||||
private Optional<WebcastWebsocketMessage> getWebcastWebsocketMessage(byte[] buffer) {
|
||||
try {
|
||||
var websocketMessage = WebcastWebsocketMessage.parseFrom(buffer);
|
||||
if (websocketMessage.getBinary().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
sendAckId(webSocket, websocketMessage.getId());
|
||||
try {
|
||||
var response = WebcastResponse.parseFrom(websocketMessage.getBinary());
|
||||
webResponseHandler.handle(response);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveMessageParsingException("Unable to read WebcastResponse", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(websocketMessage);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokLiveMessageParsingException("Unable to read WebcastWebsocketMessage", e);
|
||||
throw new TikTokProtocolBufferException("Unable to parse WebcastWebsocketMessage", buffer, e);
|
||||
}
|
||||
}
|
||||
|
||||
private WebcastResponse getWebResponseMessage(ByteString buffer) {
|
||||
try {
|
||||
return WebcastResponse.parseFrom(buffer);
|
||||
} catch (Exception e) {
|
||||
throw new TikTokProtocolBufferException("Unable to parse WebcastResponse", buffer.toByteArray(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.common.TikTokBaseTest;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.handlers.WebResponseHandler;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
|
||||
import io.github.jwdeveloper.tiktok.messages.WebcastSocialMessage;
|
||||
import io.github.jwdeveloper.tiktok.models.SocialTypes;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class WebResponseHandlerTests extends TikTokBaseTest
|
||||
{
|
||||
public static WebResponseHandler sut;
|
||||
public class WebResponseHandlerTests extends TikTokBaseTest {
|
||||
public static TikTokMessageHandlerRegistration sut;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
public void before() {
|
||||
var mockEventHandler = mock(TikTokEventHandler.class);
|
||||
var mockGiftManager = mock(TikTokGiftManager.class);
|
||||
sut = new WebResponseHandler(mockEventHandler, mockGiftManager);
|
||||
var mockRoomInfo = mock(TikTokRoomInfo.class);
|
||||
var mockClientSettings = mock(ClientSettings.class);
|
||||
var mockLogger = mock(Logger.class);
|
||||
sut = new TikTokMessageHandlerRegistration(mockEventHandler,mockClientSettings,mockLogger, mockGiftManager, mockRoomInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,24 +4,22 @@ import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigurationExample
|
||||
{
|
||||
public class ConfigurationExample {
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
TikTokLive.newClient(Main.TEST_TIKTOK_USER)
|
||||
.configure(clientSettings ->
|
||||
{
|
||||
clientSettings.setHostName(Main.TEST_TIKTOK_USER); //tiktok user
|
||||
clientSettings.setClientLanguage("en"); //language
|
||||
clientSettings.setTimeout(Duration.ofSeconds(2)); //connection timeout
|
||||
clientSettings.setLogLevel(Level.ALL); //log level
|
||||
clientSettings.setDownloadGiftInfo(true); //TODO
|
||||
clientSettings.setCheckForUnparsedData(true); //TODO
|
||||
clientSettings.setPollingInterval(Duration.ofSeconds(1)); //TODO
|
||||
clientSettings.setPrintMessageData(true); //TODO
|
||||
clientSettings.setPrintToConsole(true); //TODO
|
||||
clientSettings.setHandleExistingMessagesOnConnect(true); //TODO
|
||||
clientSettings.setRetryOnConnectionFailure(true); //TODO
|
||||
clientSettings.setHostName(Main.TEST_TIKTOK_USER); // TikTok user name
|
||||
clientSettings.setClientLanguage("en"); // Language
|
||||
clientSettings.setTimeout(Duration.ofSeconds(2)); // Connection timeout
|
||||
clientSettings.setLogLevel(Level.ALL); // Log level
|
||||
clientSettings.setDownloadGiftInfo(true); // Downloading meta information about gifts. You can access it by client.getGiftManager().getGiftsInfo();
|
||||
clientSettings.setPrintMessageData(true); // Printing TikTok Protocol buffer messages in Base64 format
|
||||
clientSettings.setPrintToConsole(true); // Printing all logs to console even if log level is Level.OFF
|
||||
clientSettings.setHandleExistingMessagesOnConnect(true); // Invokes all TikTok events that had occurred before connection
|
||||
clientSettings.setRetryOnConnectionFailure(true); // Reconnecting if TikTok user is offline
|
||||
clientSettings.setRetryConnectionTimeout(Duration.ofSeconds(1)); // Timeout before next reconnection
|
||||
})
|
||||
.buildAndRun();
|
||||
System.in.read();
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.messages.*;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static String TEST_TIKTOK_USER = "mr_cios";
|
||||
public static String TEST_TIKTOK_USER = "vadimpyrography";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
var client = TikTokLive.newClient(TEST_TIKTOK_USER)
|
||||
@@ -21,59 +22,59 @@ public class Main {
|
||||
.onLike(Main::onLike)
|
||||
.onGiftMessage(Main::onGiftMessage)
|
||||
.onEmote(Main::onEmote)
|
||||
.onError(tikTokErrorEvent ->
|
||||
.onError((_client, error) ->
|
||||
{
|
||||
// tikTokErrorEvent.getException().printStackTrace();
|
||||
error.getException().printStackTrace();
|
||||
})
|
||||
.buildAndRun();
|
||||
|
||||
|
||||
var viewers = client.getRoomInfo().getViewersCount();
|
||||
System.in.read();
|
||||
}
|
||||
|
||||
private static void onConnected(TikTokConnectedEvent e) {
|
||||
private static void onConnected(LiveClient tikTokLive, TikTokConnectedEvent e) {
|
||||
print("Connected");
|
||||
}
|
||||
|
||||
private static void onDisconnected(TikTokDisconnectedEvent e) {
|
||||
private static void onDisconnected(LiveClient tikTokLive, TikTokDisconnectedEvent e) {
|
||||
print("Disconnected");
|
||||
}
|
||||
|
||||
private static void onViewerData(TikTokRoomViewerDataEvent e) {
|
||||
private static void onViewerData(LiveClient tikTokLive, TikTokRoomViewerDataEvent e) {
|
||||
print("Viewer count is:", e.getViewerCount());
|
||||
}
|
||||
|
||||
private static void onJoin(TikTokJoinEvent e) {
|
||||
private static void onJoin(LiveClient tikTokLive, TikTokJoinEvent e) {
|
||||
print(e.getUser().getUniqueId(), "joined!");
|
||||
}
|
||||
|
||||
private static void onComment(TikTokCommentEvent e) {
|
||||
private static void onComment(LiveClient tikTokLive, TikTokCommentEvent e) {
|
||||
print(e.getUser().getUniqueId(), e.getText());
|
||||
}
|
||||
|
||||
private static void onFollow(TikTokFollowEvent e) {
|
||||
private static void onFollow(LiveClient tikTokLive, TikTokFollowEvent e) {
|
||||
print(e.getNewFollower().getUniqueId(), "followed!");
|
||||
}
|
||||
|
||||
private static void onShare(TikTokShareEvent e) {
|
||||
private static void onShare(LiveClient tikTokLive, TikTokShareEvent e) {
|
||||
print(e.getUser().getUniqueId(), "shared!");
|
||||
}
|
||||
|
||||
private static void onSubscribe(TikTokSubscribeEvent e) {
|
||||
private static void onSubscribe(LiveClient tikTokLive, TikTokSubscribeEvent e) {
|
||||
print(e.getNewSubscriber().getUniqueId(), "subscribed!");
|
||||
}
|
||||
|
||||
private static void onLike(TikTokLikeEvent e) {
|
||||
private static void onLike(LiveClient tikTokLive, TikTokLikeEvent e) {
|
||||
|
||||
print(e.getSender().getUniqueId(), "liked!");
|
||||
}
|
||||
|
||||
private static void onGiftMessage(TikTokGiftMessageEvent e) {
|
||||
private static void onGiftMessage(LiveClient tikTokLive, TikTokGiftMessageEvent e)
|
||||
{
|
||||
print(e.getSender().getUniqueId(), "sent", e.getAmount(), "x", e.getGift().getName());
|
||||
}
|
||||
|
||||
private static void onEmote(TikTokEmoteEvent e) {
|
||||
private static void onEmote(LiveClient tikTokLive, TikTokEmoteEvent e) {
|
||||
print(e.getUser().getUniqueId(), "sent", e.getEmoteId());
|
||||
}
|
||||
|
||||
|
||||
@@ -6,21 +6,24 @@ public class SimpleExample {
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
TikTokLive.newClient(Main.TEST_TIKTOK_USER)
|
||||
.onConnected(event ->
|
||||
.onConnected((client, event) ->
|
||||
{
|
||||
System.out.println("Connected");
|
||||
})
|
||||
.onJoin(event ->
|
||||
.onJoin((client, event) ->
|
||||
{
|
||||
System.out.println("User joined -> " + event.getUser().getNickName());
|
||||
})
|
||||
.onComment(event ->
|
||||
.onComment((client, event) ->
|
||||
{
|
||||
System.out.println(event.getUser().getUniqueId() + ": " + event.getText());
|
||||
})
|
||||
.onError(event ->
|
||||
.onEvent((client, event) ->
|
||||
{
|
||||
System.out.println("Viewers count: "+client.getRoomInfo().getViewersCount());
|
||||
})
|
||||
.onError((client, event) ->
|
||||
{
|
||||
System.out.println("OTO tajeminica wiary");
|
||||
event.getException().printStackTrace();
|
||||
})
|
||||
.buildAndRun();
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package io.github.jwdeveloper.tiktok.events_generator;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.FilesUtility;
|
||||
import io.github.jwdeveloper.tiktok.utils.FilesUtility;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EventsGenerator
|
||||
{
|
||||
|
||||
@@ -20,16 +20,16 @@ public class EventsInterfaceGenerator {
|
||||
// System.out.println(clazz.getName());
|
||||
}
|
||||
|
||||
//var result = generateInterface("io.github.jwdeveloper.tiktok.events", classes);System.out.println(result);
|
||||
// var result = generateInterface("io.github.jwdeveloper.tiktok.events", classes);System.out.println(result);
|
||||
|
||||
|
||||
var result = getBuilderImplementation("x",classes); System.out.println(result);
|
||||
var result = getBuilderImplementation("x",classes); System.out.println(result);
|
||||
|
||||
}
|
||||
|
||||
public String generateInterface(String packageName, Set<Class<? extends TikTokEvent>> eventsClasses) {
|
||||
|
||||
TypeSpec.Builder classBuilder = TypeSpec.interfaceBuilder("TikTokEvents");
|
||||
TypeSpec.Builder classBuilder = TypeSpec.interfaceBuilder("TikTokEventBuilder");
|
||||
classBuilder.addModifiers(Modifier.PUBLIC);
|
||||
classBuilder.addTypeVariable(TypeVariableName.get("T"));
|
||||
|
||||
@@ -46,7 +46,7 @@ public class EventsInterfaceGenerator {
|
||||
MethodSpec.Builder constructorBuilder = MethodSpec.methodBuilder("on" + methodName);
|
||||
|
||||
|
||||
var name = "Consumer<" + clazzName + ">";
|
||||
var name = "TikTokEventConsumer<" + clazzName + ">";
|
||||
constructorBuilder.addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC);
|
||||
constructorBuilder.addParameter(ClassName.bestGuess(name), "event");
|
||||
constructorBuilder.returns(TypeVariableName.get("T"));
|
||||
@@ -91,7 +91,7 @@ public class EventsInterfaceGenerator {
|
||||
MethodSpec.Builder constructorBuilder = MethodSpec.methodBuilder( methodName);
|
||||
|
||||
|
||||
var name = "Consumer<" + clazzName + ">";
|
||||
var name = "TikTokEventConsumer<" + clazzName + ">";
|
||||
constructorBuilder.addModifiers( Modifier.PUBLIC);
|
||||
constructorBuilder.addParameter(ClassName.bestGuess(name), "event");
|
||||
constructorBuilder.addStatement("tikTokEventHandler.subscribe("+clazzName+".class,event)");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
package io.github.jwdeveloper.tiktok.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user