diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftComboEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftComboEvent.java index 849a12b..d2f6add 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftComboEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftComboEvent.java @@ -29,8 +29,6 @@ import io.github.jwdeveloper.tiktok.data.models.users.User; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage; import lombok.Getter; - - @EventMeta(eventType = EventType.Message) @Getter public class TikTokGiftComboEvent extends TikTokGiftEvent { @@ -43,12 +41,9 @@ public class TikTokGiftComboEvent extends TikTokGiftEvent { public static TikTokGiftComboEvent of(Gift gift, int combo, GiftComboStateType comboState) { return new TikTokGiftComboEvent( - gift, - new User(0L, "Test", new Picture("")), - WebcastGiftMessage - .newBuilder() - .setComboCount(combo) - .build(), - comboState); + gift, + new User(0L, "Test", new Picture("")), + WebcastGiftMessage.newBuilder().setComboCount(combo).build(), + comboState); } } \ No newline at end of file diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftEvent.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftEvent.java index caa3485..7b98b7a 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftEvent.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/events/gift/TikTokGiftEvent.java @@ -22,7 +22,6 @@ */ package io.github.jwdeveloper.tiktok.data.events.gift; - import io.github.jwdeveloper.tiktok.annotations.*; import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent; import io.github.jwdeveloper.tiktok.data.models.Picture; @@ -31,8 +30,6 @@ import io.github.jwdeveloper.tiktok.data.models.users.User; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage; import lombok.Getter; - - @EventMeta(eventType = EventType.Message) @Getter public class TikTokGiftEvent extends TikTokHeaderEvent { diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/data/models/gifts/GiftComboStateType.java b/API/src/main/java/io/github/jwdeveloper/tiktok/data/models/gifts/GiftComboStateType.java index cbb1b28..9f6f1d3 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/data/models/gifts/GiftComboStateType.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/data/models/gifts/GiftComboStateType.java @@ -23,9 +23,9 @@ package io.github.jwdeveloper.tiktok.data.models.gifts; public enum GiftComboStateType { - Finished, Begin, - Active; + Active, + Finished; public static GiftComboStateType fromNumber(long number) { return switch ((int) number) { diff --git a/API/src/main/java/io/github/jwdeveloper/tiktok/live/builder/EventsBuilder.java b/API/src/main/java/io/github/jwdeveloper/tiktok/live/builder/EventsBuilder.java index a6f4552..9f19a27 100644 --- a/API/src/main/java/io/github/jwdeveloper/tiktok/live/builder/EventsBuilder.java +++ b/API/src/main/java/io/github/jwdeveloper/tiktok/live/builder/EventsBuilder.java @@ -123,8 +123,11 @@ public interface EventsBuilder { } /** - * Invoked for gifts that has no combo, or when combo finishes - * + * Triggers for these different reasons: + *
    + *
  1. User sends gifts that have no combo (most of expensive gifts)
  2. + *
  3. {@link TikTokGiftComboEvent} has combaState = {@link GiftComboStateType#Finished}
  4. + *
* @param action consumable action * @return self instance */ @@ -133,19 +136,19 @@ public interface EventsBuilder { } /** - * Triggered every time gift is sent + * Triggered every time a gift is sent + *

Example when user sends gift with combo

+ * + * Both {@link TikTokGiftComboEvent} and {@link TikTokGiftEvent} events are triggered when comboState is Finished * + * @apiNote {@link GiftComboStateType} has 3 states: {@link GiftComboStateType#Begin Begin}, {@link GiftComboStateType#Active Active}, & {@link GiftComboStateType#Finished Finished} * @param action consumable action * @return self instance - * @see GiftComboStateType it has 3 states - * - *

Example when user sends gift with combo

- *

>Combo: 1 -> comboState = GiftSendType.Begin

- *

Combo: 4 -> comboState = GiftSendType.Active

- *

Combo: 8 -> comboState = GiftSendType.Active

- *

Combo: 12 -> comboState = GiftSendType.Finished

- *

- * Remember if comboState is Finished both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered */ default T onGiftCombo(EventConsumer action) { return onEvent(TikTokGiftComboEvent.class, action); diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/TikTokGenericEventMapper.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/TikTokGenericEventMapper.java index c2c1cda..a7e8a0c 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/TikTokGenericEventMapper.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/TikTokGenericEventMapper.java @@ -27,26 +27,24 @@ import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Goal of this class is to map ProtocolBuffer objects to TikTok Event in generic way - * - * First parameter is ProtocolBuffer class type - * Second parameters is TikTokEvent class type - * Third parameters is bytes payload - * - * mapToEvent(WebcastGiftMessage.class, TikTokGiftEvent.class, payload) - * - * How does it work? - * 1. Finds method `parseFrom(byte[] bytes)` inside ProtocolBuffer class - * 2. put payload to the method methods and create new instance of ProtcolBuffer object - * 3. Finds in TikTokEvent constructor that takes ProtocolBuffer type as parameter - * 4. create new Instance in TikTokEvents using object from step 2 and constructor from step 3 - * - * methodCache and constructorCache are used to boost performance + *

+ *

mapToEvent(WebcastGiftMessage.class, TikTokGiftEvent.class, payload)

+ *

How does it work?

+ *
    + *
  1. Finds method `parseFrom(byte[] bytes)` inside ProtocolBuffer class
  2. + *
  3. Put payload to the method methods and create new instance of ProtcolBuffer object
  4. + *
  5. Finds in TikTokEvent constructor that takes ProtocolBuffer type as parameter
  6. + *
  7. Create new Instance in TikTokEvents using object from step 2 and constructor from step 3
  8. + *
+ * methodCache and constructorCache are used to boost performance */ public class TikTokGenericEventMapper { @@ -74,34 +72,27 @@ public class TikTokGenericEventMapper { } } - public Method getParsingMethod(Class input) throws NoSuchMethodException { - if (methodCache.containsKey(input)) { - return methodCache.get(input); - } - var method = input.getDeclaredMethod("parseFrom", byte[].class); - methodCache.put(input, method); - return method; + public Method getParsingMethod(Class input) throws RuntimeException { + return methodCache.computeIfAbsent(input, aClass -> { + try { + return aClass.getDeclaredMethod("parseFrom", byte[].class); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + }); } private Constructor getParsingConstructor(Class input, Class output) { - var pair = new TypePair(input, output); - if (constructorCache.containsKey(pair)) { - return constructorCache.get(pair); - } - - var optional = Arrays.stream(output.getConstructors()) + return constructorCache.computeIfAbsent(new TypePair(input, output), pair -> { + var optional = Arrays.stream(output.getConstructors()) .filter(ea -> Arrays.stream(ea.getParameterTypes()) - .toList() - .contains(input)) + .toList() + .contains(input)) .findFirst(); - if (optional.isEmpty()) { - throw new TikTokMessageMappingException(input, output, "Unable to find constructor with input class type"); - } - - constructorCache.put(pair, optional.get()); - return optional.get(); + if (optional.isEmpty()) + throw new TikTokMessageMappingException(input, output, "Unable to find constructor with input class type"); + return optional.get(); + }); } - - -} +} \ No newline at end of file diff --git a/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/handlers/TikTokGiftEventHandler.java b/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/handlers/TikTokGiftEventHandler.java index 2e4f17d..cd4293d 100644 --- a/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/handlers/TikTokGiftEventHandler.java +++ b/Client/src/main/java/io/github/jwdeveloper/tiktok/mappers/handlers/TikTokGiftEventHandler.java @@ -55,11 +55,6 @@ public class TikTokGiftEventHandler { } public List handleGift(WebcastGiftMessage currentMessage) { - var userId = currentMessage.getUser().getId(); - var currentType = GiftComboStateType.fromNumber(currentMessage.getSendType()); - var containsPreviousMessage = giftsMessages.containsKey(userId); - - //If gift is not streakable just return onGift event if (currentMessage.getGift().getType() != 1) { var comboEvent = getGiftComboEvent(currentMessage, GiftComboStateType.Finished); @@ -67,7 +62,11 @@ public class TikTokGiftEventHandler { return List.of(comboEvent, giftEvent); } - if (!containsPreviousMessage) { + var userId = currentMessage.getUser().getId(); + var currentType = GiftComboStateType.fromNumber(currentMessage.getSendType()); + var previousMessage = giftsMessages.get(userId); + + if (previousMessage == null) { if (currentType == GiftComboStateType.Finished) { return List.of(getGiftEvent(currentMessage)); } else { @@ -76,7 +75,6 @@ public class TikTokGiftEventHandler { } } - var previousMessage = giftsMessages.get(userId); var previousType = GiftComboStateType.fromNumber(previousMessage.getSendType()); if (currentType == GiftComboStateType.Active && previousType == GiftComboStateType.Active) { @@ -114,9 +112,9 @@ public class TikTokGiftEventHandler { gift = giftsManager.getByName(giftMessage.getGift().getName()); if (gift == Gift.UNDEFINED) { gift = new Gift(giftId, - giftMessage.getGift().getName(), - giftMessage.getGift().getDiamondCount(), - Picture.map(giftMessage.getGift().getImage())); + giftMessage.getGift().getName(), + giftMessage.getGift().getDiamondCount(), + Picture.map(giftMessage.getGift().getImage())); giftsManager.attachGift(gift); }