From cfef082d3b2791e0ebdd74933918c55ea0b5ceb8 Mon Sep 17 00:00:00 2001 From: kohlerpop1 Date: Fri, 28 Jun 2024 23:07:10 -0400 Subject: [PATCH] Updated ProxyData exceptions to include previous exception to finish stacktrace Updated LiveUserData.Request to throw an IllegalArgumentException when a null or blank username is provided Updated HttpClientSettings to use setProxyClientSettings instead of direct access Fixed ProxyRotation bug starting at index 1 instead of 0 and made methods default to synchronized in case concurrency is used in implementors code Changed HttpClient#toUrl to toUri Added @Getter to HttpClientFactory for liveClientSettings Added consumer to TikTokLive#requests so that way proxies can be used when calling the fetch methods Changed LiveUserData.Response#startTime to clarify the variable name --- .../tiktok/data/dto/ProxyData.java | 8 +-- .../tiktok/data/requests/LiveUserData.java | 17 +++--- .../data/settings/HttpClientSettings.java | 2 +- .../data/settings/ProxyClientSettings.java | 53 +++++++++++-------- .../github/jwdeveloper/tiktok/TikTokLive.java | 13 ++++- .../jwdeveloper/tiktok/TikTokLiveClient.java | 2 +- .../tiktok/TikTokLiveClientBuilder.java | 4 +- .../tiktok/TikTokLiveHttpClient.java | 12 +++-- .../jwdeveloper/tiktok/http/HttpClient.java | 4 +- .../tiktok/http/HttpClientFactory.java | 2 + .../tiktok/http/HttpProxyClient.java | 4 +- 11 files changed, 71 insertions(+), 50 deletions(-) diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/dto/ProxyData.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/dto/ProxyData.java index e1a75ea..cca5afc 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/dto/ProxyData.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/dto/ProxyData.java @@ -50,16 +50,12 @@ public class ProxyData return new ProxyData(address, port); } catch (NumberFormatException e) { - throw new IllegalArgumentException("Port must be a valid integer!"); + throw new IllegalArgumentException("Port must be a valid integer!", e); } catch (UnknownHostException e) { - throw new IllegalArgumentException("Address must be valid IPv4, IPv6, or domain name!"); + throw new IllegalArgumentException("Address must be valid IPv4, IPv6, or domain name!", e); } } - public ProxyData clone() { - return new ProxyData(address, port); - } - public InetSocketAddress toSocketAddress() { return new InetSocketAddress(address, port); } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/requests/LiveUserData.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/requests/LiveUserData.java index ce20ce8..44ad687 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/requests/LiveUserData.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/requests/LiveUserData.java @@ -27,18 +27,23 @@ import lombok.*; public class LiveUserData { @Getter - @AllArgsConstructor public static class Request { - private String userName; + private final String userName; + + public Request(String userName) { + if (userName == null || userName.isBlank()) + throw new IllegalArgumentException("Invalid empty username!"); + this.userName = userName; + } } @Getter @AllArgsConstructor public static class Response { - private String json; - private UserStatus userStatus; - private String roomId; - private long startedAtTimeStamp; + private final String json; + private final UserStatus userStatus; + private final String roomId; + private final long startTime; public boolean isLiveOnline() { return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused; diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/HttpClientSettings.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/HttpClientSettings.java index 7f724f4..33f3bbe 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/HttpClientSettings.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/HttpClientSettings.java @@ -97,7 +97,7 @@ public class HttpClientSettings { newSettings.getHeaders().putAll(new TreeMap<>(this.headers)); newSettings.getCookies().putAll(new TreeMap<>(this.cookies)); newSettings.getParams().putAll(new TreeMap<>(this.params)); - newSettings.proxyClientSettings = this.proxyClientSettings; + newSettings.setProxyClientSettings(this.proxyClientSettings); return newSettings; } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/ProxyClientSettings.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/ProxyClientSettings.java index ab295e1..2b56a25 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/ProxyClientSettings.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/settings/ProxyClientSettings.java @@ -36,7 +36,7 @@ public class ProxyClientSettings implements Iterator private boolean enabled, autoDiscard = true, fallback = true; private Rotation rotation = Rotation.CONSECUTIVE; private final List proxyList = new ArrayList<>(); - private int index = -1; + private int index; private Proxy.Type type = Proxy.Type.DIRECT; private Consumer onProxyUpdated = x -> {}; @@ -57,33 +57,27 @@ public class ProxyClientSettings implements Iterator } @Override - public boolean hasNext() { + public synchronized boolean hasNext() { return !proxyList.isEmpty(); } @Override - public ProxyData next() { - var nextProxy = switch (rotation) - { - case CONSECUTIVE -> { - index = (index+1) % proxyList.size(); - yield proxyList.get(index).clone(); + public synchronized ProxyData next() { + try { + var nextProxy = proxyList.get(index); + onProxyUpdated.accept(nextProxy); + return nextProxy; + } finally { + switch (rotation) { + case CONSECUTIVE -> index = ++index % proxyList.size(); + case RANDOM -> index = (int) (Math.random() * proxyList.size()); + case NONE -> index = Math.max(index, 0); } - case RANDOM -> { - index = new Random().nextInt(proxyList.size()); - yield proxyList.get(index).clone(); - } - case NONE -> { - index = Math.max(index, 0); - yield proxyList.get(index).clone(); - } - }; - onProxyUpdated.accept(nextProxy); - return nextProxy; - } + } + } @Override - public void remove() { + public synchronized void remove() { proxyList.remove(index); } @@ -97,8 +91,8 @@ public class ProxyClientSettings implements Iterator } } - public ProxyClientSettings clone() - { + @Override + public ProxyClientSettings clone() { ProxyClientSettings settings = new ProxyClientSettings(); settings.setEnabled(enabled); settings.setRotation(rotation); @@ -109,6 +103,19 @@ public class ProxyClientSettings implements Iterator return settings; } + @Override + public String toString() { + return "ProxyClientSettings{" + + "enabled=" + enabled + + ", autoDiscard=" + autoDiscard + + ", fallback=" + fallback + + ", rotation=" + rotation + + ", proxyList=" + proxyList + + ", index=" + index + + ", type=" + type + + '}'; + } + public enum Rotation { /** Rotate addresses consecutively, from proxy 0 -> 1 -> 2 -> ...etc. */ diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLive.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLive.java index 4b4aa89..6126703 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLive.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLive.java @@ -23,12 +23,14 @@ package io.github.jwdeveloper.tiktok; +import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings; import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager; import io.github.jwdeveloper.tiktok.http.LiveHttpClient; import io.github.jwdeveloper.tiktok.live.GiftsManager; import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; public class TikTokLive { @@ -82,13 +84,22 @@ public class TikTokLive { return CompletableFuture.supplyAsync(() -> isHostNameValid(hostName)); } + /** + * Use to get some data from TikTok about users are lives + * + * @return LiveHttpClient + */ + public static LiveHttpClient requests(Consumer consumer) { + return new TikTokLiveHttpClient(consumer); + } + /** * Use to get some data from TikTok about users are lives * * @return LiveHttpClient */ public static LiveHttpClient requests() { - return new TikTokLiveHttpClient(); + return requests(liveClientSettings -> {}); } private static GiftsManager giftsManager; diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClient.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClient.java index 15e98be..2420bc2 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClient.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClient.java @@ -125,7 +125,7 @@ public class TikTokLiveClient implements LiveClient { tikTokEventHandler.publish(this, new TikTokConnectingEvent()); var userDataRequest = new LiveUserData.Request(liveRoomInfo.getHostName()); var userData = httpClient.fetchLiveUserData(userDataRequest); - liveRoomInfo.setStartTime(userData.getStartedAtTimeStamp()); + liveRoomInfo.setStartTime(userData.getStartTime()); liveRoomInfo.setRoomId(userData.getRoomId()); if (clientSettings.isFetchGifts()) diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java index 80f1f97..258b8d9 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java @@ -117,11 +117,9 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder { var listenerManager = new TikTokListenersManager(listeners, eventHandler); - var httpClientFactory = new HttpClientFactory(clientSettings); - var liveHttpClient = clientSettings.isOffline() ? new TikTokLiveHttpOfflineClient() : - new TikTokLiveHttpClient(httpClientFactory, clientSettings); + new TikTokLiveHttpClient(new HttpClientFactory(clientSettings)); var eventsMapper = createMapper(giftsManager, tiktokRoomInfo); var messageHandler = new TikTokLiveMessageHandler(eventHandler, eventsMapper); diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveHttpClient.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveHttpClient.java index 7387a13..86092d8 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveHttpClient.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveHttpClient.java @@ -32,6 +32,7 @@ import io.github.jwdeveloper.tiktok.http.mappers.*; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse; import java.net.http.HttpResponse; +import java.util.function.Consumer; import java.util.logging.Logger; public class TikTokLiveHttpClient implements LiveHttpClient @@ -53,17 +54,18 @@ public class TikTokLiveHttpClient implements LiveHttpClient private final GiftsDataMapper giftsDataMapper; private final Logger logger; - public TikTokLiveHttpClient(HttpClientFactory factory, LiveClientSettings settings) { + public TikTokLiveHttpClient(HttpClientFactory factory) { this.httpFactory = factory; - this.clientSettings = settings; + this.clientSettings = factory.getLiveClientSettings(); this.logger = LoggerFactory.create("HttpClient-"+hashCode(), clientSettings); liveUserDataMapper = new LiveUserDataMapper(); liveDataMapper = new LiveDataMapper(); giftsDataMapper = new GiftsDataMapper(); } - public TikTokLiveHttpClient() { - this(new HttpClientFactory(LiveClientSettings.createDefault()), LiveClientSettings.createDefault()); + public TikTokLiveHttpClient(Consumer consumer) { + this(new HttpClientFactory(LiveClientSettings.createDefault())); + consumer.accept(clientSettings); } public GiftsData.Response fetchRoomGiftsData(String room_id) { @@ -191,7 +193,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient .withParam("internal_ext", webcastResponse.getInternalExt()) .withParams(webcastResponse.getRouteParamsMapMap()) .build() - .toUrl(); + .toUri(); return new LiveConnectionData.Response(websocketCookie, webSocketUrl, webcastResponse); } catch (InvalidProtocolBufferException e) { diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClient.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClient.java index eb7a228..25575a3 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClient.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClient.java @@ -90,14 +90,14 @@ public class HttpClient { return toResponse().map(HttpResponse::body); } - public URI toUrl() { + public URI toUri() { var stringUrl = prepareUrlWithParameters(url, httpClientSettings.getParams()); return URI.create(stringUrl); } protected HttpRequest prepareGetRequest() { var requestBuilder = HttpRequest.newBuilder().GET(); - requestBuilder.uri(toUrl()); + requestBuilder.uri(toUri()); requestBuilder.timeout(httpClientSettings.getTimeout()); httpClientSettings.getHeaders().forEach(requestBuilder::setHeader); diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClientFactory.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClientFactory.java index c645560..8aa39ad 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClientFactory.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpClientFactory.java @@ -23,7 +23,9 @@ package io.github.jwdeveloper.tiktok.http; import io.github.jwdeveloper.tiktok.data.settings.*; +import lombok.Getter; +@Getter public class HttpClientFactory { private final LiveClientSettings liveClientSettings; diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpProxyClient.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpProxyClient.java index 771234e..4907587 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpProxyClient.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/http/HttpProxyClient.java @@ -95,7 +95,7 @@ public class HttpProxyClient extends HttpClient { public X509Certificate[] getAcceptedIssuers() { return null; } }}, null); - URL url = toUrl().toURL(); + URL url = toUri().toURL(); if (proxySettings.hasNext()) { try { @@ -117,7 +117,7 @@ public class HttpProxyClient extends HttpClient { var responseInfo = createResponseInfo(socksConnection.getResponseCode(), headers); - var response = createHttpResponse(body, toUrl(), responseInfo); + var response = createHttpResponse(body, toUri(), responseInfo); return ActionResult.success(response); } catch (IOException e) {