Breaking changes:

'Gift': changed from class to enum, so now you can handle
incoming gifts in switch

`Events`
- new:
     onGiftComboFinished
- Removed:
      onGiftBrodcast
- Rename:
     onGiftMessage -> onGift
     onRoomPinMessage -> onRoomPin
     onRoomMessage -> onRoom
     onLinkMessage -> onLink
     onBarrageMessage -> onBarrage
     onPollMessage -> onPoll
     onShopMessage -> onShop
     onDetectMessage -> onDetect

`GiftManager`
   added:
      registerGift
      findById
      findByName
      getGifts
   removed:
      getActiveGifts
This commit is contained in:
JW
2023-10-06 02:31:40 +02:00
parent 6cc74413ec
commit 65a2d5cfff
132 changed files with 1196 additions and 589 deletions

View File

@@ -22,9 +22,9 @@
*/
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.events.messages.TikTokReconnectingEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokReconnectingEvent;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveOfflineHostException;
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;

View File

@@ -22,26 +22,26 @@
*/
package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import io.github.jwdeveloper.tiktok.events.TikTokEventBuilder;
import io.github.jwdeveloper.tiktok.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.events.messages.*;
import io.github.jwdeveloper.tiktok.events.messages.TikTokConnectedEvent;
import io.github.jwdeveloper.tiktok.events.messages.TikTokDisconnectedEvent;
import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftComboFinishedEvent;
import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomPinEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent;
import io.github.jwdeveloper.tiktok.events.messages.TikTokBarrageEvent;
import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokShareEvent;
import io.github.jwdeveloper.tiktok.events.messages.websocket.TikTokWebsocketResponseEvent;
import io.github.jwdeveloper.tiktok.events.messages.websocket.TikTokWebsocketUnhandledMessageEvent;
import io.github.jwdeveloper.tiktok.events.messages.websocket.TikTokWebsocketMessageEvent;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.live.events.TikTokEventBuilder;
import io.github.jwdeveloper.tiktok.live.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.data.events.*;
import io.github.jwdeveloper.tiktok.data.events.TikTokConnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboFinishedEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomPinEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomUserInfoEvent;
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.events.TikTokBarrageEvent;
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
import io.github.jwdeveloper.tiktok.data.events.social.TikTokShareEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandledMessageEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketMessageEvent;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
@@ -53,16 +53,15 @@ import io.github.jwdeveloper.tiktok.http.TikTokHttpRequestFactory;
import io.github.jwdeveloper.tiktok.listener.TikTokEventListener;
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
import io.github.jwdeveloper.tiktok.live.LiveClient;
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.*;
public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveClientBuilder> {
protected final ClientSettings clientSettings;
@@ -74,7 +73,7 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
this.tikTokEventHandler = new TikTokEventObserver();
this.clientSettings = Constants.DefaultClientSettings();
this.clientSettings.setHostName(userName);
this.logger = Logger.getLogger(TikTokLive.class.getName());
this.logger = Logger.getLogger(TikTokLive.class.getSimpleName()+" "+userName);
this.listeners = new ArrayList<>();
}
@@ -108,6 +107,21 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
params.put("webcast_language", clientSettings.getClientLanguage());
logger.setLevel(clientSettings.getLogLevel());
var handler = new ConsoleHandler();
handler.setFormatter(new Formatter() {
@Override
public String format(LogRecord record)
{
var sb = new StringBuilder();
sb.append(ConsoleColors.GREEN).append("[").append(record.getLoggerName()).append("] ");
sb.append(ConsoleColors.GREEN).append("[").append(record.getLevel()).append("]: ");
sb.append(ConsoleColors.WHITE_BRIGHT).append(record.getMessage());
sb.append(ConsoleColors.RESET).append("\n");
return sb.toString();
}
});
logger.setUseParentHandlers(false);
logger.addHandler(handler);
if (clientSettings.isPrintToConsole() && clientSettings.getLogLevel() == Level.OFF) {
logger.setLevel(Level.ALL);
@@ -147,17 +161,14 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
logger);
}
public LiveClient buildAndRun() {
public LiveClient buildAndConnect() {
var client = build();
client.connect();
return client;
}
public Future<LiveClient> buildAndRunAsync() {
var executor = Executors.newSingleThreadExecutor();
var future = executor.submit(this::buildAndRun);
executor.shutdown();
return future;
public CompletableFuture<LiveClient> buildAndConnectAsync() {
return CompletableFuture.supplyAsync(this::buildAndConnect);
}
public TikTokLiveClientBuilder onUnhandledSocial(
@@ -303,16 +314,17 @@ public class TikTokLiveClientBuilder implements TikTokEventBuilder<TikTokLiveCli
return this;
}
public TikTokLiveClientBuilder onGoalUpdate(TikTokEventConsumer<TikTokGoalUpdateEvent> event) {
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
return this;
}
public TikTokLiveClientBuilder onComment(TikTokEventConsumer<TikTokCommentEvent> event) {
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
return this;
}
public TikTokLiveClientBuilder onGoalUpdate(TikTokEventConsumer<TikTokGoalUpdateEvent> event) {
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
return this;
}
public TikTokLiveClientBuilder onRankUpdate(TikTokEventConsumer<TikTokRankUpdateEvent> event) {
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class, event);
return this;

View File

@@ -22,8 +22,8 @@
*/
package io.github.jwdeveloper.tiktok.gifts;
import io.github.jwdeveloper.tiktok.events.objects.Gift;
import io.github.jwdeveloper.tiktok.events.objects.Picture;
import io.github.jwdeveloper.tiktok.data.models.Gift;
import io.github.jwdeveloper.tiktok.data.models.Picture;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.live.GiftManager;
import sun.misc.Unsafe;

View File

@@ -22,9 +22,8 @@
*/
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 io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.live.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.live.LiveClient;
import java.util.HashMap;

View File

@@ -23,12 +23,11 @@
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.websocket.TikTokWebsocketMessageEvent;
import io.github.jwdeveloper.tiktok.events.messages.websocket.TikTokWebsocketResponseEvent;
import io.github.jwdeveloper.tiktok.events.messages.websocket.TikTokWebsocketUnhandledMessageEvent;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketMessageEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketResponseEvent;
import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandledMessageEvent;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
import io.github.jwdeveloper.tiktok.live.LiveClient;
@@ -86,16 +85,12 @@ public abstract class TikTokMessageHandler {
public void handleSingleMessage(LiveClient client, WebcastResponse.Message message) throws Exception {
var methodName = message.getMethod();
if (!methodName.contains("Webcast")) {
methodName = "Webcast" + methodName;
}
if (!handlers.containsKey(methodName)) {
var messageClassName = message.getMethod();
if (!handlers.containsKey(messageClassName)) {
tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message));
return;
}
var handler = handlers.get(methodName);
var handler = handlers.get(messageClassName);
var tiktokEvent = handler.handle(message.getPayload().toByteArray());
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(tiktokEvent, message));
tikTokEventHandler.publish(client, tiktokEvent);

View File

@@ -23,25 +23,25 @@
package io.github.jwdeveloper.tiktok.handlers;
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.messages.TikTokBarrageEvent;
import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftComboFinishedEvent;
import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftEvent;
import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollEndEvent;
import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollEvent;
import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollStartEvent;
import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollUpdateEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomPinEvent;
import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokShareEvent;
import io.github.jwdeveloper.tiktok.events.objects.Gift;
import io.github.jwdeveloper.tiktok.events.objects.Picture;
import io.github.jwdeveloper.tiktok.events.objects.Text;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.data.events.*;
import io.github.jwdeveloper.tiktok.data.events.TikTokBarrageEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboFinishedEvent;
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEndEvent;
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollStartEvent;
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollUpdateEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomPinEvent;
import io.github.jwdeveloper.tiktok.data.events.room.TikTokRoomUserInfoEvent;
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.events.social.TikTokShareEvent;
import io.github.jwdeveloper.tiktok.data.models.Gift;
import io.github.jwdeveloper.tiktok.data.models.Picture;
import io.github.jwdeveloper.tiktok.data.models.Text;
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftManager;
import io.github.jwdeveloper.tiktok.messages.webcast.*;
import io.github.jwdeveloper.tiktok.models.SocialTypes;
@@ -73,6 +73,7 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
//Room status events
registerMapping(WebcastLiveIntroMessage.class, TikTokRoomEvent.class);
registerMapping(WebcastRoomUserSeqMessage.class, this::handleRoomUserSeqMessage);
registerMapping(RoomMessage.class, TikTokRoomEvent.class);
registerMapping(WebcastRoomMessage.class, TikTokRoomEvent.class);
registerMapping(WebcastCaptionMessage.class, TikTokCaptionEvent.class);

View File

@@ -22,7 +22,7 @@
*/
package io.github.jwdeveloper.tiktok.listener;
import io.github.jwdeveloper.tiktok.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.live.events.TikTokEventConsumer;
import lombok.Value;

View File

@@ -24,8 +24,8 @@ package io.github.jwdeveloper.tiktok.listener;
import io.github.jwdeveloper.tiktok.annotations.TikTokEventHandler;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import io.github.jwdeveloper.tiktok.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.live.events.TikTokEventConsumer;
import io.github.jwdeveloper.tiktok.exceptions.TikTokEventListenerMethodException;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;

View File

@@ -22,7 +22,7 @@
*/
package io.github.jwdeveloper.tiktok.mappers.messages;
import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent;
import io.github.jwdeveloper.tiktok.data.events.social.TikTokLikeEvent;
import io.github.jwdeveloper.tiktok.mappers.Mapper;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLikeMessage;

View File

@@ -68,17 +68,17 @@ public class TikTokWebSocketClient implements SocketClient {
stop();
}
if (webcastResponse.getPushServer().isEmpty() ||
webcastResponse.getRouteParamsMapMap().isEmpty()) {
if (webcastResponse.getPushServer().isEmpty() || webcastResponse.getRouteParamsMapMap().isEmpty())
{
throw new TikTokLiveException("Could not find Room");
}
try {
var url = getWebSocketUrl(webcastResponse);
if (clientSettings.isHandleExistingEvents()) {
logger.info("Handling existing messages");
webResponseHandler.handle(tikTokLiveClient, webcastResponse);
}
var url = getWebSocketUrl(webcastResponse);
webSocketClient = startWebSocket(url, tikTokLiveClient);
webSocketClient.connect();
@@ -91,26 +91,28 @@ public class TikTokWebSocketClient implements SocketClient {
}
}
private WebSocketClient startWebSocket(String url, LiveClient liveClient) {
private URI getWebSocketUrl(WebcastResponse webcastResponse) {
var tiktokAccessKey = webcastResponse.getRouteParamsMapMap();
var parameters = new TreeMap<>(clientSettings.getClientParameters());
parameters.putAll(tiktokAccessKey);
var url = webcastResponse.getPushServer();
var parsed = HttpUtils.parseParametersEncode(url, parameters);
return URI.create(parsed);
}
private WebSocketClient startWebSocket(URI url, LiveClient liveClient) {
var cookie = tikTokCookieJar.parseCookies();
var map = new HashMap<String, String>();
map.put("Cookie", cookie);
return new TikTokWebSocketListener(URI.create(url),
map,
var headers = new HashMap<String, String>();
headers.put("Cookie", cookie);
return new TikTokWebSocketListener(url,
headers,
3000,
webResponseHandler,
tikTokEventHandler,
liveClient);
}
private String getWebSocketUrl(WebcastResponse webcastResponse) {
var clone = new TreeMap<>(clientSettings.getClientParameters());
clone.putAll(Constants.DefaultRequestHeaders());
clone.putAll(webcastResponse.getRouteParamsMapMap());
var url = webcastResponse.getPushServer();
return HttpUtils.parseParametersEncode(url, clone);
}
public void stop()
{
if (isConnected && webSocketClient != null) {

View File

@@ -23,10 +23,9 @@
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.data.events.TikTokConnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokDisconnectedEvent;
import io.github.jwdeveloper.tiktok.data.events.TikTokErrorEvent;
import io.github.jwdeveloper.tiktok.exceptions.TikTokProtocolBufferException;
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
@@ -88,16 +87,12 @@ public class TikTokWebSocketListener extends WebSocketClient {
@Override
public void onClose(int i, String s, boolean b) {
System.out.println("CLOSE "+i+" "+s+" "+b);
tikTokEventHandler.publish(tikTokLiveClient,new TikTokDisconnectedEvent());
}
@Override
public void onError(Exception error)
{
System.out.println("ERROR");
error.printStackTrace();
tikTokEventHandler.publish(tikTokLiveClient,new TikTokErrorEvent(error));
if(isNotClosing())
{
@@ -111,10 +106,14 @@ public class TikTokWebSocketListener extends WebSocketClient {
return;
}
var websocketMessage = websocketMessageOptional.get();
System.out.println("ACK ID "+websocketMessage.getLogId()+" ID "+websocketMessage.getSeqId());
sendAckId(websocketMessage.getLogId());
var webResponse = getWebResponseMessage(websocketMessage.getPayload());
if(webResponse.getNeedsAck())
{
//For some reason while send ack id, server get disconnected
// sendAckId(webResponse.getFetchInterval());
}
webResponseHandler.handle(tikTokLiveClient, webResponse);
}
@@ -143,8 +142,6 @@ public class TikTokWebSocketListener extends WebSocketClient {
return !isClosed() && !isClosing();
}
private void sendAckId(long id) {
var serverInfo = WebcastWebsocketAck
.newBuilder()

View File

@@ -67,7 +67,6 @@ public class TikTokWebSocketPingingTask
Thread.sleep(100);
continue;
}
System.out.println("PING!");
webSocket.sendPing();
var timeout = random.nextInt(MAX_TIMEOUT)+MIN_TIMEOUT;