Events handling

This commit is contained in:
JW
2023-08-16 17:36:40 +02:00
parent 59befcd6f9
commit 4b9e531c95
121 changed files with 4368 additions and 613 deletions

View File

@@ -0,0 +1,40 @@
package io.github.jwdeveloper.tiktok.handlers;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class TikTokEventHandler {
private final Map<String, Consumer> events;
public TikTokEventHandler()
{
events = new HashMap<>();
}
public void publish(TikTokEvent tikTokEvent)
{
if(events.containsKey(TikTokEvent.class.getSimpleName()))
{
var handler = events.get(TikTokEvent.class.getSimpleName());
handler.accept(tikTokEvent);
}
var name = tikTokEvent.getClass().getSimpleName();
if(!events.containsKey(name))
{
return;
}
var handler = events.get(name);
handler.accept(tikTokEvent);
}
public <T extends TikTokEvent> void subscribe(Class<?> clazz, Consumer<T> event)
{
events.put(clazz.getSimpleName(),event);
}
}

View File

@@ -0,0 +1,12 @@
package io.github.jwdeveloper.tiktok.handlers;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import io.github.jwdeveloper.tiktok.messages.WebcastResponse;
public interface TikTokMessageHandler<T>
{
Class<T> getHandleClazz();
TikTokEvent handle(WebcastResponse.Message message) throws Exception;
}

View File

@@ -0,0 +1,149 @@
package io.github.jwdeveloper.tiktok.handlers;
import io.github.jwdeveloper.tiktok.TikTokGiftManager;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import io.github.jwdeveloper.tiktok.events.messages.*;
import io.github.jwdeveloper.tiktok.events.objects.TikTokGift;
import io.github.jwdeveloper.tiktok.messages.*;
import io.github.jwdeveloper.tiktok.models.GiftId;
import io.github.jwdeveloper.tiktok.models.SocialTypes;
import lombok.SneakyThrows;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WebResponseHandler extends WebResponseHandlerBase {
private final TikTokGiftManager giftManager;
public WebResponseHandler(TikTokEventHandler tikTokEventHandler, TikTokGiftManager giftManager) {
super(tikTokEventHandler);
this.giftManager = giftManager;
}
@Override
public void init() {
//ConnectionEvents events
register(WebcastControlMessage.class, TikTokRoomMessageEvent.class);
register(SystemMessage.class, this::handleWebcastControlMessage);
//Room status events
register(WebcastLiveIntroMessage.class, TikTokRoomMessageEvent.class);
register(WebcastRoomUserSeqMessage.class, TikTokRoomViewerDataEvent.class); //TODO update viewer count ViewerCount = userSeqMessage.ViewerCount;
register(RoomMessage.class, TikTokRoomMessageEvent.class);
register(WebcastRoomMessage.class, TikTokRoomMessageEvent.class);
register(WebcastCaptionMessage.class, TikTokCaptionEvent.class);
//User Interactions events
register(WebcastChatMessage.class, TikTokCommentEvent.class);
register(WebcastLikeMessage.class, TikTokLikeEvent.class);
register(WebcastGiftMessage.class, this::handleGift);
register(WebcastSocialMessage.class, this::handleSocialMedia);
register(WebcastMemberMessage.class, this::handleMemberMessage);
//Host Interaction events
register(WebcastPollMessage.class, TikTokPollMessageEvent.class);
register(WebcastRoomPinMessage.class, TikTokRoomPinMessageEvent.class);
register(WebcastGoalUpdateMessage.class, TikTokGoalUpdateEvent.class);
//LinkMic events
register(WebcastLinkMicBattle.class, TikTokLinkMicBattleEvent.class);
register(WebcastLinkMicArmies.class, TikTokLinkMicArmiesEvent.class);
register(LinkMicMethod.class, TikTokLinkMicMethodEvent.class);
register(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
register(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
//Rank events
register(WebcastRankTextMessage.class, TikTokRankTextEvent.class);
register(WebcastRankUpdateMessage.class, TikTokRankUpdateEvent.class);
register(WebcastHourlyRankMessage.class, TikTokRankUpdateEvent.class);
//Others events
register(WebcastInRoomBannerMessage.class, TikTokInRoomBannerEvent.class);
register(WebcastMsgDetectMessage.class, TikTokDetectMessageEvent.class);
register(WebcastBarrageMessage.class, TikTokBarrageMessageEvent.class);
register(WebcastUnauthorizedMemberMessage.class, TikTokUnauthorizedMemberEvent.class);
register(WebcastGiftBroadcastMessage.class, TikTokGiftBroadcastEvent.class);
register(WebcastOecLiveShoppingMessage.class, TikTokShopMessageEvent.class);
register(WebcastImDeleteMessage.class, TikTokIMDeleteEvent.class);
register(WebcastQuestionNewMessage.class, TikTokQuestionEvent.class);
register(WebcastEnvelopeMessage.class, TikTokEnvelopeEvent.class);
register(WebcastSubNotifyMessage.class, TikTokSubNotifyEvent.class);
register(WebcastEmoteChatMessage.class, TikTokEmoteEvent.class);
}
@SneakyThrows
private TikTokEvent handleWebcastControlMessage(WebcastResponse.Message msg)
{
var message = WebcastControlMessage.parseFrom(msg.getBinary());
return switch (message.getAction()) {
case STREAM_PAUSED -> new TikTokLivePausedEvent();
case STREAM_ENDED -> new TikTokLiveEndedEvent();
default -> new TikTokUnhandledControlEvent(message);
};
}
@SneakyThrows
private TikTokEvent handleGift(WebcastResponse.Message msg) {
var giftMessage = WebcastGiftMessage.parseFrom(msg.getBinary());
var giftId = new GiftId(giftMessage.getGiftId(), giftMessage.getSender().getUniqueId());
var activeGifts = giftManager.getActiveGifts();
if (activeGifts.containsKey(giftId)) {
// Debug.Log($"Updating Gift[{giftId.Gift}]Amount[{message.Amount}]");
var gift = activeGifts.get(giftId);
gift.setAmount(giftMessage.getAmount());
} else {
TikTokGift newGift = new TikTokGift(giftMessage);
activeGifts.put(giftId, newGift);
// Debug.Log($"New Gift[{giftId.Gift}]Amount[{message.Amount}]");
// RunEvent(OnGift, newGift);
}
if (giftMessage.getRepeatEnd()) {
//if (ShouldLog(LogLevel.Verbose))
// Debug.Log($"GiftStreak Ended: [{giftId.Gift}] Amount[{message.Amount}]")
var gift = activeGifts.get(giftId);
gift.setStreakFinished(true);
activeGifts.remove(gift);
}
// Debug.Log($"Handling GiftMessage");
return new TikTokGiftMessageEvent(giftMessage);
}
@SneakyThrows
private TikTokEvent handleSocialMedia(WebcastResponse.Message msg) {
var message = WebcastSocialMessage.parseFrom(msg.getBinary());
String type = message.getHeader().getSocialData().getType();
Pattern pattern = Pattern.compile("pm_mt_guidance_viewer_([0-9]+)_share");
Matcher matcher = pattern.matcher(type);
if (matcher.find()) {
var value = matcher.group(0);
var number = Integer.parseInt(value);
return new TikTokShareEvent(message, number);
}
var socialType = message.getHeader().getSocialData().getType();
return switch (socialType) {
case SocialTypes.LikeType -> new TikTokLikeEvent(message);
case SocialTypes.FollowType -> new TikTokFollowEvent(message);
case SocialTypes.ShareType -> new TikTokShareEvent(message);
case SocialTypes.JoinType -> new TikTokJoinEvent(message);
default -> new TikTokUnhandledSocialEvent(message);
};
}
@SneakyThrows
private TikTokEvent handleMemberMessage(WebcastResponse.Message msg) {
var message = WebcastMemberMessage.parseFrom(msg.getBinary());
return switch (message.getAction()) {
case JOINED -> new TikTokJoinEvent(message);
case SUBSCRIBED -> new TikTokSubscribeEvent(message);
default -> new TikTokUnhandledMemberEvent(message);
};
}
}

View File

@@ -0,0 +1,89 @@
package io.github.jwdeveloper.tiktok.handlers;
import com.google.protobuf.ByteString;
import io.github.jwdeveloper.tiktok.events.messages.*;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
import io.github.jwdeveloper.tiktok.messages.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public abstract class WebResponseHandlerBase {
private final Map<String, TikTokMessageHandler> handlers;
private final TikTokEventHandler tikTokEventHandler;
public WebResponseHandlerBase(TikTokEventHandler tikTokEventHandler)
{
handlers = new HashMap<>();
this.tikTokEventHandler =tikTokEventHandler;
}
public abstract void init();
public void register(Class<?> input, Class<?> output)
{
register(input,(e)->
{
try
{
var parseMethod = input.getDeclaredMethod("parseFrom", ByteString.class);
var deserialized = parseMethod.invoke(null,e.getBinary());
var constructors = Arrays.stream(output.getConstructors()).filter(ea -> Arrays.stream(ea.getParameterTypes()).toList().contains(input)).findFirst();
var tiktokEvent = constructors.get().newInstance(deserialized);
return (TikTokEvent)tiktokEvent;
}
catch (Exception ex)
{
throw new TikTokLiveException("Unable to handle parsing from class: "+input.getSimpleName()+" to class "+output.getSimpleName(),ex);
}
});
}
public <T> void register(Class clazz, Function<WebcastResponse.Message,TikTokEvent> func)
{
var haandler = new TikTokMessageHandler<T>() {
@Override
public Class<T> getHandleClazz() {
return clazz;
}
@Override
public TikTokEvent handle(WebcastResponse.Message message) throws Exception {
return func.apply(message);
}
};
handlers.put(haandler.getHandleClazz().getSimpleName(), haandler);
}
public void handle(WebcastResponse webcastResponse) {
// System.out.println("==============================================================");
// System.out.println("Getting messages: " + webcastResponse.getMessagesList().size());
for (var message : webcastResponse.getMessagesList()) {
try {
handleSingleMessage(message);
} catch (Exception e) {
throw new TikTokLiveException("Error whilst Handling Message. Stopping Client.{Environment.NewLine}Final Message: {Convert.ToBase64String(message.Binary)}", e);
}
}
// System.out.println("==============================================================");
}
private void handleSingleMessage(WebcastResponse.Message message) throws Exception {
if(!handlers.containsKey(message.getType()))
{
tikTokEventHandler.publish(new TikTokUnhandledEvent(message));
return;
}
var handler = handlers.get(message.getType());
var tiktokEvent = handler.handle(message);
tikTokEventHandler.publish(tiktokEvent);
}
}