Compare commits

...

6 Commits

Author SHA1 Message Date
kohlerpop1
fb458e7e7d Rename pinging-task to heartbeat-task! 2024-07-30 20:36:45 -04:00
kohlerpop1
5f5ada312a Renamed PingTask to HeartbeatTask to reflect discovered byte array of TikTok's custom heartbeat value 2024-07-30 16:09:50 -04:00
GitHub Action
cb20c3dd3a Update version in pom.xml 2024-07-27 23:20:36 +00:00
David Kohler
bf42f65b3d Merge pull request #93 from jwdeveloper/develop-1.8.4
Added User instance to LiveUserDataMapper Response to access the retrieved user
2024-07-27 19:18:58 -04:00
kohlerpop1
05e18ef8e0 Added User instance to LiveUserDataMapper Response to access the retrieved user. 2024-07-27 13:02:31 -04:00
GitHub Action
0f6ee58d7f Update version in pom.xml 2024-07-21 17:03:47 +00:00
14 changed files with 43 additions and 27 deletions

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>API</artifactId> <artifactId>API</artifactId>

View File

@@ -22,6 +22,7 @@
*/ */
package io.github.jwdeveloper.tiktok.data.requests; package io.github.jwdeveloper.tiktok.data.requests;
import io.github.jwdeveloper.tiktok.data.models.users.User;
import lombok.*; import lombok.*;
public class LiveUserData { public class LiveUserData {
@@ -44,6 +45,7 @@ public class LiveUserData {
private final UserStatus userStatus; private final UserStatus userStatus;
private final String roomId; private final String roomId;
private final long startTime; private final long startTime;
private final User user;
public boolean isLiveOnline() { public boolean isLiveOnline() {
return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused; return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused;

View File

@@ -82,9 +82,9 @@ public class LiveClientSettings {
/** /**
* Interval of time in milliseconds between pings to TikTok * Interval of time in milliseconds between pings to TikTok
* @apiNote Min: 250 (0.25 seconds), Default: 5000 (5 seconds) * @apiNote Min: 250 (0.25 seconds), Default: 10000 (10 seconds - TikTok Default)
*/ */
private long pingInterval = 5000; private long pingInterval = 10000;
/** Throw an exception on 18+ Age Restriction */ /** Throw an exception on 18+ Age Restriction */
private boolean throwOnAgeRestriction; private boolean throwOnAgeRestriction;

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -138,7 +138,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
//networking //networking
dependance.registerSingleton(HttpClientFactory.class); dependance.registerSingleton(HttpClientFactory.class);
dependance.registerSingleton(TikTokWebSocketPingingTask.class); dependance.registerSingleton(WebSocketHeartbeatTask.class);
if (clientSettings.isOffline()) { if (clientSettings.isOffline()) {
dependance.registerSingleton(LiveSocketClient.class, TikTokWebSocketOfflineClient.class); dependance.registerSingleton(LiveSocketClient.class, TikTokWebSocketOfflineClient.class);
dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpOfflineClient.class); dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpOfflineClient.class);

View File

@@ -47,7 +47,7 @@ public class TikTokLiveHttpOfflineClient implements LiveHttpClient {
@Override @Override
public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) { public LiveUserData.Response fetchLiveUserData(LiveUserData.Request request) {
return new LiveUserData.Response("", LiveUserData.UserStatus.Live, "offline_room_id", 0); return new LiveUserData.Response("", LiveUserData.UserStatus.Live, "offline_room_id", 0, null);
} }
@Override @Override

View File

@@ -23,9 +23,12 @@
package io.github.jwdeveloper.tiktok.http.mappers; package io.github.jwdeveloper.tiktok.http.mappers;
import com.google.gson.*; import com.google.gson.*;
import io.github.jwdeveloper.tiktok.data.models.Picture;
import io.github.jwdeveloper.tiktok.data.models.users.User;
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;
import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
public class LiveUserDataMapper public class LiveUserDataMapper
@@ -40,17 +43,18 @@ public class LiveUserDataMapper
throw new TikTokLiveRequestException("fetchRoomIdFromTiktokApi -> Unable to fetch roomID, contact the developer"); throw new TikTokLiveRequestException("fetchRoomIdFromTiktokApi -> Unable to fetch roomID, contact the developer");
} }
if (message.equals("user_not_found")) { if (message.equals("user_not_found")) {
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1); return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1, null);
} }
//live -> status 2 //live -> status 2
//live paused -> 3 //live paused -> 3
//not live -> status 4 //not live -> status 4
var element = jsonObject.get("data"); var element = jsonObject.get("data");
if (element.isJsonNull()) { if (element.isJsonNull()) {
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1); return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1, null);
} }
var data = element.getAsJsonObject(); var data = element.getAsJsonObject();
var user = data.getAsJsonObject("user"); var user = data.getAsJsonObject("user");
var stats = data.getAsJsonObject("stats");
var roomId = user.get("roomId").getAsString(); var roomId = user.get("roomId").getAsString();
var status = user.get("status").getAsInt(); var status = user.get("status").getAsInt();
@@ -64,10 +68,19 @@ public class LiveUserDataMapper
default -> LiveUserData.UserStatus.NotFound; default -> LiveUserData.UserStatus.NotFound;
}; };
return new LiveUserData.Response(json, statusEnum, roomId, startTime); User foundUser = new User(
Long.parseLong(user.get("id").getAsString()),
user.get("uniqueId").getAsString(),
user.get("nickname").getAsString(),
new Picture(user.get("avatarLarger").getAsString()),
stats.get("followingCount").getAsLong(),
stats.get("followerCount").getAsLong(),
List.of());
return new LiveUserData.Response(json, statusEnum, roomId, startTime, foundUser);
} catch (JsonSyntaxException | IllegalStateException e) { } catch (JsonSyntaxException | IllegalStateException e) {
logger.warning("Malformed Json: '"+json+"' - Error Message: "+e.getMessage()); logger.warning("Malformed Json: '"+json+"' - Error Message: "+e.getMessage());
return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1); return new LiveUserData.Response(json, LiveUserData.UserStatus.NotFound, "", -1, null);
} }
} }
} }

View File

@@ -40,7 +40,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
private final LiveClientSettings clientSettings; private final LiveClientSettings clientSettings;
private final LiveMessagesHandler messageHandler; private final LiveMessagesHandler messageHandler;
private final LiveEventsHandler tikTokEventHandler; private final LiveEventsHandler tikTokEventHandler;
private final TikTokWebSocketPingingTask pingingTask; private final WebSocketHeartbeatTask heartbeatTask;
private WebSocketClient webSocketClient; private WebSocketClient webSocketClient;
private boolean isConnected; private boolean isConnected;
@@ -48,12 +48,12 @@ public class TikTokWebSocketClient implements LiveSocketClient {
LiveClientSettings clientSettings, LiveClientSettings clientSettings,
LiveMessagesHandler messageHandler, LiveMessagesHandler messageHandler,
LiveEventsHandler tikTokEventHandler, LiveEventsHandler tikTokEventHandler,
TikTokWebSocketPingingTask pingingTask) WebSocketHeartbeatTask heartbeatTask)
{ {
this.clientSettings = clientSettings; this.clientSettings = clientSettings;
this.messageHandler = messageHandler; this.messageHandler = messageHandler;
this.tikTokEventHandler = tikTokEventHandler; this.tikTokEventHandler = tikTokEventHandler;
this.pingingTask = pingingTask; this.heartbeatTask = heartbeatTask;
isConnected = false; isConnected = false;
} }
@@ -84,7 +84,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
private void connectDefault() { private void connectDefault() {
try { try {
webSocketClient.connect(); webSocketClient.connect();
pingingTask.run(webSocketClient, clientSettings.getPingInterval()); heartbeatTask.run(webSocketClient, clientSettings.getPingInterval());
isConnected = true; isConnected = true;
} catch (Exception e) { } catch (Exception e) {
isConnected = false; isConnected = false;
@@ -120,7 +120,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
proxySettings.remove(); proxySettings.remove();
continue; continue;
} }
pingingTask.run(webSocketClient, clientSettings.getPingInterval()); heartbeatTask.run(webSocketClient, clientSettings.getPingInterval());
isConnected = true; isConnected = true;
break; break;
} }
@@ -141,7 +141,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
public void stop() { public void stop() {
if (isConnected && webSocketClient != null && webSocketClient.isOpen()) { if (isConnected && webSocketClient != null && webSocketClient.isOpen()) {
webSocketClient.closeConnection(0, ""); webSocketClient.closeConnection(0, "");
pingingTask.stop(); heartbeatTask.stop();
} }
webSocketClient = null; webSocketClient = null;
isConnected = false; isConnected = false;

View File

@@ -22,18 +22,19 @@
*/ */
package io.github.jwdeveloper.tiktok.websocket; package io.github.jwdeveloper.tiktok.websocket;
import io.github.jwdeveloper.tiktok.live.LiveEventsHandler;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
public class TikTokWebSocketPingingTask { public class WebSocketHeartbeatTask
{
private Thread thread; private Thread thread;
private boolean isRunning = false; private boolean isRunning = false;
private final int MAX_TIMEOUT = 250; private final int MAX_TIMEOUT = 250;
private final int SLEEP_TIME = 500; private final int SLEEP_TIME = 500;
private final byte[] heartbeatBytes = {58, 2, 104, 98}; // Byte Array of "3A026862" which is TikTok's custom heartbeat value
public void run(WebSocket webSocket, long pingTaskTime) { public void run(WebSocket webSocket, long pingTaskTime) {
stop(); stop();
thread = new Thread(() -> pingTask(webSocket, pingTaskTime), "pinging-task"); thread = new Thread(() -> heartbeatTask(webSocket, pingTaskTime), "heartbeat-task");
isRunning = true; isRunning = true;
thread.start(); thread.start();
} }
@@ -44,11 +45,11 @@ public class TikTokWebSocketPingingTask {
isRunning = false; isRunning = false;
} }
private void pingTask(WebSocket webSocket, long pingTaskTime) { private void heartbeatTask(WebSocket webSocket, long pingTaskTime) {
while (isRunning) { while (isRunning) {
try { try {
if (webSocket.isOpen()) { if (webSocket.isOpen()) {
webSocket.sendPing(); webSocket.send(heartbeatBytes);
Thread.sleep(pingTaskTime + (int) (Math.random() * MAX_TIMEOUT)); Thread.sleep(pingTaskTime + (int) (Math.random() * MAX_TIMEOUT));
} else } else
Thread.sleep(SLEEP_TIME); Thread.sleep(SLEEP_TIME);

View File

@@ -41,7 +41,7 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
@@ -33,7 +33,7 @@
<dependency> <dependency>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>API</artifactId> <artifactId>API</artifactId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>extension-recorder</artifactId> <artifactId>extension-recorder</artifactId>

View File

@@ -7,7 +7,7 @@
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
<modules> <modules>
<module>API</module> <module>API</module>
<module>Client</module> <module>Client</module>

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.8.2-Release</version> <version>1.8.4-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>