mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 08:49:40 -05:00
Compare commits
8 Commits
1.10.6-Rel
...
1.10.9-Rel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92c9724108 | ||
|
|
f7bef6bb31 | ||
|
|
d8661fa2e3 | ||
|
|
fc02239d48 | ||
|
|
77eeedc15c | ||
|
|
54b0216bf3 | ||
|
|
4443fbe554 | ||
|
|
a6188d8bb0 |
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>API</artifactId>
|
<artifactId>API</artifactId>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package io.github.jwdeveloper.tiktok.data.events;
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.annotations.*;
|
||||||
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattleItemCard;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@EventMeta(eventType = EventType.Message)
|
||||||
|
public class TikTokLinkMicBattleItemCard extends TikTokHeaderEvent {
|
||||||
|
|
||||||
|
public TikTokLinkMicBattleItemCard(WebcastLinkMicBattleItemCard msg) {
|
||||||
|
super(msg.getCommon());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
package io.github.jwdeveloper.tiktok.data.models.battles;
|
package io.github.jwdeveloper.tiktok.data.models.battles;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
|
import io.github.jwdeveloper.tiktok.messages.data.BattleUserInfo;
|
||||||
import io.github.jwdeveloper.tiktok.messages.enums.BattleType;
|
import io.github.jwdeveloper.tiktok.messages.enums.BattleType;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicBattle;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -72,12 +73,12 @@ public class Team {
|
|||||||
this.hosts = List.copyOf(hosts);
|
this.hosts = List.copyOf(hosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Team(WebcastLinkMicBattle.BattleUserInfo anchorInfo) {
|
public Team(BattleUserInfo anchorInfo) {
|
||||||
this.hosts = List.of(new User(anchorInfo.getUser()));
|
this.hosts = List.of(new User(anchorInfo.getUser()));
|
||||||
this.teamId = hosts.get(0).getId();
|
this.teamId = hosts.get(0).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Team(WebcastLinkMicBattle.BattleUserInfo anchorInfo, WebcastLinkMicBattle.BattleComboInfo battleCombo) {
|
public Team(BattleUserInfo anchorInfo, WebcastLinkMicBattle.BattleComboInfo battleCombo) {
|
||||||
this(anchorInfo);
|
this(anchorInfo);
|
||||||
this.winStreak = (int) battleCombo.getComboCount();
|
this.winStreak = (int) battleCombo.getComboCount();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ package io.github.jwdeveloper.tiktok.data.models.users;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
import io.github.jwdeveloper.tiktok.data.models.Picture;
|
||||||
import io.github.jwdeveloper.tiktok.data.models.badges.Badge;
|
import io.github.jwdeveloper.tiktok.data.models.badges.Badge;
|
||||||
import io.github.jwdeveloper.tiktok.messages.data.BattleUserArmy;
|
import io.github.jwdeveloper.tiktok.messages.data.*;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
import io.github.jwdeveloper.tiktok.messages.webcast.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ public class User {
|
|||||||
this(id, name, profileId, null, picture, 0, 0, List.of(Badge.empty()));
|
this(id, name, profileId, null, picture, 0, 0, List.of(Badge.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public User(WebcastLinkMicBattle.BattleUserInfo.BattleBaseUserInfo host) {
|
public User(BattleUserInfo.BattleBaseUserInfo host) {
|
||||||
this(host.getUserId(), host.getDisplayId(), host.getNickName(), Picture.map(host.getAvatarThumb()));
|
this(host.getUserId(), host.getDisplayId(), host.getNickName(), Picture.map(host.getAvatarThumb()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class LiveData {
|
|||||||
public enum LiveStatus {
|
public enum LiveStatus {
|
||||||
HostNotFound,
|
HostNotFound,
|
||||||
HostOnline,
|
HostOnline,
|
||||||
|
HostPaused,
|
||||||
HostOffline,
|
HostOffline,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import io.github.jwdeveloper.tiktok.data.requests.GiftsData;
|
|||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveData;
|
import io.github.jwdeveloper.tiktok.data.requests.LiveData;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
import io.github.jwdeveloper.tiktok.data.requests.LiveUserData;
|
||||||
|
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||||
|
|
||||||
public interface LiveHttpClient
|
public interface LiveHttpClient
|
||||||
{
|
{
|
||||||
@@ -64,4 +65,6 @@ public interface LiveHttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request);
|
LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request);
|
||||||
|
|
||||||
|
boolean sendChat(LiveRoomInfo roomInfo, String content);
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,6 @@ public interface LiveClient {
|
|||||||
*/
|
*/
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects in asynchronous way
|
* Connects in asynchronous way
|
||||||
* When connected Consumer returns instance of LiveClient
|
* When connected Consumer returns instance of LiveClient
|
||||||
@@ -48,7 +47,6 @@ public interface LiveClient {
|
|||||||
*/
|
*/
|
||||||
CompletableFuture<LiveClient> connectAsync();
|
CompletableFuture<LiveClient> connectAsync();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects the connection.
|
* Disconnects the connection.
|
||||||
* @param type
|
* @param type
|
||||||
@@ -68,7 +66,6 @@ public interface LiveClient {
|
|||||||
*/
|
*/
|
||||||
void publishEvent(TikTokEvent event);
|
void publishEvent(TikTokEvent event);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param webcastMessageName name of TikTok protocol-buffer message
|
* @param webcastMessageName name of TikTok protocol-buffer message
|
||||||
* @param payloadBase64 protocol-buffer message bytes payload
|
* @param payloadBase64 protocol-buffer message bytes payload
|
||||||
@@ -96,4 +93,12 @@ public interface LiveClient {
|
|||||||
* Logger
|
* Logger
|
||||||
*/
|
*/
|
||||||
Logger getLogger();
|
Logger getLogger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a chat message to the connected room
|
||||||
|
* @return true if successful, otherwise false
|
||||||
|
* @apiNote This is known to return true on some sessionIds despite failing!
|
||||||
|
* <p>We cannot fix this as it is a TikTok issue, not a library issue.
|
||||||
|
*/
|
||||||
|
boolean sendChat(String content);
|
||||||
}
|
}
|
||||||
@@ -2121,6 +2121,24 @@ message PublicAreaMessageCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message BattleUserInfo {
|
||||||
|
BattleBaseUserInfo user = 1;
|
||||||
|
repeated BattleRivalTag tags = 2;
|
||||||
|
|
||||||
|
message BattleBaseUserInfo {
|
||||||
|
int64 user_id = 1;
|
||||||
|
string nick_name = 2;
|
||||||
|
Image avatar_thumb = 3;
|
||||||
|
string display_id = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BattleRivalTag {
|
||||||
|
Image bg_image = 1;
|
||||||
|
Image icon_image = 2;
|
||||||
|
string content = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message GiftModeMeta {
|
message GiftModeMeta {
|
||||||
int64 gift_id = 1;
|
int64 gift_id = 1;
|
||||||
string gift_name_key = 2;
|
string gift_name_key = 2;
|
||||||
|
|||||||
@@ -820,4 +820,19 @@ enum BattleType {
|
|||||||
enum BattleInviteType {
|
enum BattleInviteType {
|
||||||
BATTLE_INVITE_TYPE_NORMAL = 0;
|
BATTLE_INVITE_TYPE_NORMAL = 0;
|
||||||
BATTLE_INVITE_TYPE_AGAIN = 1;
|
BATTLE_INVITE_TYPE_AGAIN = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BattleCardMsgType {
|
||||||
|
BATTLE_CARD_MSG_TYPE_UNKNOWN_CARD_ACTION = 0;
|
||||||
|
BATTLE_CARD_MSG_TYPE_CARD_OBTAIN_GUIDE = 1;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_CRITICAL_STRIKE_CARD = 2;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_SMOKE_CARD = 3;
|
||||||
|
BATTLE_CARD_MSG_TYPE_AWARD_CARD_NOTICE = 4;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_EXTRA_TIME_CARD = 5;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_SPECIAL_EFFECT_CARD = 6;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_POTION_CARD = 7;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_WAVE_CARD = 8;
|
||||||
|
BATTLE_CARD_MSG_TYPE_SPECIAL_EFFECT_NOTICE = 9;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_TOP_2_CARD = 10;
|
||||||
|
BATTLE_CARD_MSG_TYPE_USE_TOP_3_CARD = 11;
|
||||||
}
|
}
|
||||||
@@ -1219,24 +1219,6 @@ message WebcastLinkMicBattle {
|
|||||||
// BattleUserInfo user_info = 2;
|
// BattleUserInfo user_info = 2;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
message BattleUserInfo {
|
|
||||||
BattleBaseUserInfo user = 1;
|
|
||||||
repeated BattleRivalTag tags = 2;
|
|
||||||
|
|
||||||
message BattleBaseUserInfo {
|
|
||||||
int64 user_id = 1;
|
|
||||||
string nick_name = 2;
|
|
||||||
Image avatar_thumb = 3;
|
|
||||||
string display_id = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BattleRivalTag {
|
|
||||||
Image bg_image = 1;
|
|
||||||
Image icon_image = 2;
|
|
||||||
string content = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message BattleABTestSetting {
|
message BattleABTestSetting {
|
||||||
int64 uid = 1;
|
int64 uid = 1;
|
||||||
BattleABTestList ab_test_list = 2;
|
BattleABTestList ab_test_list = 2;
|
||||||
@@ -1471,4 +1453,139 @@ message RoomVerifyMessage {
|
|||||||
string content = 3;
|
string content = 3;
|
||||||
int64 noticeType = 4;
|
int64 noticeType = 4;
|
||||||
bool closeRoom = 5;
|
bool closeRoom = 5;
|
||||||
|
}
|
||||||
|
message WebcastLinkMicBattleItemCard {
|
||||||
|
CommonMessageData common = 1;
|
||||||
|
int64 battle_id = 2;
|
||||||
|
BattleCardMsgType msg_type = 3;
|
||||||
|
CardObtainGuide card_obtain_guide = 4;
|
||||||
|
UseCriticalStrikeCard use_critical_strike_card = 5;
|
||||||
|
UseSmokeCard use_smoke_card = 6;
|
||||||
|
AwardCardNotice award_card_notice = 7;
|
||||||
|
UseExtraTimeCard use_extra_time_card = 8;
|
||||||
|
UseSpecialEffectCard use_special_effect_card = 9;
|
||||||
|
UsePotionCard use_potion_card = 10;
|
||||||
|
UseWaveCard use_wave_card = 11;
|
||||||
|
SpecialEffectNotice special_effect_notice = 12;
|
||||||
|
UseTop2Card use_top2_card = 13;
|
||||||
|
UseTop3Card use_top3_card = 14;
|
||||||
|
|
||||||
|
message CardObtainGuide {
|
||||||
|
int32 not_in_use = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseCriticalStrikeCard {
|
||||||
|
CriticalStrikeCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
|
||||||
|
message CriticalStrikeCardInfo {
|
||||||
|
string card_name_key = 1;
|
||||||
|
Image card_image = 2;
|
||||||
|
int64 send_time_sec = 3;
|
||||||
|
BattleUserInfo send_user = 4;
|
||||||
|
int64 effect_last_duration = 5;
|
||||||
|
int64 critical_strike_rate_low = 6;
|
||||||
|
int64 critical_strike_rate_high = 7;
|
||||||
|
int64 multiple = 8;
|
||||||
|
string gift_name_key = 9;
|
||||||
|
string rule_url = 10;
|
||||||
|
int64 effect_time_sec = 11;
|
||||||
|
int64 to_anchor_id = 12;
|
||||||
|
string to_anchor_id_str = 13;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseSmokeCard {
|
||||||
|
CommonCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AwardCardNotice {
|
||||||
|
Text display_content = 1;
|
||||||
|
repeated BattleUserInfo awarded_users = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseExtraTimeCard {
|
||||||
|
ExtraTimeCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
|
||||||
|
message ExtraTimeCardInfo {
|
||||||
|
string card_name_key = 1;
|
||||||
|
Image card_image = 2;
|
||||||
|
int64 send_time_sec = 3;
|
||||||
|
BattleUserInfo send_user = 4;
|
||||||
|
int64 effect_last_duration = 5;
|
||||||
|
string rule_url = 6;
|
||||||
|
int64 effect_time_sec = 7;
|
||||||
|
int64 to_anchor_id = 8;
|
||||||
|
int64 extra_duration_sec = 9;
|
||||||
|
string to_anchor_id_str = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseSpecialEffectCard {
|
||||||
|
CommonCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
repeated AnchorPair affected_anchor_pairs = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AnchorPair {
|
||||||
|
int64 source_anchor_id = 1;
|
||||||
|
int64 target_anchor_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UsePotionCard {
|
||||||
|
CommonCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseWaveCard {
|
||||||
|
CommonCardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CommonCardInfo {
|
||||||
|
string card_name_key = 1;
|
||||||
|
Image card_image = 2;
|
||||||
|
int64 send_time_sec = 3;
|
||||||
|
BattleUserInfo send_user = 4;
|
||||||
|
int64 effect_last_duration = 5;
|
||||||
|
string rule_url = 6;
|
||||||
|
int64 effect_time_sec = 7;
|
||||||
|
int64 to_anchor_id = 8;
|
||||||
|
string to_anchor_id_str = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SpecialEffectNotice {
|
||||||
|
int64 score = 1;
|
||||||
|
int64 from_user_id = 2;
|
||||||
|
int64 to_anchor_id = 3;
|
||||||
|
repeated AnchorPair affected_anchor_pairs = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseTop2Card {
|
||||||
|
Top2CardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
|
||||||
|
message Top2CardInfo {
|
||||||
|
CommonCardInfo common = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message UseTop3Card {
|
||||||
|
Top3CardInfo card_info = 1;
|
||||||
|
int64 anchor_id = 2;
|
||||||
|
Text display_content = 3;
|
||||||
|
|
||||||
|
message Top3CardInfo {
|
||||||
|
CommonCardInfo common = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,11 @@ public class TikTokLiveClient implements LiveClient
|
|||||||
messageHandler.handleSingleMessage(this, message);
|
messageHandler.handleSingleMessage(this, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendChat(String content) {
|
||||||
|
return httpClient.sendChat(roomInfo, content);
|
||||||
|
}
|
||||||
|
|
||||||
public void connectAsync(Consumer<LiveClient> onConnection) {
|
public void connectAsync(Consumer<LiveClient> onConnection) {
|
||||||
connectAsync().thenAccept(onConnection);
|
connectAsync().thenAccept(onConnection);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
|
|
||||||
//networking
|
//networking
|
||||||
dependance.registerSingleton(HttpClientFactory.class);
|
dependance.registerSingleton(HttpClientFactory.class);
|
||||||
dependance.registerSingleton(WebSocketHeartbeatTask.class);
|
dependance.registerSingleton(WebSocketHeartbeatTask.class); // True global singleton - Static objects are located to serve as global
|
||||||
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);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import io.github.jwdeveloper.dependance.injector.api.annotations.Inject;
|
import io.github.jwdeveloper.dependance.injector.api.annotations.Inject;
|
||||||
import io.github.jwdeveloper.tiktok.common.*;
|
import io.github.jwdeveloper.tiktok.common.*;
|
||||||
@@ -30,9 +31,10 @@ import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
|||||||
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.live.LiveRoomInfo;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult;
|
import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult;
|
||||||
|
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -42,9 +44,11 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
* <a href="https://github-wiki-see.page/m/isaackogan/TikTokLive/wiki/All-About-Signatures">Signing API by Isaac Kogan</a>
|
* <a href="https://github-wiki-see.page/m/isaackogan/TikTokLive/wiki/All-About-Signatures">Signing API by Isaac Kogan</a>
|
||||||
*/
|
*/
|
||||||
private static final String TIKTOK_SIGN_API = "https://tiktok.eulerstream.com/webcast/fetch";
|
private static final String TIKTOK_SIGN_API = "https://tiktok.eulerstream.com/webcast/fetch";
|
||||||
|
private static final String TIKTOK_CHAT_URL = "https://tiktok.eulerstream.com/webcast/chat";
|
||||||
private static final String TIKTOK_URL_WEB = "https://www.tiktok.com/";
|
private static final String TIKTOK_URL_WEB = "https://www.tiktok.com/";
|
||||||
private static final String TIKTOK_URL_WEBCAST = "https://webcast.tiktok.com/webcast/";
|
private static final String TIKTOK_URL_WEBCAST = "https://webcast.tiktok.com/webcast/";
|
||||||
public static final String TIKTOK_ROOM_GIFTS_URL = TIKTOK_URL_WEBCAST+"gift/list/";
|
private static final String TIKTOK_ROOM_GIFTS_URL = TIKTOK_URL_WEBCAST+"gift/list/";
|
||||||
|
private static final String TIKTOK_ROOM_INFO_URL = TIKTOK_URL_WEBCAST + "room/info";
|
||||||
public static final int TIKTOK_AGE_RESTRICTED_CODE = 4003110;
|
public static final int TIKTOK_AGE_RESTRICTED_CODE = 4003110;
|
||||||
|
|
||||||
private final HttpClientFactory httpFactory;
|
private final HttpClientFactory httpFactory;
|
||||||
@@ -138,8 +142,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LiveData.Response getLiveData(LiveData.Request request) {
|
public LiveData.Response getLiveData(LiveData.Request request) {
|
||||||
var url = TIKTOK_URL_WEBCAST + "room/info";
|
var result = httpFactory.client(TIKTOK_ROOM_INFO_URL)
|
||||||
var result = httpFactory.client(url)
|
|
||||||
.withParam("room_id", request.getRoomId())
|
.withParam("room_id", request.getRoomId())
|
||||||
.withCookie("sessionid", clientSettings.getSessionId())
|
.withCookie("sessionid", clientSettings.getSessionId())
|
||||||
.withCookie("tt-target-idc", clientSettings.getTtTargetIdc())
|
.withCookie("tt-target-idc", clientSettings.getTtTargetIdc())
|
||||||
@@ -182,6 +185,35 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendChat(LiveRoomInfo roomInfo, String content) {
|
||||||
|
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
|
||||||
|
if (proxyClientSettings.isEnabled()) {
|
||||||
|
while (proxyClientSettings.hasNext()) {
|
||||||
|
try {
|
||||||
|
return requestSendChat(roomInfo, content);
|
||||||
|
} catch (TikTokProxyRequestException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requestSendChat(roomInfo, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean requestSendChat(LiveRoomInfo roomInfo, String content) {
|
||||||
|
JsonObject body = new JsonObject();
|
||||||
|
body.addProperty("content", content);
|
||||||
|
body.addProperty("sessionId", clientSettings.getSessionId());
|
||||||
|
body.addProperty("ttTargetIdc", clientSettings.getTtTargetIdc());
|
||||||
|
body.addProperty("roomId", roomInfo.getRoomId());
|
||||||
|
if (clientSettings.getApiKey() != null)
|
||||||
|
body.addProperty("apiKey", clientSettings.getApiKey());
|
||||||
|
var result = httpFactory.client(TIKTOK_CHAT_URL)
|
||||||
|
.withHeader("Content-Type", "application/json")
|
||||||
|
.withBody(HttpRequest.BodyPublishers.ofString(body.toString()))
|
||||||
|
.build()
|
||||||
|
.toJsonResponse();
|
||||||
|
return result.isSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
protected ActionResult<HttpResponse<byte[]>> getStartingPayload(LiveConnectionData.Request request) {
|
protected ActionResult<HttpResponse<byte[]>> getStartingPayload(LiveConnectionData.Request request) {
|
||||||
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
|
var proxyClientSettings = clientSettings.getHttpSettings().getProxyClientSettings();
|
||||||
if (proxyClientSettings.isEnabled()) {
|
if (proxyClientSettings.isEnabled()) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import io.github.jwdeveloper.tiktok.data.models.Picture;
|
|||||||
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
import io.github.jwdeveloper.tiktok.data.models.users.User;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.*;
|
import io.github.jwdeveloper.tiktok.data.requests.*;
|
||||||
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
||||||
|
import io.github.jwdeveloper.tiktok.live.LiveRoomInfo;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult;
|
import io.github.jwdeveloper.tiktok.messages.webcast.ProtoMessageFetchResult;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@@ -45,20 +46,26 @@ public class TikTokLiveHttpOfflineClient implements LiveHttpClient {
|
|||||||
@Override
|
@Override
|
||||||
public LiveData.Response fetchLiveData(LiveData.Request request) {
|
public LiveData.Response fetchLiveData(LiveData.Request request) {
|
||||||
return new LiveData.Response("",
|
return new LiveData.Response("",
|
||||||
LiveData.LiveStatus.HostOnline,
|
LiveData.LiveStatus.HostOnline,
|
||||||
"offline live",
|
"offline live",
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
new User(0L, "offline user", new Picture("")),
|
new User(0L, "offline user", new Picture("")),
|
||||||
LiveData.LiveType.SOLO);
|
LiveData.LiveType.SOLO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request) {
|
public LiveConnectionData.Response fetchLiveConnectionData(LiveConnectionData.Request request) {
|
||||||
return new LiveConnectionData.Response("",
|
return new LiveConnectionData.Response("",
|
||||||
URI.create("https://example.live"),
|
URI.create("https://example.live"),
|
||||||
ProtoMessageFetchResult.newBuilder().build());
|
ProtoMessageFetchResult.newBuilder().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendChat(LiveRoomInfo roomInfo, String content) {
|
||||||
|
// DO NOTHING
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,11 +40,12 @@ public class HttpClient {
|
|||||||
|
|
||||||
protected final HttpClientSettings httpClientSettings;
|
protected final HttpClientSettings httpClientSettings;
|
||||||
protected final String url;
|
protected final String url;
|
||||||
|
protected final HttpRequest.BodyPublisher bodyPublisher;
|
||||||
private final Pattern pattern = Pattern.compile("charset=(.*?)(?=&|$)");
|
private final Pattern pattern = Pattern.compile("charset=(.*?)(?=&|$)");
|
||||||
|
|
||||||
public <T> ActionResult<HttpResponse<T>> toHttpResponse(HttpResponse.BodyHandler<T> handler) {
|
public <T> ActionResult<HttpResponse<T>> toHttpResponse(HttpResponse.BodyHandler<T> handler) {
|
||||||
var client = prepareClient();
|
var client = prepareClient();
|
||||||
var request = prepareGetRequest();
|
var request = prepareRequest();
|
||||||
try {
|
try {
|
||||||
var response = client.send(request, handler);
|
var response = client.send(request, handler);
|
||||||
var result = ActionResult.of(response);
|
var result = ActionResult.of(response);
|
||||||
@@ -99,8 +100,13 @@ public class HttpClient {
|
|||||||
return URI.create(stringUrl);
|
return URI.create(stringUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpRequest prepareGetRequest() {
|
/**
|
||||||
var requestBuilder = HttpRequest.newBuilder().GET();
|
* @return {@link HttpRequest} with default GET, otherwise POST if {@link #bodyPublisher} is not null
|
||||||
|
*/
|
||||||
|
protected HttpRequest prepareRequest() {
|
||||||
|
var requestBuilder = HttpRequest.newBuilder();
|
||||||
|
if (bodyPublisher != null)
|
||||||
|
requestBuilder.POST(bodyPublisher);
|
||||||
requestBuilder.uri(toUri());
|
requestBuilder.uri(toUri());
|
||||||
requestBuilder.timeout(httpClientSettings.getTimeout());
|
requestBuilder.timeout(httpClientSettings.getTimeout());
|
||||||
if (!httpClientSettings.getCookies().isEmpty()) {
|
if (!httpClientSettings.getCookies().isEmpty()) {
|
||||||
@@ -124,12 +130,10 @@ public class HttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String prepareUrlWithParameters(String url, Map<String, Object> parameters) {
|
protected String prepareUrlWithParameters(String url, Map<String, Object> parameters) {
|
||||||
if (parameters.isEmpty()) {
|
if (parameters.isEmpty())
|
||||||
return url;
|
return url;
|
||||||
}
|
|
||||||
|
|
||||||
return url + "?" + parameters.entrySet().stream().map(entry ->
|
return url + "?" + parameters.entrySet().stream().map(entry -> {
|
||||||
{
|
|
||||||
var encodedKey = URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8);
|
var encodedKey = URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8);
|
||||||
var encodedValue = URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8);
|
var encodedValue = URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8);
|
||||||
return encodedKey + "=" + encodedValue;
|
return encodedKey + "=" + encodedValue;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ package io.github.jwdeveloper.tiktok.http;
|
|||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.HttpClientSettings;
|
import io.github.jwdeveloper.tiktok.data.settings.HttpClientSettings;
|
||||||
|
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ public class HttpClientBuilder {
|
|||||||
|
|
||||||
private final HttpClientSettings httpClientSettings;
|
private final HttpClientSettings httpClientSettings;
|
||||||
private String url;
|
private String url;
|
||||||
|
private HttpRequest.BodyPublisher bodyPublisher;
|
||||||
|
|
||||||
public HttpClientBuilder(String url, HttpClientSettings httpClientSettings) {
|
public HttpClientBuilder(String url, HttpClientSettings httpClientSettings) {
|
||||||
this.httpClientSettings = httpClientSettings;
|
this.httpClientSettings = httpClientSettings;
|
||||||
@@ -78,10 +80,15 @@ public class HttpClientBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpClientBuilder withBody(HttpRequest.BodyPublisher bodyPublisher) {
|
||||||
|
this.bodyPublisher = bodyPublisher;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public HttpClient build() {
|
public HttpClient build() {
|
||||||
var proxyClientSettings = httpClientSettings.getProxyClientSettings();
|
var proxyClientSettings = httpClientSettings.getProxyClientSettings();
|
||||||
if (proxyClientSettings.isEnabled() && proxyClientSettings.hasNext())
|
if (proxyClientSettings.isEnabled() && proxyClientSettings.hasNext())
|
||||||
return new HttpProxyClient(httpClientSettings, url);
|
return new HttpProxyClient(httpClientSettings, url, bodyPublisher);
|
||||||
return new HttpClient(httpClientSettings, url);
|
return new HttpClient(httpClientSettings, url, bodyPublisher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,8 +40,8 @@ public class HttpProxyClient extends HttpClient {
|
|||||||
|
|
||||||
private final ProxyClientSettings proxySettings;
|
private final ProxyClientSettings proxySettings;
|
||||||
|
|
||||||
public HttpProxyClient(HttpClientSettings httpClientSettings, String url) {
|
public HttpProxyClient(HttpClientSettings httpClientSettings, String url, HttpRequest.BodyPublisher bodyPublisher) {
|
||||||
super(httpClientSettings, url);
|
super(httpClientSettings, url, bodyPublisher);
|
||||||
this.proxySettings = httpClientSettings.getProxyClientSettings();
|
this.proxySettings = httpClientSettings.getProxyClientSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class HttpProxyClient extends HttpClient {
|
|||||||
|
|
||||||
httpClientSettings.getOnClientCreating().accept(builder);
|
httpClientSettings.getOnClientCreating().accept(builder);
|
||||||
var client = builder.build();
|
var client = builder.build();
|
||||||
var request = prepareGetRequest();
|
var request = prepareRequest();
|
||||||
|
|
||||||
var response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
|
var response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
|
||||||
if (response.statusCode() != 200)
|
if (response.statusCode() != 200)
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public class LiveDataMapper {
|
|||||||
var statusId = status.getAsInt();
|
var statusId = status.getAsInt();
|
||||||
var statusValue = switch (statusId) {
|
var statusValue = switch (statusId) {
|
||||||
case 2 -> LiveData.LiveStatus.HostOnline;
|
case 2 -> LiveData.LiveStatus.HostOnline;
|
||||||
|
case 3 -> LiveData.LiveStatus.HostPaused;
|
||||||
case 4 -> LiveData.LiveStatus.HostOffline;
|
case 4 -> LiveData.LiveStatus.HostOffline;
|
||||||
default -> LiveData.LiveStatus.HostNotFound;
|
default -> LiveData.LiveStatus.HostNotFound;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class MessagesMapperFactory {
|
|||||||
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicArmies.class);
|
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicArmies.class);
|
||||||
return MappingResult.of(message, new TikTokLinkMicArmiesEvent(message));
|
return MappingResult.of(message, new TikTokLinkMicArmiesEvent(message));
|
||||||
});
|
});
|
||||||
mapper.forMessage(WebcastLinkMessage.class, ((inputBytes, messageName, mapperHelper) -> {
|
mapper.forMessage(WebcastLinkMessage.class, (inputBytes, messageName, mapperHelper) -> {
|
||||||
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMessage.class);
|
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMessage.class);
|
||||||
return MappingResult.of(message, switch (message.getMessageType()) {
|
return MappingResult.of(message, switch (message.getMessageType()) {
|
||||||
case TYPE_LINKER_INVITE -> new TikTokLinkInviteEvent(message);
|
case TYPE_LINKER_INVITE -> new TikTokLinkInviteEvent(message);
|
||||||
@@ -116,8 +116,7 @@ public class MessagesMapperFactory {
|
|||||||
case TYPE_LINKER_KICK_OUT -> new TikTokLinkKickOutEvent(message);
|
case TYPE_LINKER_KICK_OUT -> new TikTokLinkKickOutEvent(message);
|
||||||
case TYPE_LINKER_LINKED_LIST_CHANGE -> new TikTokLinkLinkedListChangeEvent(message);
|
case TYPE_LINKER_LINKED_LIST_CHANGE -> new TikTokLinkLinkedListChangeEvent(message);
|
||||||
case TYPE_LINKER_UPDATE_USER -> new TikTokLinkUpdateUserEvent(message);
|
case TYPE_LINKER_UPDATE_USER -> new TikTokLinkUpdateUserEvent(message);
|
||||||
case TYPE_LINKER_WAITING_LIST_CHANGE, TYPE_LINKER_WAITING_LIST_CHANGE_V2 ->
|
case TYPE_LINKER_WAITING_LIST_CHANGE, TYPE_LINKER_WAITING_LIST_CHANGE_V2 -> new TikTokLinkWaitListChangeEvent(message);
|
||||||
new TikTokLinkWaitListChangeEvent(message);
|
|
||||||
case TYPE_LINKER_MUTE -> new TikTokLinkMuteEvent(message);
|
case TYPE_LINKER_MUTE -> new TikTokLinkMuteEvent(message);
|
||||||
case TYPE_LINKER_MATCH -> new TikTokLinkRandomMatchEvent(message);
|
case TYPE_LINKER_MATCH -> new TikTokLinkRandomMatchEvent(message);
|
||||||
case TYPE_LINKER_UPDATE_USER_SETTING -> new TikTokLinkUpdateUserSettingEvent(message);
|
case TYPE_LINKER_UPDATE_USER_SETTING -> new TikTokLinkUpdateUserSettingEvent(message);
|
||||||
@@ -130,7 +129,11 @@ public class MessagesMapperFactory {
|
|||||||
case TYPE_LINKMIC_USER_TOAST -> new TikTokLinkUserToastEvent(message);
|
case TYPE_LINKMIC_USER_TOAST -> new TikTokLinkUserToastEvent(message);
|
||||||
default -> new TikTokLinkEvent(message);
|
default -> new TikTokLinkEvent(message);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
|
mapper.forMessage(WebcastLinkMicBattleItemCard.class, (inputBytes, messageName, mapperHelper) -> {
|
||||||
|
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicBattleItemCard.class);
|
||||||
|
return MappingResult.of(message, new TikTokLinkMicBattleItemCard(message));
|
||||||
|
});
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
|
||||||
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
|
||||||
|
|
||||||
@@ -149,4 +152,4 @@ public class MessagesMapperFactory {
|
|||||||
// mapper.bytesToEvents(WebcastEnvelopeMessage.class, commonHandler::handleEnvelop);
|
// mapper.bytesToEvents(WebcastEnvelopeMessage.class, commonHandler::handleEnvelop);
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ public class TikTokWebSocketClient implements LiveSocketClient {
|
|||||||
case 2 -> webSocketClient.closeConnection(CloseFrame.NORMAL, "");
|
case 2 -> webSocketClient.closeConnection(CloseFrame.NORMAL, "");
|
||||||
default -> webSocketClient.close();
|
default -> webSocketClient.close();
|
||||||
}
|
}
|
||||||
heartbeatTask.stop();
|
heartbeatTask.stop(webSocketClient);
|
||||||
}
|
}
|
||||||
webSocketClient = null;
|
webSocketClient = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,41 +24,52 @@ package io.github.jwdeveloper.tiktok.websocket;
|
|||||||
|
|
||||||
import org.java_websocket.WebSocket;
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
import java.util.Base64;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class WebSocketHeartbeatTask
|
public class WebSocketHeartbeatTask
|
||||||
{
|
{
|
||||||
private Thread thread;
|
// Single shared pool for all heartbeat tasks
|
||||||
private boolean isRunning = false;
|
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, r -> {
|
||||||
private final int MAX_TIMEOUT = 250;
|
Thread t = new Thread(r, "heartbeat-pool");
|
||||||
private final int SLEEP_TIME = 500;
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
private static final Map<WebSocket, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>();
|
||||||
|
private static final Map<WebSocket, Long> commTime = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final byte[] heartbeatBytes = Base64.getDecoder().decode("MgJwYjoCaGI="); // Used to be '3A026862' aka ':\x02hb', now is '2\x02pb:\x02hb'.
|
private final byte[] heartbeatBytes = Base64.getDecoder().decode("MgJwYjoCaGI="); // Used to be '3A026862' aka ':\x02hb', now is '2\x02pb:\x02hb'.
|
||||||
|
|
||||||
public void run(WebSocket webSocket, long pingTaskTime) {
|
public void run(WebSocket webSocket, long pingTaskTime) {
|
||||||
stop();
|
stop(webSocket); // remove existing task if any
|
||||||
thread = new Thread(() -> heartbeatTask(webSocket, pingTaskTime), "heartbeat-task");
|
|
||||||
isRunning = true;
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
tasks.put(webSocket, scheduler.scheduleAtFixedRate(() -> {
|
||||||
if (thread != null)
|
|
||||||
thread.interrupt();
|
|
||||||
isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void heartbeatTask(WebSocket webSocket, long pingTaskTime) {
|
|
||||||
while (isRunning) {
|
|
||||||
try {
|
try {
|
||||||
if (webSocket.isOpen()) {
|
if (webSocket.isOpen()) {
|
||||||
webSocket.send(heartbeatBytes);
|
webSocket.send(heartbeatBytes);
|
||||||
Thread.sleep(pingTaskTime + (int) (Math.random() * MAX_TIMEOUT));
|
commTime.put(webSocket, System.currentTimeMillis());
|
||||||
} else
|
} else {
|
||||||
Thread.sleep(SLEEP_TIME);
|
Long time = commTime.get(webSocket);
|
||||||
|
if (time != null && System.currentTimeMillis() - time >= 60_000) // Stop if disconnected longer than 60s
|
||||||
|
stop(webSocket);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//TODO we should display some kind of error message
|
e.printStackTrace();
|
||||||
isRunning = false;
|
stop(webSocket);
|
||||||
}
|
}
|
||||||
}
|
}, 0, pingTaskTime, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(WebSocket webSocket) {
|
||||||
|
ScheduledFuture<?> future = tasks.remove(webSocket);
|
||||||
|
if (future != null)
|
||||||
|
future.cancel(true);
|
||||||
|
commTime.remove(webSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
tasks.values().forEach(f -> f.cancel(true));
|
||||||
|
commTime.clear();
|
||||||
|
scheduler.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|||||||
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>extension-recorder</artifactId>
|
<artifactId>extension-recorder</artifactId>
|
||||||
|
|||||||
5
pom.xml
5
pom.xml
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>API</module>
|
<module>API</module>
|
||||||
<module>Client</module>
|
<module>Client</module>
|
||||||
@@ -78,7 +78,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@@ -110,7 +109,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>RELEASE</version>
|
<version>5.9.3</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -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.10.5-Release</version>
|
<version>1.10.8-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user