From 9f4c1c8c92d795a947bc2a816e801203030fbfde Mon Sep 17 00:00:00 2001 From: JW Date: Thu, 5 Oct 2023 16:52:05 +0200 Subject: [PATCH] Breaking changes: 'Gift': changed from class to enum, so now you can handle incoming gifts in switch `Events` - new: onGiftComboFinished - Removed: onGiftBrodcast - Rename: onGiftMessage -> onGift onRoomPinMessage -> onRoomPin onRoomMessage -> onRoom onLinkMessage -> onLink onBarrageMessage -> onBarrage onPollMessage -> onPoll onShopMessage -> onShop onDetectMessage -> onDetect `GiftManager` added: registerGift findById findByName getGifts removed: getActiveGifts --- .../tiktok/events/TikTokEventBuilder.java | 6 +- .../events/messages/TikTokBarrageEvent.java | 13 +---- .../events/messages/TikTokCaptionEvent.java | 2 +- .../events/messages/TikTokIMDeleteEvent.java | 6 +- .../messages/TikTokLinkMicFanTicketEvent.java | 1 - .../events/messages/TikTokQuestionEvent.java | 11 +--- .../events/messages/TikTokShopEvent.java | 1 + .../events/messages/gift/TikTokGiftEvent.java | 6 +- .../messages/{ => room}/TikTokRoomEvent.java | 2 +- .../{ => room}/TikTokRoomPinEvent.java | 3 +- .../{ => room}/TikTokRoomUserInfoEvent.java | 2 +- .../tiktok/events/objects/Emote.java | 3 +- .../tiktok/events/objects/Text.java | 20 +++++-- .../events/objects/barrage/BarrageParam.java | 14 ++++- .../tiktok/handler/TikTokMessageHandler.java | 2 +- API/src/main/proto/webcast.proto | 14 ++++- .../tiktok/TikTokLiveClientBuilder.java | 3 + .../tiktok/handlers/TikTokMessageHandler.java | 21 +++++-- .../TikTokMessageHandlerRegistration.java | 31 ++++++----- .../websocket/TikTokWebSocketListener.java | 11 +++- .../websocket/TikTokWebSocketPingingTask.java | 3 + .../io/github/jwdeveloper/tiktok/Main.java | 9 +-- .../tiktok/tools/collector/RunCollector.java | 2 +- .../tiktok/tools/tester/RunLogTester.java | 55 +++++++++++++++++-- .../mockClient/mocks/LiveClientMock.java | 7 +++ .../mockClient/mocks/WebsocketClientMock.java | 41 +++++++++----- 26 files changed, 200 insertions(+), 89 deletions(-) rename API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/{ => room}/TikTokRoomEvent.java (97%) rename API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/{ => room}/TikTokRoomPinEvent.java (93%) rename API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/{ => room}/TikTokRoomUserInfoEvent.java (97%) diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/TikTokEventBuilder.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/TikTokEventBuilder.java index 1aeeb85..9cab065 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/TikTokEventBuilder.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/TikTokEventBuilder.java @@ -25,6 +25,8 @@ package io.github.jwdeveloper.tiktok.events; import io.github.jwdeveloper.tiktok.events.messages.*; import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftComboFinishedEvent; import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent; @@ -54,6 +56,7 @@ public interface TikTokEventBuilder { T onGift(TikTokEventConsumer event); + T onQuestion(TikTokEventConsumer event); T onSubscribe(TikTokEventConsumer event); @@ -80,7 +83,6 @@ public interface TikTokEventBuilder { T onDisconnected(TikTokEventConsumer event); - T onError(TikTokEventConsumer event); T onEvent(TikTokEventConsumer event); @@ -99,7 +101,7 @@ public interface TikTokEventBuilder { //T onCaption(TikTokEventConsumer event); - //T onQuestion(TikTokEventConsumer event); + //T onRoomPin(TikTokEventConsumer event); diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokBarrageEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokBarrageEvent.java index 7ad1e2d..72da4a7 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokBarrageEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokBarrageEvent.java @@ -41,6 +41,7 @@ public class TikTokBarrageEvent extends TikTokHeaderEvent { private final Picture rightIcon; private final String eventName; private final int duration; + private BarrageParam barrageParam; public TikTokBarrageEvent(WebcastBarrageMessage msg) { @@ -50,15 +51,7 @@ public class TikTokBarrageEvent extends TikTokHeaderEvent { backGround = Picture.map(msg.getBackground()); rightIcon = Picture.map(msg.getRightIcon()); duration = msg.getDuration(); - switch (msg.getMsgType()) { - case GRADEUSERENTRANCENOTIFICATION: - barrageParam = new UserGradeParam(msg.getUserGradeParam()); - case FANSLEVELUPGRADE: - barrageParam = new FansLevelParam(msg.getFansLevelParam()); - case SUBSCRIBEGIFT: - barrageParam = new SubscribeGiftParam(msg.getSubscribeGiftParam()); - default: - barrageParam = new BarrageParam(); - } + barrageParam = BarrageParam.map(msg); + } } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokCaptionEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokCaptionEvent.java index 9e5d617..e407b6b 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokCaptionEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokCaptionEvent.java @@ -38,7 +38,7 @@ public class TikTokCaptionEvent extends TikTokHeaderEvent { String text; public TikTokCaptionEvent(WebcastCaptionMessage msg) { - super(msg.getCommon()); + super(msg.getCommon()); captionTimeStamp = msg.getTimeStamp(); iSOLanguage = msg.getCaptionData().getLanguage(); text = msg.getCaptionData().getText(); diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokIMDeleteEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokIMDeleteEvent.java index 15cec29..0366454 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokIMDeleteEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokIMDeleteEvent.java @@ -28,11 +28,15 @@ import io.github.jwdeveloper.tiktok.events.base.TikTokHeaderEvent; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastImDeleteMessage; import lombok.Getter; +import java.util.List; + @Getter @EventMeta(eventType = EventType.Message) public class TikTokIMDeleteEvent extends TikTokHeaderEvent { + List userIds; public TikTokIMDeleteEvent(WebcastImDeleteMessage msg) { - super(msg.getHeader()); + super(msg.getCommon()); + this.userIds = msg.getDeleteUserIdsListList(); } } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokLinkMicFanTicketEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokLinkMicFanTicketEvent.java index a626051..d0b9b19 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokLinkMicFanTicketEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokLinkMicFanTicketEvent.java @@ -32,7 +32,6 @@ import lombok.Getter; @EventMeta(eventType = EventType.Message) public class TikTokLinkMicFanTicketEvent extends TikTokHeaderEvent { - public TikTokLinkMicFanTicketEvent(WebcastLinkMicFanTicketMethod msg) { super(msg.getCommon()); } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokQuestionEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokQuestionEvent.java index 7113726..173cc77 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokQuestionEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokQuestionEvent.java @@ -36,22 +36,15 @@ Triggered every time someone asks a new question via the question feature. @EventMeta(eventType = EventType.Message) public class TikTokQuestionEvent extends TikTokHeaderEvent { private final Long questionId; - private final String text; - private final Long time; - - private User user; - - + private final User user; public TikTokQuestionEvent(WebcastQuestionNewMessage msg) { super(msg.getCommon()); var data = msg.getDetails(); questionId = data.getId(); text = data.getText(); time = data.getTimeStamp(); - if (data.hasUser()) { - user = new User(data.getUser()); - } + user = User.map(data.getUser()); } } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokShopEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokShopEvent.java index 113fb5f..551c9ed 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokShopEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokShopEvent.java @@ -42,6 +42,7 @@ public class TikTokShopEvent extends TikTokHeaderEvent { private final String shopName; + //Not working public TikTokShopEvent(WebcastOecLiveShoppingMessage msg) { super(msg.getCommon()); var data = msg.getShopData(); diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/gift/TikTokGiftEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/gift/TikTokGiftEvent.java index d65de3c..7e0d38a 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/gift/TikTokGiftEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/gift/TikTokGiftEvent.java @@ -40,8 +40,6 @@ import lombok.Getter; public class TikTokGiftEvent extends TikTokHeaderEvent { private final Gift gift; private final User user; - private final String purchaseId; - private final String receipt; private final int combo; private final boolean comboFinished; private final int comboIndex; @@ -49,9 +47,7 @@ public class TikTokGiftEvent extends TikTokHeaderEvent { public TikTokGiftEvent(Gift gift, WebcastGiftMessage msg) { super(msg.getCommon()); this.gift = gift; - user = User.map(msg.getUser()); - purchaseId = msg.getOrderId(); - receipt = msg.getMonitorExtra(); + user = User.map(msg.getUser(),msg.getUserIdentity()); combo = msg.getComboCount(); comboFinished = msg.getRepeatEnd() > 0; comboIndex = msg.getRepeatCount(); diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomEvent.java similarity index 97% rename from API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomEvent.java rename to API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomEvent.java index 56dddde..35edad7 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomEvent.java @@ -20,7 +20,7 @@ * 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.events.messages; +package io.github.jwdeveloper.tiktok.events.messages.room; import io.github.jwdeveloper.tiktok.annotations.EventMeta; import io.github.jwdeveloper.tiktok.annotations.EventType; diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomPinEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomPinEvent.java similarity index 93% rename from API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomPinEvent.java rename to API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomPinEvent.java index 1af004e..7034408 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomPinEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomPinEvent.java @@ -20,11 +20,12 @@ * 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.events.messages; +package io.github.jwdeveloper.tiktok.events.messages.room; import io.github.jwdeveloper.tiktok.annotations.EventMeta; import io.github.jwdeveloper.tiktok.annotations.EventType; import io.github.jwdeveloper.tiktok.events.base.TikTokHeaderEvent; +import io.github.jwdeveloper.tiktok.events.messages.TikTokCommentEvent; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastRoomPinMessage; import lombok.Getter; diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomUserInfoEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomUserInfoEvent.java similarity index 97% rename from API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomUserInfoEvent.java rename to API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomUserInfoEvent.java index bec5ee0..ff1dbf0 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/TikTokRoomUserInfoEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/messages/room/TikTokRoomUserInfoEvent.java @@ -20,7 +20,7 @@ * 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.events.messages; +package io.github.jwdeveloper.tiktok.events.messages.room; import io.github.jwdeveloper.tiktok.annotations.EventMeta; import io.github.jwdeveloper.tiktok.annotations.EventType; diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Emote.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Emote.java index 561e7b3..ea4887d 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Emote.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Emote.java @@ -30,10 +30,9 @@ import java.util.UUID; public class Emote { String emoteId; Picture picture; - UUID uuid; public static Emote map(io.github.jwdeveloper.tiktok.messages.data.Emote input) { - return new Emote(input.getEmoteId(), Picture.map(input.getImage()), UUID.fromString(input.getUuid())); + return new Emote(input.getEmoteId(), Picture.map(input.getImage())); } } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Text.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Text.java index ccda312..ea7e20e 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Text.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/Text.java @@ -25,7 +25,9 @@ package io.github.jwdeveloper.tiktok.events.objects; import io.github.jwdeveloper.tiktok.events.objects.users.User; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException; import lombok.AllArgsConstructor; +import lombok.Data; import lombok.Getter; +import lombok.Value; import java.util.List; @@ -47,16 +49,14 @@ public class Text { } - public static TextPiece mapTextPiece(io.github.jwdeveloper.tiktok.messages.data.Text.TextPiece input) - { - return switch (input.getType()) - { + public static TextPiece mapTextPiece(io.github.jwdeveloper.tiktok.messages.data.Text.TextPiece input) { + return switch (input.getType()) { case 11 -> { var user = User.map(input.getUserValue().getUser()); yield new UserTextPiece(user); } //case 12 -> new GiftTextPiece(input.getStringValue()); - default -> throw new TikTokLiveException("Unknown text piece"); + default -> new StringTextPiece(input.getStringValue()); }; } @@ -66,8 +66,18 @@ public class Text { } + @Value + public static class StringTextPiece extends TextPiece { + String text; + + public StringTextPiece(String text) { + this.text = text; + } + } + public static class UserTextPiece extends TextPiece { User user; + public UserTextPiece(User user) { this.user = user; } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/barrage/BarrageParam.java b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/barrage/BarrageParam.java index 03cd962..e5b6794 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/barrage/BarrageParam.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/events/objects/barrage/BarrageParam.java @@ -22,7 +22,17 @@ */ package io.github.jwdeveloper.tiktok.events.objects.barrage; -public class BarrageParam -{ +import io.github.jwdeveloper.tiktok.messages.webcast.WebcastBarrageMessage; +public class BarrageParam { + + //Figure out barrage type:11 + public static BarrageParam map(WebcastBarrageMessage msg) { + return switch (msg.getMsgType()) { + case GRADEUSERENTRANCENOTIFICATION -> new UserGradeParam(msg.getUserGradeParam()); + case FANSLEVELUPGRADE -> new FansLevelParam(msg.getFansLevelParam()); + case SUBSCRIBEGIFT -> new SubscribeGiftParam(msg.getSubscribeGiftParam()); + default -> new BarrageParam(); + }; + } } diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/handler/TikTokMessageHandler.java b/API/src/main/java/io/github/jwdeveloper/tiktok/handler/TikTokMessageHandler.java index d0de59b..7eade2f 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/handler/TikTokMessageHandler.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/handler/TikTokMessageHandler.java @@ -29,5 +29,5 @@ import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse; public interface TikTokMessageHandler { - TikTokEvent handle(WebcastResponse.Message message) throws Exception; + TikTokEvent handle(byte[] messagePayload) throws Exception; } diff --git a/API/src/main/proto/webcast.proto b/API/src/main/proto/webcast.proto index 834494e..474a6e0 100644 --- a/API/src/main/proto/webcast.proto +++ b/API/src/main/proto/webcast.proto @@ -244,7 +244,6 @@ message WebcastEnvelopeMessage { // @EnvelopeInfo // proto.webcast.im.EnvelopeMessage - // C:\Users\ja\RiderProjects\TikTokProBufferGenerator\Application\output\sources\test.js message EnvelopeInfo { string envelopeId = 1; int64 businessType = 2; // @warning Enum not found, should be BusinessType @@ -283,8 +282,9 @@ message WebcastGoalUpdateMessage { // Message related to Chat-moderation? //@WebcastImDeleteMessage message WebcastImDeleteMessage { - Common header = 1; - bytes data = 3; + Common common = 1; + repeated int64 deleteMsgIdsList = 2; + repeated int64 deleteUserIdsList = 3; } //@WebcastInRoomBannerMessage @@ -708,4 +708,12 @@ message WebcastLinkLayerMessage { } +message RoomVerifyMessage { + Common common = 1; + int32 action = 2; + string content = 3; + int64 noticeType = 4; + bool closeRoom = 5; +} + diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java index 3c2e9ab..9e22191 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/TikTokLiveClientBuilder.java @@ -30,6 +30,9 @@ import io.github.jwdeveloper.tiktok.events.messages.TikTokConnectedEvent; import io.github.jwdeveloper.tiktok.events.messages.TikTokDisconnectedEvent; import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftComboFinishedEvent; import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomPinEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent; diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandler.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandler.java index be87978..f8699f6 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandler.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandler.java @@ -53,7 +53,7 @@ public abstract class TikTokMessageHandler { public abstract void init(); - public void registerMapping(Class clazz, Function func) { + public void registerMapping(Class clazz, Function func) { handlers.put(clazz.getSimpleName(), func::apply); } @@ -72,6 +72,17 @@ public abstract class TikTokMessageHandler { } } } + public void handleSingleMessage(LiveClient client, String type, byte[] bytes) throws Exception { + + if (!handlers.containsKey(type)) { + tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(WebcastResponse.Message.newBuilder().setMethod(type).build())); + return; + } + var handler = handlers.get(type); + var tiktokEvent = handler.handle(bytes); + tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(tiktokEvent, WebcastResponse.Message.newBuilder().build())); + tikTokEventHandler.publish(client, tiktokEvent); + } public void handleSingleMessage(LiveClient client, WebcastResponse.Message message) throws Exception { @@ -85,15 +96,15 @@ public abstract class TikTokMessageHandler { return; } var handler = handlers.get(methodName); - var tiktokEvent = handler.handle(message); + var tiktokEvent = handler.handle(message.getPayload().toByteArray()); tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(tiktokEvent, message)); tikTokEventHandler.publish(client, tiktokEvent); } - protected TikTokEvent mapMessageToEvent(Class inputClazz, Class outputClass, WebcastResponse.Message message) { + protected TikTokEvent mapMessageToEvent(Class inputClazz, Class outputClass, byte[] payload) { try { - var parseMethod = inputClazz.getDeclaredMethod("parseFrom", ByteString.class); - var deserialized = parseMethod.invoke(null, message.getPayload()); + var parseMethod = inputClazz.getDeclaredMethod("parseFrom", byte[].class); + var deserialized = parseMethod.invoke(null,payload); var constructors = Arrays.stream(outputClass.getConstructors()) .filter(ea -> Arrays.stream(ea.getParameterTypes()) .toList() diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandlerRegistration.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandlerRegistration.java index dd28bdd..923e4b2 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandlerRegistration.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/handlers/TikTokMessageHandlerRegistration.java @@ -32,6 +32,9 @@ import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollEndEvent; import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollEvent; import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollStartEvent; import io.github.jwdeveloper.tiktok.events.messages.poll.TikTokPollUpdateEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomPinEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent; @@ -111,8 +114,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { @SneakyThrows - private TikTokEvent handleWebcastControlMessage(WebcastResponse.Message msg) { - var message = WebcastControlMessage.parseFrom(msg.getPayload()); + private TikTokEvent handleWebcastControlMessage(byte[] msg) { + var message = WebcastControlMessage.parseFrom(msg); return switch (message.getAction()) { case STREAM_PAUSED -> new TikTokLivePausedEvent(); case STREAM_ENDED -> new TikTokLiveEndedEvent(); @@ -121,8 +124,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { } @SneakyThrows - private TikTokEvent handleGift(WebcastResponse.Message msg) { - var giftMessage = WebcastGiftMessage.parseFrom(msg.getPayload()); + private TikTokEvent handleGift(byte[] msg) { + var giftMessage = WebcastGiftMessage.parseFrom(msg); var gift = giftManager.findById((int) giftMessage.getGiftId()); @@ -145,8 +148,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { } @SneakyThrows - private TikTokEvent handleSocialMedia(WebcastResponse.Message msg) { - var message = WebcastSocialMessage.parseFrom(msg.getPayload()); + private TikTokEvent handleSocialMedia(byte[] msg) { + var message = WebcastSocialMessage.parseFrom(msg); var socialType = Text.map(message.getCommon().getDisplayText()).getKey(); var matcher = socialMediaPattern.matcher(socialType); @@ -167,8 +170,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { } @SneakyThrows - private TikTokEvent handleMemberMessage(WebcastResponse.Message msg) { - var message = WebcastMemberMessage.parseFrom(msg.getPayload()); + private TikTokEvent handleMemberMessage(byte[] msg) { + var message = WebcastMemberMessage.parseFrom(msg); return switch (message.getAction()) { case JOINED -> new TikTokJoinEvent(message); case SUBSCRIBED -> new TikTokSubscribeEvent(message); @@ -176,21 +179,21 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { }; } - private TikTokEvent handleRoomUserSeqMessage(WebcastResponse.Message msg) { + private TikTokEvent handleRoomUserSeqMessage(byte[] msg) { var event = (TikTokRoomUserInfoEvent) mapMessageToEvent(WebcastRoomUserSeqMessage.class, TikTokRoomUserInfoEvent.class, msg); roomInfo.setViewersCount(event.getTotalUsers()); return event; } - private TikTokEvent handleLike(WebcastResponse.Message msg) { + private TikTokEvent handleLike(byte[] msg) { var event = (TikTokLikeEvent) mapMessageToEvent(WebcastLikeMessage.class, TikTokLikeEvent.class, msg); roomInfo.setLikesCount(event.getTotalLikes()); return event; } @SneakyThrows - private TikTokEvent handlePinMessage(WebcastResponse.Message msg) { - var pinMessage = WebcastRoomPinMessage.parseFrom(msg.getPayload()); + private TikTokEvent handlePinMessage(byte[] msg) { + var pinMessage = WebcastRoomPinMessage.parseFrom(msg); var chatMessage = WebcastChatMessage.parseFrom(pinMessage.getPinnedMessage()); var chatEvent = new TikTokCommentEvent(chatMessage); return new TikTokRoomPinEvent(pinMessage, chatEvent); @@ -198,8 +201,8 @@ public class TikTokMessageHandlerRegistration extends TikTokMessageHandler { //TODO check @SneakyThrows - private TikTokEvent handlePollEvent(WebcastResponse.Message msg) { - var poolMessage = WebcastPollMessage.parseFrom(msg.getPayload()); + private TikTokEvent handlePollEvent(byte[] msg) { + var poolMessage = WebcastPollMessage.parseFrom(msg); return switch (poolMessage.getMessageType()) { case 0 -> new TikTokPollStartEvent(poolMessage); case 1 -> new TikTokPollEndEvent(poolMessage); diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketListener.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketListener.java index 94a280b..462fa26 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketListener.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketListener.java @@ -88,11 +88,16 @@ public class TikTokWebSocketListener extends WebSocketClient { @Override public void onClose(int i, String s, boolean b) { + + System.out.println("CLOSE "+i+" "+s+" "+b); tikTokEventHandler.publish(tikTokLiveClient,new TikTokDisconnectedEvent()); } @Override - public void onError(Exception error) { + public void onError(Exception error) + { + System.out.println("ERROR"); + error.printStackTrace(); tikTokEventHandler.publish(tikTokLiveClient,new TikTokErrorEvent(error)); if(isNotClosing()) { @@ -106,6 +111,7 @@ public class TikTokWebSocketListener extends WebSocketClient { return; } var websocketMessage = websocketMessageOptional.get(); + System.out.println("ACK ID "+websocketMessage.getLogId()+" ID "+websocketMessage.getSeqId()); sendAckId(websocketMessage.getLogId()); var webResponse = getWebResponseMessage(websocketMessage.getPayload()); @@ -147,7 +153,8 @@ public class TikTokWebSocketListener extends WebSocketClient { .build(); if(isNotClosing()) { - send(serverInfo.toByteString().toByteArray()); + System.out.println("SEND ICK ID "+id); + send(serverInfo.toByteArray()); } } diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketPingingTask.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketPingingTask.java index d324b39..68031c7 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketPingingTask.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/websocket/TikTokWebSocketPingingTask.java @@ -36,6 +36,7 @@ public class TikTokWebSocketPingingTask public void run(WebSocket webSocket) { + stop(); var thread = new Thread(() -> { pingTask(webSocket); @@ -66,7 +67,9 @@ public class TikTokWebSocketPingingTask Thread.sleep(100); continue; } + System.out.println("PING!"); webSocket.sendPing(); + var timeout = random.nextInt(MAX_TIMEOUT)+MIN_TIMEOUT; Thread.sleep(timeout); } diff --git a/TestApplication/src/main/java/io/github/jwdeveloper/tiktok/Main.java b/TestApplication/src/main/java/io/github/jwdeveloper/tiktok/Main.java index c269aaf..5f00396 100644 --- a/TestApplication/src/main/java/io/github/jwdeveloper/tiktok/Main.java +++ b/TestApplication/src/main/java/io/github/jwdeveloper/tiktok/Main.java @@ -26,6 +26,7 @@ import io.github.jwdeveloper.tiktok.events.messages.*; import io.github.jwdeveloper.tiktok.events.messages.TikTokConnectedEvent; import io.github.jwdeveloper.tiktok.events.messages.TikTokDisconnectedEvent; import io.github.jwdeveloper.tiktok.events.messages.gift.TikTokGiftEvent; +import io.github.jwdeveloper.tiktok.events.messages.room.TikTokRoomUserInfoEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokFollowEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokJoinEvent; import io.github.jwdeveloper.tiktok.events.messages.social.TikTokLikeEvent; @@ -38,7 +39,7 @@ import java.time.Duration; public class Main { - public static String TEST_TIKTOK_USER = "szwagierkaqueen"; + public static String TEST_TIKTOK_USER = "ano_liwia"; public static void main(String[] args) throws IOException { @@ -57,7 +58,7 @@ public class Main { }) .onConnected(Main::onConnected) .onDisconnected(Main::onDisconnected) - .onRoomUserInfo(Main::onViewerData) + .onRoomUserInfo(Main::onRoomUserInfo) .onJoin(Main::onJoin) .onComment(Main::onComment) .onFollow(Main::onFollow) @@ -81,7 +82,7 @@ public class Main { private static void onGift(LiveClient tikTokLive, TikTokGiftEvent e) { switch (e.getGift()) { - case ROSE -> print( "\uD83D\uDC95",ConsoleColors.YELLOW,"x", e.getCombo(), " roses!", "\uD83D\uDC95"); + case ROSE -> print( ConsoleColors.YELLOW,"x", e.getCombo(), " roses!", "\uD83D\uDC95"); default -> print(ConsoleColors.YELLOW,"Thanks for gift: ", e.getGift().getName(),"X",e.getCombo()); } if(e.getGift().hasDiamondCostRange(1000,10000)) @@ -93,7 +94,7 @@ public class Main { private static void onDisconnected(LiveClient tikTokLive, TikTokDisconnectedEvent e) { print(ConsoleColors.GREEN, "[Disconnected]"); } - private static void onViewerData(LiveClient tikTokLive, TikTokRoomUserInfoEvent e) { + private static void onRoomUserInfo(LiveClient tikTokLive, TikTokRoomUserInfoEvent e) { print("Viewer count is:", e.getTotalUsers()); } diff --git a/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/collector/RunCollector.java b/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/collector/RunCollector.java index 70c452f..1b36b88 100644 --- a/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/collector/RunCollector.java +++ b/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/collector/RunCollector.java @@ -63,7 +63,7 @@ public class RunCollector { // users.add("mia_tattoo"); // users.add("mr_wavecheck"); users.add("bangbetmenygy"); - users.add("szwagierkaqueen"); + // users.add("szwagierkaqueen"); for (var user : users) { try { runTikTokLiveInstance(user, db); diff --git a/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/tester/RunLogTester.java b/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/tester/RunLogTester.java index ee8377a..bd8ce54 100644 --- a/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/tester/RunLogTester.java +++ b/Tools-EventsCollector/src/main/java/io/github/jwdeveloper/tiktok/tools/tester/RunLogTester.java @@ -22,16 +22,61 @@ */ package io.github.jwdeveloper.tiktok.tools.tester; +import com.google.gson.JsonParser; +import com.google.protobuf.InvalidProtocolBufferException; +import io.github.jwdeveloper.tiktok.messages.webcast.WebcastLinkMicFanTicketMethod; import io.github.jwdeveloper.tiktok.mockClient.TikTokClientMock; -public class RunLogTester -{ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.*; - public static void main(String[] args) - { - var mockClient = TikTokClientMock.create("123").buildAndRun(); +public class RunLogTester { + + + public static void main(String[] args) throws IOException { + + + var input ="CjwKHVdlYmNhc3RMaW5rTWljRmFuVGlja2V0TWV0aG9kEIWWp7ig2O6OZRiGlviyrNjpjmUgza2G4a8xMAESZwoNCIWIouKYhLqBYhCbARCbASpTaHR0cHM6Ly9wMTYtd2ViY2FzdC50aWt0b2tjZG4uY29tL2ltZy93ZWJjYXN0LXNnL3Rpa3Rva19saW5rbWljX2NvaW5AM3gucG5nfjB4MC5wbmc="; + var bytes = Base64.getDecoder().decode(input); + var a= WebcastLinkMicFanTicketMethod.parseFrom(bytes); + var messages = getMessages(); + var client = TikTokClientMock.create().build(); + for(var msg : messages.entrySet()) + { + for(var content : msg.getValue()) + { + client.publishMessage(msg.getKey(),content); + } + } + client.connect(); + } + + + private static Map> getMessages() throws IOException { + var path = "C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\Tools-EventsCollector\\src\\main\\resources\\log.json"; + var jsonElement = JsonParser.parseReader(new FileReader(path, Charset.defaultCharset())); + + var res = new HashMap>(); + if (jsonElement.isJsonObject()) { + var jsonObject = jsonElement.getAsJsonObject(); + var keys = jsonObject.keySet(); + for (String key : keys) { + var messages = jsonObject.get(key).getAsJsonArray(); + for (var msg : messages) { + var data = msg.getAsJsonObject().get("eventData").getAsString(); + // System.out.println("KEY: " + key + " DATA: " + data); + res.computeIfAbsent(key, s -> new ArrayList<>()).add(data); + } + } + } + return res; } } diff --git a/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/LiveClientMock.java b/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/LiveClientMock.java index ed49b9f..26eb4f6 100644 --- a/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/LiveClientMock.java +++ b/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/LiveClientMock.java @@ -56,6 +56,13 @@ public class LiveClientMock extends TikTokLiveClient { this.websocketClientMock = webSocketClient; } + public void publishMessage(String type, String base64) { + websocketClientMock.addMessage(type, base64); + } + + public void publishMessage(Class clazz, String base64) { + websocketClientMock.addMessage(clazz.getSimpleName(), base64); + } public void publishResponse(String value) { websocketClientMock.addResponse(value); diff --git a/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/WebsocketClientMock.java b/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/WebsocketClientMock.java index a321800..caba3ff 100644 --- a/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/WebsocketClientMock.java +++ b/Tools/src/main/java/io/github/jwdeveloper/tiktok/mockClient/mocks/WebsocketClientMock.java @@ -22,12 +22,13 @@ */ package io.github.jwdeveloper.tiktok.mockClient.mocks; -import io.github.jwdeveloper.tiktok.TikTokLiveClientBuilder; +import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException; import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandler; import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse; import io.github.jwdeveloper.tiktok.websocket.SocketClient; +import lombok.Value; import java.util.Base64; import java.util.Stack; @@ -37,16 +38,30 @@ import java.util.logging.Logger; public class WebsocketClientMock implements SocketClient { Logger logger; Stack responses; + + Stack messages; TikTokMessageHandler messageHandler; private boolean isRunning; + @Value + public static class MsgStruct { + String messageType; + byte[] messageValue; + } + public WebsocketClientMock(Logger logger, Stack responses, TikTokMessageHandler messageHandler) { this.logger = logger; this.responses = responses; this.messageHandler = messageHandler; + messages = new Stack<>(); } + public WebsocketClientMock addMessage(String type, String value) { + var bytes = Base64.getDecoder().decode(value); + messages.push(new MsgStruct(type, bytes)); + return this; + } public WebsocketClientMock addResponse(String value) { var bytes = Base64.getDecoder().decode(value); @@ -71,13 +86,9 @@ public class WebsocketClientMock implements SocketClient { @Override public void start(WebcastResponse webcastResponse, LiveClient tikTokLiveClient) { logger.info("Running message: " + responses.size()); - isRunning =true; - while (isRunning) { - do { - if(responses.isEmpty()) - { - break; - } + isRunning = true; + while (!responses.isEmpty() || !messages.isEmpty()) { + if (!responses.isEmpty()) { var response = responses.pop(); for (var message : response.getMessagesList()) { try { @@ -88,11 +99,15 @@ public class WebsocketClientMock implements SocketClient { } } } - while (!responses.isEmpty()); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - throw new RuntimeException(e); + if (!messages.isEmpty()) { + var messageStr = messages.pop(); + try { + System.out.println("TYPE: " + messageStr.getMessageType()); + messageHandler.handleSingleMessage(tikTokLiveClient, messageStr.getMessageType(), messageStr.getMessageValue()); + } catch (Exception e) { + logger.info("Unable to parse message for response " + messageStr.getMessageType()); + throw new TikTokLiveException(e); + } } }