Merge pull request #77 from jwdeveloper/develop-1.6.2

Develop 1.6.2
This commit is contained in:
David Kohler
2024-05-23 18:42:15 -04:00
committed by GitHub
11 changed files with 85 additions and 24 deletions

View File

@@ -93,7 +93,7 @@ public class Picture {
}
}
public static Picture Empty() {
public static Picture empty() {
return new Picture("");
}

View File

@@ -169,7 +169,7 @@ public class User {
public static User EMPTY = new User(0L,
"",
Picture.Empty(),
Picture.empty(),
0,
0,
List.of(Badge.empty()));

View File

@@ -33,20 +33,15 @@ import java.util.logging.Level;
@Data
public class LiveClientSettings {
/**
* TODO: give better description
* <p>
* sets client in the offline mode, so it do not connects to TikTok servers
* it makes sense to use it when you are testing client with your custom events
* Sets client to offline mode, prohibits connection to TikTok servers
* @apiNote Useful when testing client with custom events
*/
private boolean offline;
/**
* TODO: give better description
* <p>
* Determines if gifts data is downloaded before TikTokLive starts,
* when `false` then client.giftManager() does not contain initial gifts
* Fetch and download gifts data before TikTokLive starts
* @apiNote If `false`, client.giftManager() does not contain initial gifts
*/
private boolean fetchGifts = true;

View File

@@ -30,10 +30,14 @@ import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
public interface LiveHttpClient
{
/**
* @return list of gifts that are available in your country
* @return {@link GiftsData.Response} list of gifts that are compiled and available on github
*/
GiftsData.Response fetchGiftsData();
/**
* @return {@link GiftsData.Response} list of gifts that are available in your region / livestream
*/
GiftsData.Response fetchRoomGiftsData(String room_id);
/**
* Returns information about user that is having a livestream

View File

@@ -128,6 +128,9 @@ public class TikTokLiveClient implements LiveClient {
liveRoomInfo.setStartTime(userData.getStartedAtTimeStamp());
liveRoomInfo.setRoomId(userData.getRoomId());
if (clientSettings.isFetchGifts())
giftsManager.attachGiftsList(httpClient.fetchRoomGiftsData(userData.getRoomId()).getGifts());
if (userData.getUserStatus() == LiveUserData.UserStatus.Offline)
throw new TikTokLiveOfflineHostException("User is offline: " + liveRoomInfo.getHostName());

View File

@@ -43,6 +43,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
private static final String TIKTOK_URL_WEB = "https://www.tiktok.com/";
private static final String TIKTOK_URL_WEBCAST = "https://webcast.tiktok.com/webcast/";
public static final String TIKTOK_GIFTS_URL = "https://raw.githubusercontent.com/TikTok-LIVE-Private/GiftsGenerator/master/page/public/gifts.json";
public static final String TIKTOK_ROOM_GIFTS_URL = TIKTOK_URL_WEBCAST+"gift/list/";
public static final int TIKTOK_AGE_RESTRICTED_CODE = 4003110;
private final HttpClientFactory httpFactory;
@@ -65,6 +66,31 @@ public class TikTokLiveHttpClient implements LiveHttpClient
this(new HttpClientFactory(LiveClientSettings.createDefault()), LiveClientSettings.createDefault());
}
public GiftsData.Response fetchRoomGiftsData(String room_id) {
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled()) {
while (proxyClientSettings.hasNext()) {
try {
return getRoomGiftsData(room_id);
} catch (TikTokProxyRequestException ignored) {}
}
}
return getRoomGiftsData(room_id);
}
public GiftsData.Response getRoomGiftsData(String room_id) {
var result = httpFactory.client(TIKTOK_ROOM_GIFTS_URL)
.withParam("room_id", room_id)
.build()
.toJsonResponse();
if (result.isFailure())
throw new TikTokLiveRequestException("Unable to fetch gifts information's - "+result);
var json = result.getContent();
return giftsDataMapper.mapRoom(json);
}
public GiftsData.Response fetchGiftsData() {
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled()) {

View File

@@ -18,6 +18,11 @@ public class TikTokLiveHttpOfflineClient implements LiveHttpClient {
return new GiftsData.Response("", List.of());
}
@Override
public GiftsData.Response fetchRoomGiftsData(String room_id) {
return new GiftsData.Response("", List.of());
}
@Override
public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) {
return new LiveUserData.Response("", LiveUserData.UserStatus.Live, "offline_room_id", 0);

View File

@@ -4,7 +4,7 @@ import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
import io.github.jwdeveloper.tiktok.live.GiftsManager;
import java.util.*;
import java.util.function.Predicate;
import java.util.function.*;
import java.util.stream.Collectors;
public class TikTokGiftsManager implements GiftsManager {
@@ -12,7 +12,7 @@ public class TikTokGiftsManager implements GiftsManager {
public TikTokGiftsManager(List<Gift> giftList)
{
giftsByIdIndex = giftList.stream().collect(Collectors.toConcurrentMap(Gift::getId, e -> e));
giftsByIdIndex = giftList.stream().collect(Collectors.toConcurrentMap(Gift::getId, Function.identity()));
}
public void attachGift(Gift gift) {

View File

@@ -22,15 +22,15 @@
*/
package io.github.jwdeveloper.tiktok.http.mappers;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.*;
import io.github.jwdeveloper.tiktok.data.models.Picture;
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
import io.github.jwdeveloper.tiktok.data.requests.GiftsData;
import java.util.ArrayList;
import java.util.List;
public class GiftsDataMapper {
public GiftsData.Response map(String json) {
var parsedJson = JsonParser.parseString(json);
var jsonObject = parsedJson.getAsJsonObject();
@@ -42,7 +42,6 @@ public class GiftsDataMapper {
return new GiftsData.Response(json, gifts);
}
private Gift mapSingleGift(JsonElement jsonElement) {
var jsonObject = jsonElement.getAsJsonObject();
@@ -52,4 +51,34 @@ public class GiftsDataMapper {
var image = jsonObject.get("image").getAsString();
return new Gift(id, name, diamondCost, new Picture(image), jsonObject);
}
public GiftsData.Response mapRoom(String json) {
var parsedJson = JsonParser.parseString(json);
var jsonObject = parsedJson.getAsJsonObject();
if (jsonObject.get("data") instanceof JsonObject data && data.get("gifts") instanceof JsonArray giftArray) {
var gifts = giftArray.asList().parallelStream()
.map(this::mapSingleRoomGift)
.toList();
return new GiftsData.Response(json, gifts);
}
return new GiftsData.Response("", List.of());
}
private Gift mapSingleRoomGift(JsonElement jsonElement) {
var jsonObject = jsonElement.getAsJsonObject();
var id = jsonObject.get("id").getAsInt();
var name = jsonObject.get("name").getAsString();
var diamondCost = jsonObject.get("diamond_count").getAsInt();
Picture picture;
if (jsonObject.get("image") instanceof JsonObject image && image.get("url_list") instanceof JsonArray urls && !urls.isEmpty()) {
String url = urls.get(0).getAsString();
if (url.endsWith(".webp"))
url = url.substring(0, url.length()-4)+"png";
picture = new Picture(url);
} else
picture = Picture.empty();
return new Gift(id, name, diamondCost, picture, jsonObject);
}
}

View File

@@ -33,7 +33,6 @@ import org.java_websocket.client.WebSocketClient;
import javax.net.ssl.*;
import java.net.Proxy;
import java.security.cert.X509Certificate;
import java.util.HashMap;
public class TikTokWebSocketClient implements SocketClient {
private final LiveClientSettings clientSettings;
@@ -63,7 +62,7 @@ public class TikTokWebSocketClient implements SocketClient {
messageHandler.handle(liveClient, connectionData.getWebcastResponse());
var headers = new HashMap<String, String>();
var headers = clientSettings.getHttpSettings().getHeaders();
headers.put("Cookie", connectionData.getWebsocketCookies());
webSocketClient = new TikTokWebSocketListener(connectionData.getWebsocketUrl(),
headers,

View File

@@ -77,7 +77,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
<dependency>