mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
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:
@@ -32,13 +32,15 @@ import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.http.TikTokApiService;
|
||||
import io.github.jwdeveloper.tiktok.listener.ListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.listener.TikTokListenersManager;
|
||||
import io.github.jwdeveloper.tiktok.live.UserManager;
|
||||
import io.github.jwdeveloper.tiktok.models.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.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.models.ConnectionState;
|
||||
import io.github.jwdeveloper.tiktok.websocket.SocketClient;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class TikTokLiveClient implements LiveClient {
|
||||
@@ -70,22 +72,37 @@ public class TikTokLiveClient implements LiveClient {
|
||||
}
|
||||
|
||||
|
||||
public void connectAsync(Consumer<LiveClient> onConnection) {
|
||||
CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
connect();
|
||||
onConnection.accept(this);
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<LiveClient> connectAsync() {
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
connect();
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
try {
|
||||
tryConnect();
|
||||
}
|
||||
catch (TikTokLiveException e)
|
||||
} catch (TikTokLiveException e)
|
||||
{
|
||||
setState(ConnectionState.DISCONNECTED);
|
||||
tikTokEventHandler.publish(this, new TikTokErrorEvent(e));
|
||||
tikTokEventHandler.publish(this, new TikTokDisconnectedEvent());
|
||||
|
||||
if(e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure())
|
||||
{
|
||||
if (e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure()) {
|
||||
try {
|
||||
Thread.sleep(clientSettings.getRetryConnectionTimeout().toMillis());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
catch (Exception ignored){}
|
||||
logger.info("Reconnecting");
|
||||
tikTokEventHandler.publish(this, new TikTokReconnectingEvent());
|
||||
this.connect();
|
||||
@@ -108,27 +125,22 @@ public class TikTokLiveClient implements LiveClient {
|
||||
if (liveRoomInfo.hasConnectionState(ConnectionState.CONNECTING))
|
||||
throw new TikTokLiveException("Already connecting");
|
||||
|
||||
logger.info("Connecting");
|
||||
setState(ConnectionState.CONNECTING);
|
||||
|
||||
|
||||
apiService.updateSessionId();
|
||||
|
||||
if(clientSettings.getRoomId() != null)
|
||||
{
|
||||
if (clientSettings.getRoomId() != null) {
|
||||
liveRoomInfo.setRoomId(clientSettings.getRoomId());
|
||||
logger.info("Using roomID from settings: "+clientSettings.getRoomId());
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("Using roomID from settings: " + clientSettings.getRoomId());
|
||||
} else {
|
||||
var roomId = apiService.fetchRoomId(liveRoomInfo.getHostName());
|
||||
liveRoomInfo.setRoomId(roomId);
|
||||
}
|
||||
|
||||
|
||||
var roomData = apiService.fetchRoomInfo();
|
||||
if (roomData.getStatus() == 0 || roomData.getStatus() == 4) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for HostID could not be found. Is the Host online?");
|
||||
if (roomData.getStatus() != LiveRoomMeta.LiveRoomStatus.HostOnline) {
|
||||
throw new TikTokLiveOfflineHostException("LiveStream for Host name could not be found. Is the Host online?");
|
||||
}
|
||||
|
||||
var clientData = apiService.fetchClientData();
|
||||
@@ -140,9 +152,9 @@ public class TikTokLiveClient implements LiveClient {
|
||||
public LiveRoomInfo getRoomInfo() {
|
||||
return liveRoomInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenersManager getListenersManager()
|
||||
{
|
||||
public ListenersManager getListenersManager() {
|
||||
return listenersManager;
|
||||
}
|
||||
|
||||
@@ -156,11 +168,6 @@ public class TikTokLiveClient implements LiveClient {
|
||||
return tikTokGiftManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserManager getUserManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void setState(ConnectionState connectionState) {
|
||||
logger.info("TikTokLive client state: " + connectionState.name());
|
||||
|
||||
@@ -22,26 +22,21 @@
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventBuilder;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
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.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftComboEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.gift.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.data.events.poll.TikTokPollEvent;
|
||||
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.TikTokWebsocketMessageEvent;
|
||||
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,6 +48,7 @@ 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.live.builder.EventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||
import io.github.jwdeveloper.tiktok.utils.ConsoleColors;
|
||||
import io.github.jwdeveloper.tiktok.websocket.TikTokWebSocketClient;
|
||||
@@ -64,8 +60,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.*;
|
||||
|
||||
public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
{
|
||||
public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
||||
|
||||
protected final ClientSettings clientSettings;
|
||||
protected final Logger logger;
|
||||
@@ -76,7 +71,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
this.tikTokEventHandler = new TikTokEventObserver();
|
||||
this.clientSettings = Constants.DefaultClientSettings();
|
||||
this.clientSettings.setHostName(userName);
|
||||
this.logger = Logger.getLogger(TikTokLive.class.getSimpleName()+" "+userName);
|
||||
this.logger = Logger.getLogger(TikTokLive.class.getSimpleName() + " " + userName);
|
||||
this.listeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -105,16 +100,21 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
throw new TikTokLiveException("HostName can not be null");
|
||||
}
|
||||
|
||||
if (clientSettings.getHostName().startsWith("@"))
|
||||
{
|
||||
clientSettings.setHostName(clientSettings.getHostName().substring(1));
|
||||
}
|
||||
|
||||
|
||||
var params = clientSettings.getClientParameters();
|
||||
params.put("app_language", clientSettings.getClientLanguage());
|
||||
params.put("webcast_language", clientSettings.getClientLanguage());
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
var handler = new ConsoleHandler();
|
||||
handler.setFormatter(new Formatter() {
|
||||
@Override
|
||||
public String format(LogRecord record)
|
||||
{
|
||||
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("]: ");
|
||||
@@ -126,9 +126,13 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
logger.setUseParentHandlers(false);
|
||||
logger.addHandler(handler);
|
||||
|
||||
logger.setLevel(clientSettings.getLogLevel());
|
||||
|
||||
if (clientSettings.isPrintToConsole() && clientSettings.getLogLevel() == Level.OFF) {
|
||||
logger.setLevel(Level.ALL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public LiveClient build() {
|
||||
@@ -171,7 +175,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
public CompletableFuture<LiveClient> buildAndConnectAsync() {
|
||||
return CompletableFuture.supplyAsync(this::buildAndConnect);
|
||||
return build().connectAsync();
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onUnhandledSocial(
|
||||
@@ -261,8 +265,8 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboFinishedEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftComboFinishedEvent.class, event);
|
||||
public TikTokLiveClientBuilder onGiftCombo(EventConsumer<TikTokGiftComboEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokGiftComboEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -318,7 +322,6 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onComment(EventConsumer<TikTokCommentEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokCommentEvent.class, event);
|
||||
return this;
|
||||
@@ -328,6 +331,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
tikTokEventHandler.subscribe(TikTokGoalUpdateEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TikTokLiveClientBuilder onRankUpdate(EventConsumer<TikTokRankUpdateEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokRankUpdateEvent.class, event);
|
||||
return this;
|
||||
@@ -349,7 +353,6 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TikTokLiveClientBuilder onJoin(EventConsumer<TikTokJoinEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokJoinEvent.class, event);
|
||||
return this;
|
||||
@@ -404,6 +407,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder
|
||||
tikTokEventHandler.subscribe(TikTokWebsocketResponseEvent.class, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TikTokLiveClientBuilder onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> event) {
|
||||
tikTokEventHandler.subscribe(TikTokWebsocketMessageEvent.class, event);
|
||||
|
||||
@@ -26,7 +26,7 @@ import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
|
||||
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.TikTokGiftComboEvent;
|
||||
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;
|
||||
@@ -142,7 +142,7 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler {
|
||||
}
|
||||
|
||||
if (giftMessage.getRepeatEnd() > 0) {
|
||||
return new TikTokGiftComboFinishedEvent(gift, giftMessage);
|
||||
return new TikTokGiftComboEvent(gift, giftMessage);
|
||||
}
|
||||
|
||||
return new TikTokGiftEvent(gift, giftMessage);
|
||||
|
||||
@@ -30,6 +30,7 @@ import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.mappers.LiveRoomMetaMapper;
|
||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||
|
||||
import javax.script.ScriptEngineManager;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -116,22 +117,24 @@ public class TikTokApiService {
|
||||
|
||||
|
||||
public LiveRoomMeta fetchRoomInfo() {
|
||||
logger.info("Fetch RoomInfo");
|
||||
logger.info("Fetching RoomInfo");
|
||||
try {
|
||||
var response = tiktokHttpClient.getJObjectFromWebcastAPI("room/info/", clientSettings.getClientParameters());
|
||||
var mapper = new LiveRoomMetaMapper();
|
||||
var liveRoomMeta = mapper.map(response);
|
||||
logger.info("RoomInfo status -> " + liveRoomMeta.getStatus());
|
||||
return liveRoomMeta;
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new TikTokLiveRequestException("Failed to fetch room info from WebCast, see stacktrace for more info.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public WebcastResponse fetchClientData() {
|
||||
logger.info("Fetch ClientData");
|
||||
|
||||
logger.info("Fetching ClientData");
|
||||
try {
|
||||
var response = tiktokHttpClient.getDeserializedMessage("im/fetch/", clientSettings.getClientParameters());
|
||||
var response = tiktokHttpClient.getSigningServerMessage("im/fetch/", clientSettings.getClientParameters());
|
||||
clientSettings.getClientParameters().put("cursor", response.getCursor());
|
||||
clientSettings.getClientParameters().put("internal_ext", response.getInternalExt());
|
||||
return response;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class TikTokHttpClient {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public WebcastResponse getDeserializedMessage(String path, Map<String, Object> parameters) {
|
||||
public WebcastResponse getSigningServerMessage(String path, Map<String, Object> parameters) {
|
||||
var bytes = getSignRequest(Constants.TIKTOK_URL_WEBCAST + path, parameters);
|
||||
try {
|
||||
return WebcastResponse.parseFrom(bytes);
|
||||
|
||||
@@ -25,11 +25,11 @@ package io.github.jwdeveloper.tiktok.listener;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokEventListenerMethodException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -42,7 +42,10 @@ public class TikTokListenersManager implements ListenersManager {
|
||||
|
||||
public TikTokListenersManager(List<TikTokEventListener> listeners, TikTokEventObserver tikTokEventHandler) {
|
||||
this.eventObserver = tikTokEventHandler;
|
||||
this.bindingModels = new ArrayList<>(listeners.stream().map(this::bindToEvents).toList());
|
||||
this.bindingModels = new ArrayList<>(listeners.size());
|
||||
for (var listener : listeners) {
|
||||
addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,9 +25,14 @@ package io.github.jwdeveloper.tiktok.mappers;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
|
||||
public class LiveRoomMetaMapper
|
||||
{
|
||||
|
||||
public class LiveRoomMetaMapper {
|
||||
/**
|
||||
* 0 - Unknown
|
||||
* 1 - ?
|
||||
* 2 - Online
|
||||
* 3 - ?
|
||||
* 4 - Offline
|
||||
*/
|
||||
public LiveRoomMeta map(JsonObject input) {
|
||||
var liveRoomMeta = new LiveRoomMeta();
|
||||
|
||||
@@ -35,16 +40,27 @@ public class LiveRoomMetaMapper
|
||||
return liveRoomMeta;
|
||||
}
|
||||
var data = input.getAsJsonObject("data");
|
||||
|
||||
|
||||
if (data.has("status")) {
|
||||
var status = data.get("status");
|
||||
liveRoomMeta.setStatus(status.getAsInt());
|
||||
var statusId = status.getAsInt();
|
||||
var statusValue = switch (statusId) {
|
||||
case 0 -> LiveRoomMeta.LiveRoomStatus.HostNotFound;
|
||||
case 2 -> LiveRoomMeta.LiveRoomStatus.HostOnline;
|
||||
case 4 -> LiveRoomMeta.LiveRoomStatus.HostOffline;
|
||||
default-> LiveRoomMeta.LiveRoomStatus.HostNotFound;
|
||||
};
|
||||
liveRoomMeta.setStatus(statusValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
liveRoomMeta.setStatus(LiveRoomMeta.LiveRoomStatus.HostNotFound);
|
||||
}
|
||||
|
||||
|
||||
if(data.has("age_restricted"))
|
||||
{
|
||||
if (data.has("age_restricted")) {
|
||||
var element = data.getAsJsonObject("age_restricted");
|
||||
var restricted= element.get("restricted").getAsBoolean();
|
||||
var restricted = element.get("restricted").getAsBoolean();
|
||||
liveRoomMeta.setAgeRestricted(restricted);
|
||||
}
|
||||
return liveRoomMeta;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class TikTokWebSocketClient implements SocketClient {
|
||||
|
||||
try {
|
||||
if (clientSettings.isHandleExistingEvents()) {
|
||||
logger.info("Handling existing messages");
|
||||
logger.info("Handling existing events");
|
||||
webResponseHandler.handle(tikTokLiveClient, webcastResponse);
|
||||
}
|
||||
var url = getWebSocketUrl(webcastResponse);
|
||||
|
||||
Reference in New Issue
Block a user