Final Proxy Commit!

This commit is contained in:
kohlerpop1
2024-01-14 14:52:54 -05:00
committed by Jacek W
parent f40a26ad7c
commit 39c3b5b1bc
13 changed files with 173 additions and 105 deletions

View File

@@ -24,7 +24,7 @@ package io.github.jwdeveloper.tiktok.data.events;
import io.github.jwdeveloper.tiktok.annotations.EventMeta; import io.github.jwdeveloper.tiktok.annotations.EventMeta;
import io.github.jwdeveloper.tiktok.annotations.EventType; import io.github.jwdeveloper.tiktok.annotations.EventType;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokLiveClientEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokLiveClientEvent;
import lombok.Getter;
/** /**
* Triggered when the connection gets disconnected. In that case you can call connect() again to have a reconnect logic. * Triggered when the connection gets disconnected. In that case you can call connect() again to have a reconnect logic.
@@ -32,4 +32,12 @@ import io.github.jwdeveloper.tiktok.data.events.common.TikTokLiveClientEvent;
*/ */
@EventMeta(eventType = EventType.Control) @EventMeta(eventType = EventType.Control)
public class TikTokDisconnectedEvent extends TikTokLiveClientEvent { public class TikTokDisconnectedEvent extends TikTokLiveClientEvent {
} @Getter private final String reason;
public TikTokDisconnectedEvent(String reason) {
this.reason = reason.isBlank() ? "None" : reason;
}
public TikTokDisconnectedEvent() {
this("None");
}
}

View File

@@ -22,10 +22,7 @@
*/ */
package io.github.jwdeveloper.tiktok.data.requests; package io.github.jwdeveloper.tiktok.data.requests;
import lombok.AllArgsConstructor; import lombok.*;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
public class LiveUserData { public class LiveUserData {
@@ -38,15 +35,18 @@ public class LiveUserData {
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public static class Response { public static class Response {
private String json; private String json;
private UserStatus userStatus; private UserStatus userStatus;
private String roomId; private String roomId;
private long startedAtTimeStamp; private long startedAtTimeStamp;
public boolean isLiveOnline() {
return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused;
}
public boolean isHostNameValid() {
return userStatus != LiveUserData.UserStatus.NotFound;
}
} }
public enum UserStatus { public enum UserStatus {
@@ -55,6 +55,4 @@ public class LiveUserData {
LivePaused, LivePaused,
Live, Live,
} }
} }

View File

@@ -63,10 +63,11 @@ public class ProxyClientSettings implements Iterator<ProxyData>
} }
@Override @Override
public ProxyData next() public ProxyData next() {
{ return lastSuccess ? proxyList.get(index) : rotate();
if (lastSuccess) }
return proxyList.get(index);
public ProxyData rotate() {
var nextProxy = switch (rotation) var nextProxy = switch (rotation)
{ {
case CONSECUTIVE -> { case CONSECUTIVE -> {

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package io.github.jwdeveloper.tiktok.exceptions;
/*
* Happens while bad response from http proxy request to TikTok
*/
public class TikTokProxyRequestException extends TikTokLiveException
{
public TikTokProxyRequestException() {
}
public TikTokProxyRequestException(String message) {
super(message);
}
public TikTokProxyRequestException(String message, Throwable cause) {
super(message, cause);
}
public TikTokProxyRequestException(Throwable cause) {
super(cause);
}
public TikTokProxyRequestException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -23,7 +23,6 @@
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
import io.github.jwdeveloper.tiktok.http.LiveHttpClient; import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder; import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
@@ -48,8 +47,7 @@ public class TikTokLive {
*/ */
public static boolean isLiveOnline(String hostName) public static boolean isLiveOnline(String hostName)
{ {
LiveUserData.UserStatus status = requests().fetchLiveUserData(hostName).getUserStatus(); return requests().fetchLiveUserData(hostName).isLiveOnline();
return status == LiveUserData.UserStatus.Live || status == LiveUserData.UserStatus.LivePaused;
} }
@@ -72,8 +70,7 @@ public class TikTokLive {
*/ */
public static boolean isHostNameValid(String hostName) public static boolean isHostNameValid(String hostName)
{ {
LiveUserData.UserStatus status = requests().fetchLiveUserData(hostName).getUserStatus(); return requests().fetchLiveUserData(hostName).isHostNameValid();
return status != LiveUserData.UserStatus.NotFound;
} }
/** /**

View File

@@ -76,19 +76,15 @@ public class TikTokLiveClient implements LiveClient {
public void connectAsync(Consumer<LiveClient> onConnection) { public void connectAsync(Consumer<LiveClient> onConnection) {
CompletableFuture.supplyAsync(() -> CompletableFuture.runAsync(() -> {
{
connect(); connect();
onConnection.accept(this); onConnection.accept(this);
return this;
}); });
} }
public CompletableFuture<LiveClient> connectAsync() { public CompletableFuture<LiveClient> connectAsync() {
return CompletableFuture.supplyAsync(() -> return CompletableFuture.supplyAsync(() -> {
{
connect(); connect();
return this; return this;
}); });
@@ -105,8 +101,7 @@ public class TikTokLiveClient implements LiveClient {
if (e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure()) { if (e instanceof TikTokLiveOfflineHostException && clientSettings.isRetryOnConnectionFailure()) {
try { try {
Thread.sleep(clientSettings.getRetryConnectionTimeout().toMillis()); Thread.sleep(clientSettings.getRetryConnectionTimeout().toMillis());
} catch (Exception ignored) { } catch (Exception ignored) {}
}
logger.info("Reconnecting"); logger.info("Reconnecting");
tikTokEventHandler.publish(this, new TikTokReconnectingEvent()); tikTokEventHandler.publish(this, new TikTokReconnectingEvent());
this.connect(); this.connect();
@@ -120,14 +115,12 @@ public class TikTokLiveClient implements LiveClient {
} }
public void tryConnect() { public void tryConnect() {
if (!liveRoomInfo.hasConnectionState(ConnectionState.DISCONNECTED)) if (!liveRoomInfo.hasConnectionState(ConnectionState.DISCONNECTED)) {
{
throw new TikTokLiveException("Already connected"); throw new TikTokLiveException("Already connected");
} }
setState(ConnectionState.CONNECTING); setState(ConnectionState.CONNECTING);
var userDataRequest = new LiveUserData.Request(liveRoomInfo.getHostName()); var userDataRequest = new LiveUserData.Request(liveRoomInfo.getHostName());
var userData = httpClient.fetchLiveUserData(userDataRequest); var userData = httpClient.fetchLiveUserData(userDataRequest);
liveRoomInfo.setStartTime(userData.getStartedAtTimeStamp()); liveRoomInfo.setStartTime(userData.getStartedAtTimeStamp());
@@ -139,7 +132,6 @@ public class TikTokLiveClient implements LiveClient {
throw new TikTokLiveOfflineHostException("User not found: "+liveRoomInfo.getHostUser()); throw new TikTokLiveOfflineHostException("User not found: "+liveRoomInfo.getHostUser());
} }
var liveDataRequest = new LiveData.Request(userData.getRoomId()); var liveDataRequest = new LiveData.Request(userData.getRoomId());
var liveData = httpClient.fetchLiveData(liveDataRequest); var liveData = httpClient.fetchLiveData(liveDataRequest);
if (liveData.getLiveStatus() == LiveData.LiveStatus.HostNotFound) { if (liveData.getLiveStatus() == LiveData.LiveStatus.HostNotFound) {
@@ -155,7 +147,6 @@ public class TikTokLiveClient implements LiveClient {
liveRoomInfo.setAgeRestricted(liveData.isAgeRestricted()); liveRoomInfo.setAgeRestricted(liveData.isAgeRestricted());
liveRoomInfo.setHost(liveData.getHost()); liveRoomInfo.setHost(liveData.getHost());
var liveConnectionRequest =new LiveConnectionData.Request(userData.getRoomId()); var liveConnectionRequest =new LiveConnectionData.Request(userData.getRoomId());
var liveConnectionData = httpClient.fetchLiveConnectionData(liveConnectionRequest); var liveConnectionData = httpClient.fetchLiveConnectionData(liveConnectionRequest);
webSocketClient.start(liveConnectionData, this); webSocketClient.start(liveConnectionData, this);
@@ -181,7 +172,6 @@ public class TikTokLiveClient implements LiveClient {
tikTokEventHandler.publish(this, event); tikTokEventHandler.publish(this, event);
} }
public LiveRoomInfo getRoomInfo() { public LiveRoomInfo getRoomInfo() {
return liveRoomInfo; return liveRoomInfo;
} }
@@ -200,6 +190,4 @@ public class TikTokLiveClient implements LiveClient {
public GiftManager getGiftManager() { public GiftManager getGiftManager() {
return tikTokGiftManager; return tikTokGiftManager;
} }
} }

View File

@@ -156,7 +156,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
var httpClientFactory = new HttpClientFactory(clientSettings); var httpClientFactory = new HttpClientFactory(clientSettings);
var tikTokLiveHttpClient = new TikTokLiveHttpClient(httpClientFactory); var tikTokLiveHttpClient = new TikTokLiveHttpClient(httpClientFactory, clientSettings);
var webSocketClient = new TikTokWebSocketClient( var webSocketClient = new TikTokWebSocketClient(
clientSettings, clientSettings,
@@ -346,7 +346,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
@Override @Override
public LiveClientBuilder onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event) { public TikTokLiveClientBuilder onRoomInfo(EventConsumer<TikTokRoomInfoEvent> event) {
tikTokEventHandler.subscribe(TikTokRoomInfoEvent.class, event); tikTokEventHandler.subscribe(TikTokRoomInfoEvent.class, event);
return this; return this;
} }
@@ -358,7 +358,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
} }
@Override @Override
public LiveClientBuilder onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event) { public TikTokLiveClientBuilder onLiveUnpaused(EventConsumer<TikTokLiveUnpausedEvent> event) {
tikTokEventHandler.subscribe(TikTokLiveUnpausedEvent.class, event); tikTokEventHandler.subscribe(TikTokLiveUnpausedEvent.class, event);
return this; return this;
} }

View File

@@ -24,13 +24,14 @@ package io.github.jwdeveloper.tiktok;
import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.InvalidProtocolBufferException;
import io.github.jwdeveloper.tiktok.data.requests.*; import io.github.jwdeveloper.tiktok.data.requests.*;
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings; import io.github.jwdeveloper.tiktok.data.settings.*;
import io.github.jwdeveloper.tiktok.exceptions.*; import io.github.jwdeveloper.tiktok.exceptions.*;
import io.github.jwdeveloper.tiktok.http.*; import io.github.jwdeveloper.tiktok.http.*;
import io.github.jwdeveloper.tiktok.http.mappers.*; import io.github.jwdeveloper.tiktok.http.mappers.*;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.util.Optional;
public class TikTokLiveHttpClient implements LiveHttpClient { public class TikTokLiveHttpClient implements LiveHttpClient {
@@ -43,13 +44,15 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
private static final String TIKTOK_URL_WEBCAST = "https://webcast.tiktok.com/webcast/"; private static final String TIKTOK_URL_WEBCAST = "https://webcast.tiktok.com/webcast/";
private final HttpClientFactory httpFactory; private final HttpClientFactory httpFactory;
private final LiveClientSettings clientSettings;
private final LiveUserDataMapper liveUserDataMapper; private final LiveUserDataMapper liveUserDataMapper;
private final LiveDataMapper liveDataMapper; private final LiveDataMapper liveDataMapper;
private final SignServerResponseMapper signServerResponseMapper; private final SignServerResponseMapper signServerResponseMapper;
private final GiftsDataMapper giftsDataMapper; private final GiftsDataMapper giftsDataMapper;
public TikTokLiveHttpClient(HttpClientFactory factory) { public TikTokLiveHttpClient(HttpClientFactory factory, LiveClientSettings settings) {
this.httpFactory = factory; this.httpFactory = factory;
clientSettings = settings;
liveUserDataMapper = new LiveUserDataMapper(); liveUserDataMapper = new LiveUserDataMapper();
liveDataMapper = new LiveDataMapper(); liveDataMapper = new LiveDataMapper();
signServerResponseMapper = new SignServerResponseMapper(); signServerResponseMapper = new SignServerResponseMapper();
@@ -57,7 +60,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
} }
public TikTokLiveHttpClient() { public TikTokLiveHttpClient() {
this(new HttpClientFactory(LiveClientSettings.createDefault())); this(new HttpClientFactory(LiveClientSettings.createDefault()), LiveClientSettings.createDefault());
} }
@@ -82,7 +85,26 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
@Override @Override
public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) { public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) {
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled()) {
while (proxyClientSettings.hasNext()) {
try {
var url = TIKTOK_URL_WEB + "api-live/user/room";
var optional = httpFactory.client(url)
.withParam("uniqueId", request.getUserName())
.withParam("sourceType", "54")
.build()
.toJsonResponse();
if (optional.isEmpty()) {
throw new TikTokLiveRequestException("Unable to get information's about user");
}
var json = optional.get();
return liveUserDataMapper.map(json);
} catch (TikTokProxyRequestException ignored) {}
}
}
var url = TIKTOK_URL_WEB + "api-live/user/room"; var url = TIKTOK_URL_WEB + "api-live/user/room";
var optional = httpFactory.client(url) var optional = httpFactory.client(url)
.withParam("uniqueId", request.getUserName()) .withParam("uniqueId", request.getUserName())
@@ -105,7 +127,25 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
@Override @Override
public LiveData.Response fetchLiveData(LiveData.Request request) { public LiveData.Response fetchLiveData(LiveData.Request request) {
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled()) {
while (proxyClientSettings.hasNext()) {
try {
var url = TIKTOK_URL_WEBCAST + "room/info";
var optional = httpFactory.client(url)
.withParam("room_id", request.getRoomId())
.build()
.toJsonResponse();
if (optional.isEmpty()) {
throw new TikTokLiveRequestException("Unable to get info about live room");
}
var json = optional.get();
return liveDataMapper.map(json);
} catch (TikTokProxyRequestException ignored) {}
}
}
var url = TIKTOK_URL_WEBCAST + "room/info"; var url = TIKTOK_URL_WEBCAST + "room/info";
var optional = httpFactory.client(url) var optional = httpFactory.client(url)
.withParam("room_id", request.getRoomId()) .withParam("room_id", request.getRoomId())
@@ -127,14 +167,15 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
@Override @Override
public LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request) { public LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request) {
HttpResponse<byte[]> credentialsResponse = getOptionalProxyResponse(request).orElseGet(()-> {
var signServerResponse = getSignedUrl(request.getRoomId()); SignServerResponse signServerResponse = getSignedUrl(request.getRoomId());
var credentialsResponse = getWebsocketCredentialsResponse(signServerResponse.getSignedUrl()); return getWebsocketCredentialsResponse(signServerResponse.getSignedUrl());
});
try { try {
var optionalHeader = credentialsResponse.headers().firstValue("set-cookie"); var optionalHeader = credentialsResponse.headers().firstValue("set-cookie");
if (optionalHeader.isEmpty()) { if (optionalHeader.isEmpty()) {
throw new TikTokSignServerException("Sign server does not returned set-cookie header"); throw new TikTokSignServerException("Sign server did not return the set-cookie header");
} }
var websocketCookie = optionalHeader.get(); var websocketCookie = optionalHeader.get();
var webcastResponse = WebcastResponse.parseFrom(credentialsResponse.body()); var webcastResponse = WebcastResponse.parseFrom(credentialsResponse.body());
@@ -189,4 +230,18 @@ public class TikTokLiveHttpClient implements LiveHttpClient {
return optionalResponse.get(); return optionalResponse.get();
} }
Optional<HttpResponse<byte[]>> getOptionalProxyResponse(LiveConnectionData.Request request) {
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled()) {
while (proxyClientSettings.hasNext()) {
try {
SignServerResponse signServerResponse = getSignedUrl(request.getRoomId());
HttpResponse<byte[]> credentialsResponse = getWebsocketCredentialsResponse(signServerResponse.getSignedUrl());
clientSettings.getHttpSettings().getProxyClientSettings().rotate();
return Optional.of(credentialsResponse);
} catch (TikTokProxyRequestException | TikTokSignServerException ignored) {}
}
}
return Optional.empty();
}
} }

View File

@@ -23,12 +23,14 @@
package io.github.jwdeveloper.tiktok.http; package io.github.jwdeveloper.tiktok.http;
import io.github.jwdeveloper.tiktok.data.settings.*; import io.github.jwdeveloper.tiktok.data.settings.*;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException; import io.github.jwdeveloper.tiktok.exceptions.*;
import javax.net.ssl.*; import javax.net.ssl.*;
import java.io.IOException;
import java.net.*; import java.net.*;
import java.net.http.*; import java.net.http.*;
import java.net.http.HttpResponse.ResponseInfo; import java.net.http.HttpResponse.ResponseInfo;
import java.security.*;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -93,7 +95,7 @@ public class HttpProxyClient extends HttpClient
URL url = toUrl().toURL(); URL url = toUrl().toURL();
while (proxySettings.hasNext()) { if (proxySettings.hasNext()) {
try { try {
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxySettings.next().toSocketAddress()); Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxySettings.next().toSocketAddress());
@@ -117,21 +119,24 @@ public class HttpProxyClient extends HttpClient
proxySettings.setLastSuccess(true); proxySettings.setLastSuccess(true);
return Optional.of(response); return Optional.of(response);
} catch (SocketException | SocketTimeoutException e) { } catch (IOException e) {
e.printStackTrace();
if (proxySettings.isAutoDiscard()) if (proxySettings.isAutoDiscard())
proxySettings.remove(); proxySettings.remove();
proxySettings.setLastSuccess(false); proxySettings.setLastSuccess(false);
throw new TikTokProxyRequestException(e);
} catch (Exception e) { } catch (Exception e) {
throw new TikTokLiveRequestException(e); throw new TikTokLiveRequestException(e);
} }
} }
throw new TikTokLiveRequestException("No more proxies available!"); throw new TikTokLiveRequestException("No more proxies available!");
} catch (Exception e) { } catch (NoSuchAlgorithmException | MalformedURLException | KeyManagementException e) {
// Should never be reached! // Should never be reached!
System.out.println("handleSocksProxyRequest()! If you see this message, reach us on discord!"); System.out.println("handleSocksProxyRequest()! If you see this message, reach us on discord!");
e.printStackTrace(); e.printStackTrace();
return Optional.empty(); return Optional.empty();
} catch (TikTokLiveRequestException e) {
e.printStackTrace();
return Optional.empty();
} }
} }

View File

@@ -26,12 +26,10 @@ import com.google.gson.JsonParser;
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData; import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
public class LiveUserDataMapper { public class LiveUserDataMapper
{
public LiveUserData.Response map(String json) { public LiveUserData.Response map(String json) {
var parsedJson = JsonParser.parseString(json); var jsonObject = JsonParser.parseString(json).getAsJsonObject();
var jsonObject = parsedJson.getAsJsonObject();
var message = jsonObject.get("message").getAsString(); var message = jsonObject.get("message").getAsString();
@@ -64,6 +62,5 @@ public class LiveUserDataMapper {
}; };
return new LiveUserData.Response(json, statusEnum, roomId, startTime); return new LiveUserData.Response(json, statusEnum, roomId, startTime);
} }
} }

View File

@@ -52,6 +52,7 @@ public class TikTokWebSocketClient implements SocketClient {
this.tikTokEventHandler = tikTokEventHandler; this.tikTokEventHandler = tikTokEventHandler;
isConnected = false; isConnected = false;
} }
@Override @Override
public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) public void start(LiveConnectionData.Response connectionData, LiveClient liveClient)
{ {
@@ -71,7 +72,6 @@ public class TikTokWebSocketClient implements SocketClient {
liveClient); liveClient);
// ProxyClientSettings proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings(); // ProxyClientSettings proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
//
// if (proxyClientSettings.isEnabled()) // if (proxyClientSettings.isEnabled())
// connectProxy(proxyClientSettings); // connectProxy(proxyClientSettings);
// else // else

View File

@@ -81,13 +81,12 @@ public class TikTokWebSocketListener extends WebSocketClient {
pushFrameBuilder.setPayload(webcastResponse.getInternalExtBytes()); pushFrameBuilder.setPayload(webcastResponse.getInternalExtBytes());
if (isNotClosing()) if (isNotClosing())
{ {
this.send(pushFrameBuilder.build().toByteArray()); this.send(pushFrameBuilder.build().toByteArray());
} }
} }
messageHandler.handle(tikTokLiveClient, webcastResponse); messageHandler.handle(tikTokLiveClient, webcastResponse);
} }
@Override @Override
public void onOpen(ServerHandshake serverHandshake) { public void onOpen(ServerHandshake serverHandshake) {
tikTokEventHandler.publish(tikTokLiveClient, new TikTokConnectedEvent()); tikTokEventHandler.publish(tikTokLiveClient, new TikTokConnectedEvent());
@@ -96,10 +95,9 @@ public class TikTokWebSocketListener extends WebSocketClient {
} }
} }
@Override @Override
public void onClose(int code, String reason, boolean remote) { public void onClose(int code, String reason, boolean remote) {
tikTokEventHandler.publish(tikTokLiveClient, new TikTokDisconnectedEvent()); tikTokEventHandler.publish(tikTokLiveClient, new TikTokDisconnectedEvent(reason));
tikTokLiveClient.disconnect(); tikTokLiveClient.disconnect();
} }
@@ -111,8 +109,6 @@ public class TikTokWebSocketListener extends WebSocketClient {
} }
} }
private Optional<WebcastPushFrame> getWebcastPushFrame(byte[] buffer) { private Optional<WebcastPushFrame> getWebcastPushFrame(byte[] buffer) {
try { try {
var websocketMessage = WebcastPushFrame.parseFrom(buffer); var websocketMessage = WebcastPushFrame.parseFrom(buffer);
@@ -137,9 +133,8 @@ public class TikTokWebSocketListener extends WebSocketClient {
return !isClosed() && !isClosing(); return !isClosed() && !isClosing();
} }
@Override @Override
public void onMessage(String s) { public void onMessage(String s) {
System.err.println(s); // System.err.println(s);
} }
} }

View File

@@ -22,54 +22,29 @@
*/ */
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import java.net.*; import java.net.Proxy;
import java.net.http.*;
import java.util.*;
import java.util.stream.Stream;
public class ProxyExample public class ProxyExample
{ {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
// TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME) TikTokLive.newClient(SimpleExample.TIKTOK_HOSTNAME)
.configure(clientSettings -> {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.proxyscrape.com/v2/?request=displayproxies&protocol=socks4,socks5&timeout=10000&country=us")).GET().build();
HttpResponse<Stream<String>> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofLines());
List<AbstractMap.SimpleEntry<String, Integer>> entries = new ArrayList<>(response.body().map(s -> {
String[] split = s.split(":");
return new AbstractMap.SimpleEntry<>(split[0], Integer.parseInt(split[1]));
}).toList());
TikTokLive.newClient("dash4214")
.configure(clientSettings ->
{
clientSettings.setPrintToConsole(true); clientSettings.setPrintToConsole(true);
clientSettings.getHttpSettings().configureProxy(proxySettings -> { clientSettings.getHttpSettings().configureProxy(proxySettings -> {
proxySettings.setOnProxyUpdated(proxyData -> proxySettings.setOnProxyUpdated(proxyData -> System.err.println("Next proxy: " + proxyData.toString()));
{
System.err.println("Next proxy: "+proxyData.toString());
});
proxySettings.setType(Proxy.Type.SOCKS); proxySettings.setType(Proxy.Type.SOCKS);
entries.forEach(entry -> proxySettings.addProxy(entry.getKey(), entry.getValue())); proxySettings.addProxy("localhost", 8080);
}); });
}) })
.onComment((liveClient, event) -> {
liveClient.getLogger().info(event.getUser().getName()+": "+event.getText());
})
.onConnected((liveClient, event) -> .onConnected((liveClient, event) ->
{ liveClient.getLogger().info("Connected "+liveClient.getRoomInfo().getHostName()))
liveClient.getLogger().info("Hello world!");
})
.onDisconnected((liveClient, event) -> .onDisconnected((liveClient, event) ->
{ liveClient.getLogger().info("Disconnect reason: "+event.getReason()))
liveClient.getLogger().info("Goodbye world!"); .onLiveEnded((liveClient, event) ->
}) liveClient.getLogger().info("Live Ended"))
.onError((liveClient, event) -> .onError((liveClient, event) ->
{ event.getException().printStackTrace())
event.getException().printStackTrace();
})
.buildAndConnect(); .buildAndConnect();
System.in.read(); System.in.read();
} }
} }