Compare commits

...

18 Commits

Author SHA1 Message Date
kohlerpop1
54b0216bf3 Downgrade junit jupiter to use Java 16 only! 2025-07-19 20:58:21 -04:00
David Kohler
4443fbe554 Add Paused state for live data due to false positive of returning HostNotFound when they were only paused! (#135)
* Add Paused state for live data due to false positive of returning HostNotFound when they were only paused!

* Fix accidental pom.xml comment!
2025-07-19 20:12:19 -04:00
GitHub Action
a6188d8bb0 Update version in pom.xml 2025-05-21 22:48:07 +00:00
David Kohler
81fd7dc85c Merge pull request #131 from jwdeveloper/develop-1.10.6
Add session id to websocket connection to get authenticated WS as well as optional customizable type for disconnecting websocket client in various ways.
2025-05-21 18:45:17 -04:00
kohlerpop1
7e59099793 Add session id to websocket connection to get authenticated WS as well as optional customizable type for disconnecting websocket client in various ways. 2025-05-21 18:43:14 -04:00
GitHub Action
dd2f311539 Update version in pom.xml 2025-05-19 18:47:52 +00:00
David Kohler
ba69f5f5eb Merge pull request #129 from jwdeveloper/develop-1.10.5
Add TikTok Target Identity Data Center cookie to make sessionid effective and verifiable.
2025-05-19 14:46:16 -04:00
kohlerpop1
e9a91f5741 Add TikTok Target Identity Data Center cookie to make sessionid effective and verifiable. 2025-05-19 14:40:41 -04:00
GitHub Action
053bb5e3dc Update version in pom.xml 2025-05-12 02:21:39 +00:00
David Kohler
906796dc23 Merge pull request #128 from jwdeveloper/develop-1.10.4
Fix throwing error bug when connecting using proxy!
2025-05-11 22:19:37 -04:00
kohlerpop1
162092c638 Fix throwing error bug when connecting using proxy! 2025-05-11 22:19:04 -04:00
GitHub Action
a72d134796 Update version in pom.xml 2025-05-11 02:09:04 +00:00
David Kohler
75f6368f2c Merge pull request #125 from jwdeveloper/develop-1.10.3
Change websocket connection logic!
2025-05-10 22:06:35 -04:00
kohlerpop1
b9eb0eba93 Removal of debug print statements! 2025-05-04 21:59:22 -04:00
GitHub Action
50d6d6e515 Update version in pom.xml 2025-04-25 21:00:20 +00:00
kohlerpop1
42f9fe360b Removal of debug print statements! 2025-04-25 16:58:24 -04:00
GitHub Action
dff226740c Update version in pom.xml 2025-04-25 19:42:02 +00:00
David Kohler
951d30e6a7 Merge pull request #124 from jwdeveloper/develop-1.10.1
Add additional helper methods back to TikTokLinkMicBattleEvent!
2025-04-25 15:40:08 -04:00
18 changed files with 78 additions and 53 deletions

View File

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

View File

@@ -51,7 +51,6 @@ public class TikTokLinkMicArmiesEvent extends TikTokHeaderEvent {
public TikTokLinkMicArmiesEvent(WebcastLinkMicArmies msg) {
super(msg.getCommon());
System.out.println(msg);
battleId = msg.getBattleId();
armies = new HashMap<>();
picture = Picture.map(msg.getGifIconImage());

View File

@@ -51,7 +51,6 @@ public class TikTokLinkMicBattleEvent extends TikTokHeaderEvent
public TikTokLinkMicBattleEvent(WebcastLinkMicBattle msg) {
super(msg.getCommon());
System.out.println(msg);
battleId = msg.getBattleId();
finished = msg.getAction() == BattleAction.BATTLE_ACTION_FINISH;
battleType = msg.getBattleSetting().getBattleType();

View File

@@ -52,6 +52,7 @@ public class LiveData {
public enum LiveStatus {
HostNotFound,
HostOnline,
HostPaused,
HostOffline,
}

View File

@@ -90,11 +90,18 @@ public class LiveClientSettings {
private boolean throwOnAgeRestriction;
/**
* Optional: Sometimes not every messages from chat are send to TikTokLiveJava to fix this issue you can set sessionId
* @see <a href="https://github.com/isaackogan/TikTok-Live-Connector#send-chat-messages">Documentation: How to obtain sessionId</a>
* Optional: Sometimes not every messages from chat are send to TikTokLiveJava to fix this issue you can set sessionId.
* <p>This requires {@link #ttTargetIdc} also being set correctly for sessionid to be effective.
* @apiNote This cookie is supplied by <a href="https://www.tiktok.com">TikTok</a> and can be found in your browser cookies.
*/
private String sessionId;
/**
* Used with {@link #sessionId} to verify it is valid and return extra chat messages and 18+ content.
* @apiNote This cookie is supplied by <a href="https://www.tiktok.com">TikTok</a> and can be found in your browser cookies.
*/
private String ttTargetIdc;
/**
* Optional: By default roomID is fetched before connect to live, but you can set it manually
*/

View File

@@ -51,9 +51,17 @@ public interface LiveClient {
/**
* Disconnects the connection.
* @param type
* <p>0 - Normal - Initiates disconnection and returns
* <p>1 - Disconnects blocking and returns after closure
* <p>2 - Disconnects and kills connection to websocket
* <p>Default {@link #disconnect()} is 0
*/
void disconnect();
void disconnect(int type);
default void disconnect() {
disconnect(0);
}
/**
* Use to manually invoke event

View File

@@ -27,5 +27,6 @@ import io.github.jwdeveloper.tiktok.live.LiveClient;
public interface LiveSocketClient {
void start(LiveConnectionData.Response webcastResponse, LiveClient tikTokLiveClient);
void stop();
}
void stop(int type);
boolean isConnected();
}

View File

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

View File

@@ -153,13 +153,12 @@ public class TikTokLiveClient implements LiveClient
tikTokEventHandler.publish(this, new TikTokRoomInfoEvent(roomInfo));
}
public void disconnect() {
if (roomInfo.hasConnectionState(ConnectionState.DISCONNECTED)) {
return;
}
setState(ConnectionState.DISCONNECTED);
webSocketClient.stop();
}
public void disconnect(int type) {
if (webSocketClient.isConnected())
webSocketClient.stop(type);
if (!roomInfo.hasConnectionState(ConnectionState.DISCONNECTED))
setState(ConnectionState.DISCONNECTED);
}
private void setState(ConnectionState connectionState) {
logger.info("TikTokLive client state: " + connectionState.name());
@@ -174,9 +173,9 @@ public class TikTokLiveClient implements LiveClient
public void publishMessage(String webcastMessageName, String payloadBase64) {
this.publishMessage(webcastMessageName, Base64.getDecoder().decode(payloadBase64));
}
@Override
public void publishMessage(String webcastMessageName, byte[] payload) {
var builder = ProtoMessageFetchResult.BaseProtoMessage.newBuilder();
builder.setMethod(webcastMessageName);
builder.setPayload(ByteString.copyFrom(payload));
@@ -184,7 +183,6 @@ public class TikTokLiveClient implements LiveClient
messageHandler.handleSingleMessage(this, message);
}
public void connectAsync(Consumer<LiveClient> onConnection) {
connectAsync().thenAccept(onConnection);
}

View File

@@ -113,6 +113,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
.withParam("uniqueId", request.getUserName())
.withParam("sourceType", "54") //MAGIC NUMBER, WHAT 54 means?
.withCookie("sessionid", clientSettings.getSessionId())
.withCookie("tt-target-idc", clientSettings.getTtTargetIdc())
.build()
.toJsonResponse();
@@ -141,6 +142,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
var result = httpFactory.client(url)
.withParam("room_id", request.getRoomId())
.withCookie("sessionid", clientSettings.getSessionId())
.withCookie("tt-target-idc", clientSettings.getTtTargetIdc())
.build()
.toJsonResponse();
@@ -197,6 +199,8 @@ public class TikTokLiveHttpClient implements LiveHttpClient
.withParam("client", "ttlive-java")
.withParam("room_id", room_id);
if (clientSettings.getSessionId() != null) // Allows receiving of all comments and Subscribe Events
builder.withParam("session_id", clientSettings.getSessionId());
if (clientSettings.getApiKey() != null)
builder.withParam("apiKey", clientSettings.getApiKey());

View File

@@ -61,6 +61,7 @@ public class LiveDataMapper {
var statusId = status.getAsInt();
var statusValue = switch (statusId) {
case 2 -> LiveData.LiveStatus.HostOnline;
case 3 -> LiveData.LiveStatus.HostPaused;
case 4 -> LiveData.LiveStatus.HostOffline;
default -> LiveData.LiveStatus.HostNotFound;
};

View File

@@ -26,10 +26,9 @@ import io.github.jwdeveloper.tiktok.data.dto.ProxyData;
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
import io.github.jwdeveloper.tiktok.data.settings.*;
import io.github.jwdeveloper.tiktok.exceptions.*;
import io.github.jwdeveloper.tiktok.live.LiveClient;
import io.github.jwdeveloper.tiktok.live.LiveEventsHandler;
import io.github.jwdeveloper.tiktok.live.LiveMessagesHandler;
import io.github.jwdeveloper.tiktok.live.*;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.framing.CloseFrame;
import javax.net.ssl.*;
import java.net.Proxy;
@@ -42,7 +41,6 @@ public class TikTokWebSocketClient implements LiveSocketClient {
private final LiveEventsHandler tikTokEventHandler;
private final WebSocketHeartbeatTask heartbeatTask;
private WebSocketClient webSocketClient;
private boolean isConnected;
public TikTokWebSocketClient(
LiveClientSettings clientSettings,
@@ -54,25 +52,23 @@ public class TikTokWebSocketClient implements LiveSocketClient {
this.messageHandler = messageHandler;
this.tikTokEventHandler = tikTokEventHandler;
this.heartbeatTask = heartbeatTask;
isConnected = false;
}
@Override
public void start(LiveConnectionData.Response connectionData, LiveClient liveClient) {
if (isConnected) {
stop();
}
if (isConnected())
stop(0);
messageHandler.handle(liveClient, connectionData.getWebcastResponse());
var headers = new HashMap<>(clientSettings.getHttpSettings().getHeaders());
headers.put("Cookie", connectionData.getWebsocketCookies());
webSocketClient = new TikTokWebSocketListener(connectionData.getWebsocketUrl(),
headers,
clientSettings.getHttpSettings().getTimeout().toMillisPart(),
messageHandler,
tikTokEventHandler,
liveClient);
headers,
clientSettings.getHttpSettings().getTimeout().toMillisPart(),
messageHandler,
tikTokEventHandler,
liveClient);
ProxyClientSettings proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
if (proxyClientSettings.isEnabled() && proxyClientSettings.isAllowWebsocket())
@@ -85,9 +81,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
try {
webSocketClient.connect();
heartbeatTask.run(webSocketClient, clientSettings.getPingInterval());
isConnected = true;
} catch (Exception e) {
isConnected = false;
throw new TikTokLiveException("Failed to connect to the websocket", e);
}
}
@@ -117,14 +111,12 @@ public class TikTokWebSocketClient implements LiveSocketClient {
ProxyData proxyData = proxySettings.next();
if (tryProxyConnection(proxySettings, proxyData)) {
heartbeatTask.run(webSocketClient, clientSettings.getPingInterval());
isConnected = true;
break;
return;
}
if (proxySettings.isAutoDiscard())
proxySettings.remove();
}
if (!isConnected)
throw new TikTokLiveException("Failed to connect to the websocket");
throw new TikTokLiveException("Failed to connect to the websocket");
}
public boolean tryProxyConnection(ProxyClientSettings proxySettings, ProxyData proxyData) {
@@ -137,12 +129,25 @@ public class TikTokWebSocketClient implements LiveSocketClient {
}
}
public void stop() {
if (isConnected && webSocketClient != null && webSocketClient.isOpen()) {
webSocketClient.closeConnection(0, "");
public void stop(int type) {
if (isConnected()) {
switch (type) {
case 1 -> {
try {
webSocketClient.closeBlocking();
} catch (InterruptedException e) {
throw new TikTokLiveException("Failed to stop the websocket");
}
}
case 2 -> webSocketClient.closeConnection(CloseFrame.NORMAL, "");
default -> webSocketClient.close();
}
heartbeatTask.stop();
}
webSocketClient = null;
isConnected = false;
}
public boolean isConnected() {
return webSocketClient != null && webSocketClient.isOpen();
}
}

View File

@@ -44,10 +44,13 @@ public class TikTokWebSocketOfflineClient implements LiveSocketClient {
}
@Override
public void stop() {
if (liveClient == null) {
return;
}
handler.publish(liveClient, new TikTokDisconnectedEvent("Stopping"));
public void stop(int type) {
if (liveClient != null)
handler.publish(liveClient, new TikTokDisconnectedEvent("Stopping"));
}
@Override
public boolean isConnected() {
return false;
}
}

View File

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

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>TikTokLiveJava</artifactId>
<version>1.10.0-Release</version>
<version>1.10.6-Release</version>
</parent>

View File

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

View File

@@ -7,7 +7,7 @@
<groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>TikTokLiveJava</artifactId>
<packaging>pom</packaging>
<version>1.10.0-Release</version>
<version>1.10.6-Release</version>
<modules>
<module>API</module>
<module>Client</module>
@@ -78,7 +78,6 @@
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -110,7 +109,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>

View File

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