Compare commits

...

10 Commits

Author SHA1 Message Date
jacek.wolniewicz
47b050d0ba Introduce dependecy injection container
- TikTokLiveClientBuilder this class has been higly modify to support DI container
2024-06-29 22:52:39 +02:00
GitHub Action
34ddc74189 Update version in pom.xml 2024-06-24 14:16:40 +00:00
Jacek W
9a66d240bc Merge pull request #85 from jwdeveloper/develop-1.7.2
Develop 1.7.2
2024-06-24 08:38:22 +02:00
kohlerpop1
d825803187 Added while loop condition so it does not exit when getConnectionState returns Disconnected and stopOnDisconnect is false! 2024-06-23 23:06:05 -04:00
kohlerpop1
77c9cd6b52 Converted Consumer to BiConsumer to also accept liveClient! 2024-06-20 16:51:42 -04:00
kohlerpop1
0329d3cfeb Removed useless imports and altered logger message! 2024-06-18 22:01:47 -04:00
kohlerpop1
26659bb37d Removed not needed/used RecorderSettings#startOnConnected 2024-06-18 15:36:03 -04:00
kohlerpop1
0b9852c4d4 Moved ActionResult#message to top of toJson() for easier reading
Change Recording settings to accept an output file instead of directory and filename
2024-06-18 15:21:05 -04:00
GitHub Action
31618a16ba Update version in pom.xml 2024-06-07 10:55:14 +00:00
GitHub Action
243791f6b8 Update version in pom.xml 2024-06-02 20:11:19 +00:00
44 changed files with 804 additions and 246 deletions

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>API</artifactId> <artifactId>API</artifactId>

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.data.models.battles; package io.github.jwdeveloper.tiktok.data.models.battles;
public abstract class Team { public abstract class Team {

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.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;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.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;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.data.models.battles; package io.github.jwdeveloper.tiktok.data.models.battles;
import io.github.jwdeveloper.tiktok.data.models.Picture; import io.github.jwdeveloper.tiktok.data.models.Picture;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.data.models.gifts; package io.github.jwdeveloper.tiktok.data.models.gifts;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.data.models.users; package io.github.jwdeveloper.tiktok.data.models.users;
import lombok.Getter; import lombok.Getter;

View File

@@ -31,7 +31,7 @@ import java.util.function.Consumer;
@Getter @Getter
@Setter @Setter
public class ProxyClientSettings implements Iterator<ProxyData> public class ProxyClientSettings implements Iterator<ProxyData>, Iterable<ProxyData>
{ {
private boolean enabled, autoDiscard = true, fallback = true; private boolean enabled, autoDiscard = true, fallback = true;
private Rotation rotation = Rotation.CONSECUTIVE; private Rotation rotation = Rotation.CONSECUTIVE;
@@ -109,6 +109,14 @@ public class ProxyClientSettings implements Iterator<ProxyData>
return settings; return settings;
} }
/**
* With Iterable<?> interface you can use this object inside For loop!
*/
@Override
public Iterator<ProxyData> iterator() {
return this;
}
public enum Rotation public enum Rotation
{ {
/** Rotate addresses consecutively, from proxy 0 -> 1 -> 2 -> ...etc. */ /** Rotate addresses consecutively, from proxy 0 -> 1 -> 2 -> ...etc. */

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.listener; package io.github.jwdeveloper.tiktok.listener;
import io.github.jwdeveloper.tiktok.data.events.*; import io.github.jwdeveloper.tiktok.data.events.*;

View File

@@ -25,6 +25,7 @@ package io.github.jwdeveloper.tiktok.live.builder;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;
@FunctionalInterface
public interface EventConsumer<T extends TikTokEvent> public interface EventConsumer<T extends TikTokEvent>
{ {
void onEvent(LiveClient liveClient, T event); void onEvent(LiveClient liveClient, T event);

View File

@@ -5,12 +5,18 @@
<parent> <parent>
<artifactId>TikTokLiveJava</artifactId> <artifactId>TikTokLiveJava</artifactId>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<version>1.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>Client</artifactId> <artifactId>Client</artifactId>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -24,7 +30,12 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.jwdeveloper.DepenDance</groupId>
<artifactId>DepenDance-Full</artifactId>
<version>0.0.18-Release</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.google.protobuf</groupId> <groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId> <artifactId>protobuf-java</artifactId>

View File

@@ -35,7 +35,7 @@ public class TikTokLive {
/** /**
* Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo' * Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo'
* *
* @param hostName profile name of Tiktok user could be found in profile link * @param hostName profile name of TikTok user could be found in profile link
* @return LiveClientBuilder * @return LiveClientBuilder
*/ */
public static LiveClientBuilder newClient(String hostName) { public static LiveClientBuilder newClient(String hostName) {
@@ -45,7 +45,7 @@ public class TikTokLive {
/** /**
* Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo' * Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo'
* *
* @param hostName profile name of Tiktok user could be found in profile link * @param hostName profile name of TikTok user could be found in profile link
* @return true if live is Online, false if is offline * @return true if live is Online, false if is offline
*/ */
public static boolean isLiveOnline(String hostName) { public static boolean isLiveOnline(String hostName) {
@@ -55,7 +55,7 @@ public class TikTokLive {
/** /**
* Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo' * Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo'
* *
* @param hostName profile name of Tiktok user could be found in profile link * @param hostName profile name of TikTok user could be found in profile link
* @return true if live is Online, false if is offline * @return true if live is Online, false if is offline
*/ */
public static CompletableFuture<Boolean> isLiveOnlineAsync(String hostName) { public static CompletableFuture<Boolean> isLiveOnlineAsync(String hostName) {
@@ -65,7 +65,7 @@ public class TikTokLive {
/** /**
* Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo' * Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo'
* *
* @param hostName profile name of Tiktok user could be found in profile link * @param hostName profile name of TikTok user could be found in profile link
* @return true is hostName name is valid and exists, false if not * @return true is hostName name is valid and exists, false if not
*/ */
public static boolean isHostNameValid(String hostName) { public static boolean isHostNameValid(String hostName) {
@@ -75,7 +75,7 @@ public class TikTokLive {
/** /**
* Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo' * Example: https://www.tiktok.com/@dostawcavideo - hostName would be 'dostawcavideo'
* *
* @param hostName profile name of Tiktok user could be found in profile link * @param hostName profile name of TikTok user could be found in profile link
* @return true is hostName name is valid and exists, false if not * @return true is hostName name is valid and exists, false if not
*/ */
public static CompletableFuture<Boolean> isHostNameValidAsync(String hostName) { public static CompletableFuture<Boolean> isHostNameValidAsync(String hostName) {

View File

@@ -23,6 +23,7 @@
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import io.github.jwdeveloper.dependance.injector.api.annotations.Inject;
import io.github.jwdeveloper.tiktok.data.events.*; import io.github.jwdeveloper.tiktok.data.events.*;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
import io.github.jwdeveloper.tiktok.data.events.control.*; import io.github.jwdeveloper.tiktok.data.events.control.*;
@@ -43,13 +44,14 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Logger; import java.util.logging.Logger;
public class TikTokLiveClient implements LiveClient { public class TikTokLiveClient implements LiveClient
{
private final TikTokRoomInfo liveRoomInfo; private final TikTokRoomInfo liveRoomInfo;
private final LiveHttpClient httpClient; private final LiveHttpClient httpClient;
private final SocketClient webSocketClient; private final SocketClient webSocketClient;
private final TikTokLiveEventHandler tikTokEventHandler; private final TikTokLiveEventHandler tikTokEventHandler;
private final LiveClientSettings clientSettings; private final LiveClientSettings clientSettings;
private final TikTokListenersManager listenersManager; private final ListenersManager listenersManager;
private final Logger logger; private final Logger logger;
private final GiftsManager giftsManager; private final GiftsManager giftsManager;
private final TikTokLiveMessageHandler messageHandler; private final TikTokLiveMessageHandler messageHandler;
@@ -62,7 +64,7 @@ public class TikTokLiveClient implements LiveClient {
SocketClient webSocketClient, SocketClient webSocketClient,
TikTokLiveEventHandler tikTokEventHandler, TikTokLiveEventHandler tikTokEventHandler,
LiveClientSettings clientSettings, LiveClientSettings clientSettings,
TikTokListenersManager listenersManager, ListenersManager listenersManager,
Logger logger) { Logger logger) {
this.messageHandler = messageHandler; this.messageHandler = messageHandler;
this.giftsManager = giftsManager; this.giftsManager = giftsManager;

View File

@@ -22,6 +22,9 @@
*/ */
package io.github.jwdeveloper.tiktok; package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.dependance.Dependance;
import io.github.jwdeveloper.dependance.api.DependanceContainer;
import io.github.jwdeveloper.tiktok.mappers.MessagesMapperFactory;
import io.github.jwdeveloper.tiktok.common.LoggerFactory; import io.github.jwdeveloper.tiktok.common.LoggerFactory;
import io.github.jwdeveloper.tiktok.data.events.*; import io.github.jwdeveloper.tiktok.data.events.*;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
@@ -38,13 +41,15 @@ import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException; import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager; import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
import io.github.jwdeveloper.tiktok.http.HttpClientFactory; import io.github.jwdeveloper.tiktok.http.HttpClientFactory;
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
import io.github.jwdeveloper.tiktok.listener.*; import io.github.jwdeveloper.tiktok.listener.*;
import io.github.jwdeveloper.tiktok.live.*; import io.github.jwdeveloper.tiktok.live.*;
import io.github.jwdeveloper.tiktok.live.builder.*; import io.github.jwdeveloper.tiktok.live.builder.*;
import io.github.jwdeveloper.tiktok.mappers.*; import io.github.jwdeveloper.tiktok.mappers.*;
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult; import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokCommonEventHandler;
import io.github.jwdeveloper.tiktok.mappers.handlers.*; import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokGiftEventHandler;
import io.github.jwdeveloper.tiktok.messages.webcast.*; import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokRoomInfoEventHandler;
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokSocialMediaEventHandler;
import io.github.jwdeveloper.tiktok.websocket.*; import io.github.jwdeveloper.tiktok.websocket.*;
import java.util.*; import java.util.*;
@@ -52,28 +57,23 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.logging.Logger; import java.util.logging.Logger;
import static io.github.jwdeveloper.tiktok.messages.enums.LinkMessageType.*;
public class TikTokLiveClientBuilder implements LiveClientBuilder { public class TikTokLiveClientBuilder implements LiveClientBuilder {
protected final LiveClientSettings clientSettings; protected final LiveClientSettings clientSettings;
protected final TikTokLiveEventHandler eventHandler; protected final TikTokLiveEventHandler eventHandler;
protected final List<TikTokEventListener> listeners; protected final List<TikTokEventListener> listeners;
protected Consumer<TikTokMapper> onCustomMappings; protected final List<Consumer<TikTokMapper>> onCustomMappings;
protected Logger logger;
protected GiftsManager giftsManager;
public TikTokLiveClientBuilder(String userName) { public TikTokLiveClientBuilder(String userName) {
this.clientSettings = LiveClientSettings.createDefault(); this.clientSettings = LiveClientSettings.createDefault();
this.clientSettings.setHostName(userName); this.clientSettings.setHostName(userName);
this.eventHandler = new TikTokLiveEventHandler(); this.eventHandler = new TikTokLiveEventHandler();
this.listeners = new ArrayList<>(); this.listeners = new ArrayList<>();
this.onCustomMappings = (e) -> { this.onCustomMappings = new ArrayList<>();
};
} }
public LiveClientBuilder onMapping(Consumer<TikTokMapper> onCustomMappings) { public LiveClientBuilder onMapping(Consumer<TikTokMapper> consumer) {
this.onCustomMappings = onCustomMappings; this.onCustomMappings.add(consumer);
return this; return this;
} }
@@ -104,169 +104,74 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
var httpSettings = clientSettings.getHttpSettings(); var httpSettings = clientSettings.getHttpSettings();
httpSettings.getParams().put("app_language", clientSettings.getClientLanguage()); httpSettings.getParams().put("app_language", clientSettings.getClientLanguage());
httpSettings.getParams().put("webcast_language", clientSettings.getClientLanguage()); httpSettings.getParams().put("webcast_language", clientSettings.getClientLanguage());
this.logger = LoggerFactory.create(clientSettings.getHostName(), clientSettings);
this.giftsManager = clientSettings.isFetchGifts() ? TikTokLive.gifts() : new TikTokGiftsManager(List.of());
} }
//TODO each class registered to container should implement own interface,
public LiveClient build() { public LiveClient build() {
validate(); validate();
var tiktokRoomInfo = new TikTokRoomInfo(); var dependance = Dependance.newContainer();
tiktokRoomInfo.setHostName(clientSettings.getHostName());
var listenerManager = new TikTokListenersManager(listeners, eventHandler); //config
dependance.registerSingleton(LiveClientSettings.class, clientSettings);
dependance.registerSingleton(TikTokRoomInfo.class, container ->
{
var roomInfo = new TikTokRoomInfo();
roomInfo.setHostName(clientSettings.getHostName());
return roomInfo;
});
dependance.registerSingleton(Logger.class, LoggerFactory.create(clientSettings.getHostName(), clientSettings));
var httpClientFactory = new HttpClientFactory(clientSettings); //messages
dependance.registerSingleton(TikTokLiveEventHandler.class, eventHandler);
dependance.registerSingleton(TikTokLiveMessageHandler.class);
dependance.registerSingleton(TikTokLiveMapper.class, (container) ->
{
var dependace = (DependanceContainer) container.find(DependanceContainer.class);
var mapper = MessagesMapperFactory.create(dependace);
onCustomMappings.forEach(action -> action.accept(mapper));
return mapper;
});
var liveHttpClient = clientSettings.isOffline() ? //listeners
new TikTokLiveHttpOfflineClient() : dependance.registerSingletonList(TikTokEventListener.class, (e) -> listeners);
new TikTokLiveHttpClient(httpClientFactory, clientSettings); dependance.registerSingleton(ListenersManager.class, TikTokListenersManager.class);
var eventsMapper = createMapper(giftsManager, tiktokRoomInfo); //networking
var messageHandler = new TikTokLiveMessageHandler(eventHandler, eventsMapper); dependance.registerSingleton(HttpClientFactory.class);
if (clientSettings.isOffline()) {
dependance.registerSingleton(SocketClient.class, TikTokWebSocketOfflineClient.class);
dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpOfflineClient.class);
} else {
dependance.registerSingleton(SocketClient.class, TikTokWebSocketClient.class);
dependance.registerSingleton(LiveHttpClient.class, TikTokLiveHttpClient.class);
}
var webSocketClient = clientSettings.isOffline() ? //gifts
new TikTokWebSocketOfflineClient(eventHandler) : if (clientSettings.isFetchGifts()) {
new TikTokWebSocketClient( dependance.registerSingleton(GiftsManager.class, TikTokLive.gifts());
clientSettings, } else {
messageHandler, dependance.registerSingleton(GiftsManager.class, new TikTokGiftsManager(List.of()));
eventHandler); }
return new TikTokLiveClient( //mapper
messageHandler, dependance.registerSingleton(TikTokGenericEventMapper.class);
giftsManager, dependance.registerSingleton(TikTokMapperHelper.class, TikTokLiveMapperHelper.class);
tiktokRoomInfo, dependance.registerSingleton(TikTokLiveMapper.class);
liveHttpClient,
webSocketClient, //mapper handlers
eventHandler, dependance.registerSingleton(TikTokCommonEventHandler.class);
clientSettings, dependance.registerSingleton(TikTokGiftEventHandler.class);
listenerManager, dependance.registerSingleton(TikTokRoomInfoEventHandler.class);
logger); dependance.registerSingleton(TikTokSocialMediaEventHandler.class);
//client
dependance.registerSingleton(LiveClient.class, TikTokLiveClient.class);
var container = dependance.build();
return container.find(LiveClient.class);
} }
public TikTokLiveMapper createMapper(GiftsManager giftsManager, TikTokRoomInfo roomInfo) {
var eventMapper = new TikTokGenericEventMapper();
var mapper = new TikTokLiveMapper(new TikTokLiveMapperHelper(eventMapper));
//ConnectionEvents events
var commonHandler = new TikTokCommonEventHandler();
var giftHandler = new TikTokGiftEventHandler(giftsManager, roomInfo);
var roomInfoHandler = new TikTokRoomInfoEventHandler(roomInfo);
var socialHandler = new TikTokSocialMediaEventHandler(roomInfo);
mapper.forMessage(WebcastControlMessage.class, commonHandler::handleWebcastControlMessage);
//Room status events
mapper.forMessage(WebcastLiveIntroMessage.class, roomInfoHandler::handleIntro);
mapper.forMessage(WebcastRoomUserSeqMessage.class, roomInfoHandler::handleUserRanking);
mapper.forMessage(WebcastCaptionMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastCaptionMessage.class);
return MappingResult.of(messageObject, new TikTokCaptionEvent(messageObject));
});
//User Interactions events
mapper.forMessage(WebcastChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
return MappingResult.of(messageObject, new TikTokCommentEvent(messageObject));
});
mapper.forMessage(WebcastSubNotifyMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastSubNotifyMessage.class);
return MappingResult.of(messageObject, new TikTokSubscribeEvent(messageObject));
});
mapper.forMessage(WebcastEmoteChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastEmoteChatMessage.class);
return MappingResult.of(messageObject, new TikTokEmoteEvent(messageObject));
});
mapper.forMessage(WebcastQuestionNewMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastQuestionNewMessage.class);
return MappingResult.of(messageObject, new TikTokQuestionEvent(messageObject));
});
mapper.forMessage(WebcastLikeMessage.class, roomInfoHandler::handleLike);
mapper.forMessage(WebcastGiftMessage.class, giftHandler::handleGifts);
mapper.forMessage(WebcastSocialMessage.class, socialHandler::handle);
mapper.forMessage(WebcastMemberMessage.class, roomInfoHandler::handleMemberMessage);
//Host Interaction events
mapper.forMessage(WebcastPollMessage.class, commonHandler::handlePollEvent);
mapper.forMessage(WebcastRoomPinMessage.class, commonHandler::handlePinMessage);
mapper.forMessage(WebcastChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
return MappingResult.of(messageObject, new TikTokCommentEvent(messageObject));
});
//LinkMic events
mapper.forMessage(WebcastLinkMicBattle.class, (inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicBattle.class);
return MappingResult.of(message, new TikTokLinkMicBattleEvent(message));
});
mapper.forMessage(WebcastLinkMicArmies.class, (inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicArmies.class);
return MappingResult.of(message, new TikTokLinkMicArmiesEvent(message));
});
mapper.forMessage(WebcastLinkMessage.class, ((inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMessage.class);
return MappingResult.of(message, switch (message.getMessageType()) {
case TYPE_LINKER_INVITE -> new TikTokLinkInviteEvent(message);
case TYPE_LINKER_REPLY -> new TikTokLinkReplyEvent(message);
case TYPE_LINKER_CREATE -> new TikTokLinkCreateEvent(message);
case TYPE_LINKER_CLOSE -> new TikTokLinkCloseEvent(message);
case TYPE_LINKER_ENTER -> new TikTokLinkEnterEvent(message);
case TYPE_LINKER_LEAVE -> new TikTokLinkLeaveEvent(message);
case TYPE_LINKER_CANCEL_INVITE, TYPE_LINKER_CANCEL_APPLY -> new TikTokLinkCancelEvent(message);
case TYPE_LINKER_KICK_OUT -> new TikTokLinkKickOutEvent(message);
case TYPE_LINKER_LINKED_LIST_CHANGE -> new TikTokLinkLinkedListChangeEvent(message);
case TYPE_LINKER_UPDATE_USER -> new TikTokLinkUpdateUserEvent(message);
case TYPE_LINKER_WAITING_LIST_CHANGE, TYPE_LINKER_WAITING_LIST_CHANGE_V2 -> new TikTokLinkWaitListChangeEvent(message);
case TYPE_LINKER_MUTE -> new TikTokLinkMuteEvent(message);
case TYPE_LINKER_MATCH -> new TikTokLinkRandomMatchEvent(message);
case TYPE_LINKER_UPDATE_USER_SETTING -> new TikTokLinkUpdateUserSettingEvent(message);
case TYPE_LINKER_MIC_IDX_UPDATE -> new TikTokLinkMicIdxUpdateEvent(message);
case TYPE_LINKER_LINKED_LIST_CHANGE_V2 -> new TikTokLinkListChangeEvent(message);
case TYPE_LINKER_COHOST_LIST_CHANGE -> new TikTokLinkCohostListChangeEvent(message);
case TYPE_LINKER_MEDIA_CHANGE -> new TikTokLinkMediaChangeEvent(message);
case TYPE_LINKER_ACCEPT_NOTICE -> new TikTokLinkAcceptNoticeEvent(message);
case TYPE_LINKER_SYS_KICK_OUT -> new TikTokLinkSysKickOutEvent(message);
case TYPE_LINKMIC_USER_TOAST -> new TikTokLinkUserToastEvent(message);
default -> new TikTokLinkEvent(message);
});
}));
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
//Rank events
// mapper.webcastObjectToConstructor(WebcastRankTextMessage.class, TikTokRankTextEvent.class);
// mapper.webcastObjectToConstructor(WebcastRankUpdateMessage.class, TikTokRankUpdateEvent.class);
// mapper.webcastObjectToConstructor(WebcastHourlyRankMessage.class, TikTokRankUpdateEvent.class);
//Others events
// mapper.webcastObjectToConstructor(WebcastInRoomBannerMessage.class, TikTokInRoomBannerEvent.class);
// mapper.webcastObjectToConstructor(WebcastMsgDetectMessage.class, TikTokDetectEvent.class);
// mapper.webcastObjectToConstructor(WebcastBarrageMessage.class, TikTokBarrageEvent.class);
// mapper.webcastObjectToConstructor(WebcastUnauthorizedMemberMessage.class, TikTokUnauthorizedMemberEvent.class);
// mapper.webcastObjectToConstructor(WebcastOecLiveShoppingMessage.class, TikTokShopEvent.class);
// mapper.webcastObjectToConstructor(WebcastImDeleteMessage.class, TikTokIMDeleteEvent.class);
// mapper.bytesToEvents(WebcastEnvelopeMessage.class, commonHandler::handleEnvelop);
onCustomMappings.accept(mapper);
return mapper;
}
public LiveClient buildAndConnect() { public LiveClient buildAndConnect() {
var client = build(); var client = build();
client.connect(); client.connect();
@@ -277,6 +182,11 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
return build().connectAsync(); return build().connectAsync();
} }
/**
* To do figure out how to use Annotation processor can could dynamically
* like Lombok generates methods for all possible events, everytime library
* is compiled
*/
public TikTokLiveClientBuilder onUnhandledSocial(EventConsumer<TikTokUnhandledSocialEvent> event) { public TikTokLiveClientBuilder onUnhandledSocial(EventConsumer<TikTokUnhandledSocialEvent> event) {
eventHandler.subscribe(TikTokUnhandledSocialEvent.class, event); eventHandler.subscribe(TikTokUnhandledSocialEvent.class, event);
return this; return this;

View File

@@ -41,19 +41,14 @@ public class TikTokLiveEventHandler {
public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) { public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) {
if (events.containsKey(TikTokEvent.class)) { if (events.containsKey(TikTokEvent.class)) {
var handlers = events.get(TikTokEvent.class); var handlers = events.get(TikTokEvent.class);
for (var handle : handlers) { handlers.forEach(handler -> handler.onEvent(tikTokLiveClient,tikTokEvent));
handle.onEvent(tikTokLiveClient, tikTokEvent);
}
} }
if (!events.containsKey(tikTokEvent.getClass())) { if (!events.containsKey(tikTokEvent.getClass())) {
return; return;
} }
var handlers = events.get(tikTokEvent.getClass()); var handlers = events.get(tikTokEvent.getClass());
for (var handler : handlers) { handlers.forEach(handler -> handler.onEvent(tikTokLiveClient,tikTokEvent));
handler.onEvent(tikTokLiveClient, tikTokEvent);
}
} }
public <T extends TikTokEvent> void subscribe(Class<?> clazz, EventConsumer<T> event) { public <T extends TikTokEvent> void subscribe(Class<?> clazz, EventConsumer<T> event) {
@@ -81,6 +76,5 @@ public class TikTokLiveEventHandler {
var eventSet = events.get(clazz); var eventSet = events.get(clazz);
eventSet.remove(consumer); eventSet.remove(consumer);
} }
} }

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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; package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.data.models.Picture; import io.github.jwdeveloper.tiktok.data.models.Picture;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.common; package io.github.jwdeveloper.tiktok.common;
import com.google.gson.*; import com.google.gson.*;
@@ -100,8 +122,8 @@ public class ActionResult<T> {
public JsonObject toJson() { public JsonObject toJson() {
JsonObject map = new JsonObject(); JsonObject map = new JsonObject();
map.addProperty("success", success); map.addProperty("success", success);
map.add("content", gson.toJsonTree(content));
map.addProperty("message", message); map.addProperty("message", message);
map.add("content", gson.toJsonTree(content));
map.add("previous", hasPrevious() ? previous.toJson() : null); map.add("previous", hasPrevious() ? previous.toJson() : null);
return map; return map;
} }

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.common; package io.github.jwdeveloper.tiktok.common;
import lombok.Setter; import lombok.Setter;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.common; package io.github.jwdeveloper.tiktok.common;
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings; import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.gifts; package io.github.jwdeveloper.tiktok.gifts;
import io.github.jwdeveloper.tiktok.data.models.gifts.Gift; import io.github.jwdeveloper.tiktok.data.models.gifts.Gift;
@@ -7,6 +29,7 @@ import java.util.*;
import java.util.function.*; import java.util.function.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//TODO I should've been called it TikTokGiftsRepository
public class TikTokGiftsManager implements GiftsManager { public class TikTokGiftsManager implements GiftsManager {
private final Map<Integer, Gift> giftsByIdIndex; private final Map<Integer, Gift> giftsByIdIndex;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.http.mappers; package io.github.jwdeveloper.tiktok.http.mappers;
import com.google.gson.*; import com.google.gson.*;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.http.mappers; package io.github.jwdeveloper.tiktok.http.mappers;
import com.google.gson.*; import com.google.gson.*;

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.mappers;
import io.github.jwdeveloper.dependance.api.DependanceContainer;
import io.github.jwdeveloper.dependance.injector.api.containers.Container;
import io.github.jwdeveloper.tiktok.TikTokRoomInfo;
import io.github.jwdeveloper.tiktok.data.events.*;
import io.github.jwdeveloper.tiktok.data.events.link.*;
import io.github.jwdeveloper.tiktok.live.GiftsManager;
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokCommonEventHandler;
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokGiftEventHandler;
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokRoomInfoEventHandler;
import io.github.jwdeveloper.tiktok.mappers.handlers.TikTokSocialMediaEventHandler;
import io.github.jwdeveloper.tiktok.messages.webcast.*;
import static io.github.jwdeveloper.tiktok.messages.enums.LinkMessageType.*;
public class MessagesMapperFactory {
public static TikTokLiveMapper create(DependanceContainer container) {
var mapper = container.find(TikTokLiveMapper.class);
//ConnectionEvents events
var commonHandler = container.find(TikTokCommonEventHandler.class);
var giftHandler = container.find(TikTokGiftEventHandler.class);
var roomInfoHandler = container.find(TikTokRoomInfoEventHandler.class);
var socialHandler = container.find(TikTokSocialMediaEventHandler.class);
mapper.forMessage(WebcastControlMessage.class, commonHandler::handleWebcastControlMessage);
//Room status events
mapper.forMessage(WebcastLiveIntroMessage.class, roomInfoHandler::handleIntro);
mapper.forMessage(WebcastRoomUserSeqMessage.class, roomInfoHandler::handleUserRanking);
mapper.forMessage(WebcastCaptionMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastCaptionMessage.class);
return MappingResult.of(messageObject, new TikTokCaptionEvent(messageObject));
});
//User Interactions events
mapper.forMessage(WebcastChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
return MappingResult.of(messageObject, new TikTokCommentEvent(messageObject));
});
mapper.forMessage(WebcastSubNotifyMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastSubNotifyMessage.class);
return MappingResult.of(messageObject, new TikTokSubscribeEvent(messageObject));
});
mapper.forMessage(WebcastEmoteChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastEmoteChatMessage.class);
return MappingResult.of(messageObject, new TikTokEmoteEvent(messageObject));
});
mapper.forMessage(WebcastQuestionNewMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastQuestionNewMessage.class);
return MappingResult.of(messageObject, new TikTokQuestionEvent(messageObject));
});
mapper.forMessage(WebcastLikeMessage.class, roomInfoHandler::handleLike);
mapper.forMessage(WebcastGiftMessage.class, giftHandler::handleGifts);
mapper.forMessage(WebcastSocialMessage.class, socialHandler::handle);
mapper.forMessage(WebcastMemberMessage.class, roomInfoHandler::handleMemberMessage);
//Host Interaction events
mapper.forMessage(WebcastPollMessage.class, commonHandler::handlePollEvent);
mapper.forMessage(WebcastRoomPinMessage.class, commonHandler::handlePinMessage);
mapper.forMessage(WebcastChatMessage.class, (inputBytes, messageName, mapperHelper) ->
{
var messageObject = mapperHelper.bytesToWebcastObject(inputBytes, WebcastChatMessage.class);
return MappingResult.of(messageObject, new TikTokCommentEvent(messageObject));
});
//LinkMic events
mapper.forMessage(WebcastLinkMicBattle.class, (inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicBattle.class);
return MappingResult.of(message, new TikTokLinkMicBattleEvent(message));
});
mapper.forMessage(WebcastLinkMicArmies.class, (inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMicArmies.class);
return MappingResult.of(message, new TikTokLinkMicArmiesEvent(message));
});
mapper.forMessage(WebcastLinkMessage.class, ((inputBytes, messageName, mapperHelper) -> {
var message = mapperHelper.bytesToWebcastObject(inputBytes, WebcastLinkMessage.class);
return MappingResult.of(message, switch (message.getMessageType()) {
case TYPE_LINKER_INVITE -> new TikTokLinkInviteEvent(message);
case TYPE_LINKER_CREATE -> new TikTokLinkCreateEvent(message);
case TYPE_LINKER_CLOSE -> new TikTokLinkCloseEvent(message);
case TYPE_LINKER_ENTER -> new TikTokLinkEnterEvent(message);
case TYPE_LINKER_LEAVE -> new TikTokLinkLeaveEvent(message);
case TYPE_LINKER_CANCEL_INVITE, TYPE_LINKER_CANCEL_APPLY -> new TikTokLinkCancelEvent(message);
case TYPE_LINKER_KICK_OUT -> new TikTokLinkKickOutEvent(message);
case TYPE_LINKER_LINKED_LIST_CHANGE -> new TikTokLinkLinkedListChangeEvent(message);
case TYPE_LINKER_UPDATE_USER -> new TikTokLinkUpdateUserEvent(message);
case TYPE_LINKER_WAITING_LIST_CHANGE, TYPE_LINKER_WAITING_LIST_CHANGE_V2 ->
new TikTokLinkWaitListChangeEvent(message);
case TYPE_LINKER_MUTE -> new TikTokLinkMuteEvent(message);
case TYPE_LINKER_MATCH -> new TikTokLinkRandomMatchEvent(message);
case TYPE_LINKER_UPDATE_USER_SETTING -> new TikTokLinkUpdateUserSettingEvent(message);
case TYPE_LINKER_MIC_IDX_UPDATE -> new TikTokLinkMicIdxUpdateEvent(message);
case TYPE_LINKER_LINKED_LIST_CHANGE_V2 -> new TikTokLinkListChangeEvent(message);
case TYPE_LINKER_COHOST_LIST_CHANGE -> new TikTokLinkCohostListChangeEvent(message);
case TYPE_LINKER_MEDIA_CHANGE -> new TikTokLinkMediaChangeEvent(message);
case TYPE_LINKER_ACCEPT_NOTICE -> new TikTokLinkAcceptNoticeEvent(message);
case TYPE_LINKER_SYS_KICK_OUT -> new TikTokLinkSysKickOutEvent(message);
case TYPE_LINKMIC_USER_TOAST -> new TikTokLinkUserToastEvent(message);
default -> new TikTokLinkEvent(message);
});
}));
// mapper.webcastObjectToConstructor(WebcastLinkMicMethod.class, TikTokLinkMicMethodEvent.class);
// mapper.webcastObjectToConstructor(WebcastLinkMicFanTicketMethod.class, TikTokLinkMicFanTicketEvent.class);
//Rank events
// mapper.webcastObjectToConstructor(WebcastRankTextMessage.class, TikTokRankTextEvent.class);
// mapper.webcastObjectToConstructor(WebcastRankUpdateMessage.class, TikTokRankUpdateEvent.class);
// mapper.webcastObjectToConstructor(WebcastHourlyRankMessage.class, TikTokRankUpdateEvent.class);
//Others events
// mapper.webcastObjectToConstructor(WebcastInRoomBannerMessage.class, TikTokInRoomBannerEvent.class);
// mapper.webcastObjectToConstructor(WebcastMsgDetectMessage.class, TikTokDetectEvent.class);
// mapper.webcastObjectToConstructor(WebcastBarrageMessage.class, TikTokBarrageEvent.class);
// mapper.webcastObjectToConstructor(WebcastUnauthorizedMemberMessage.class, TikTokUnauthorizedMemberEvent.class);
// mapper.webcastObjectToConstructor(WebcastOecLiveShoppingMessage.class, TikTokShopEvent.class);
// mapper.webcastObjectToConstructor(WebcastImDeleteMessage.class, TikTokIMDeleteEvent.class);
// mapper.bytesToEvents(WebcastEnvelopeMessage.class, commonHandler::handleEnvelop);
return mapper;
}
}

View File

@@ -75,5 +75,4 @@ public class TikTokLiveMapperModel implements TikTokMapperModel {
return this; return this;
} }
} }

View File

@@ -1,26 +0,0 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.mappers.handlers;
public class TikTokChestEventHandler {
}

View File

@@ -22,6 +22,7 @@
*/ */
package io.github.jwdeveloper.tiktok.websocket; package io.github.jwdeveloper.tiktok.websocket;
import io.github.jwdeveloper.dependance.injector.api.containers.Container;
import io.github.jwdeveloper.tiktok.*; import io.github.jwdeveloper.tiktok.*;
import io.github.jwdeveloper.tiktok.data.dto.ProxyData; import io.github.jwdeveloper.tiktok.data.dto.ProxyData;
import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData; import io.github.jwdeveloper.tiktok.data.requests.LiveConnectionData;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.websocket; package io.github.jwdeveloper.tiktok.websocket;
import io.github.jwdeveloper.tiktok.TikTokLiveEventHandler; import io.github.jwdeveloper.tiktok.TikTokLiveEventHandler;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.websocket; package io.github.jwdeveloper.tiktok.websocket;
import org.java_websocket.WebSocket; import org.java_websocket.WebSocket;
@@ -15,6 +37,7 @@ public class TikTokWebSocketPingingTask
{ {
stop(); stop();
thread = new Thread(() -> pingTask(webSocket, pingTaskTime)); thread = new Thread(() -> pingTask(webSocket, pingTaskTime));
thread.setName("pinging-task");
isRunning = true; isRunning = true;
thread.start(); thread.start();
} }
@@ -40,6 +63,7 @@ public class TikTokWebSocketPingingTask
Thread.sleep(pingTaskTime+random.nextInt(MAX_TIMEOUT)); Thread.sleep(pingTaskTime+random.nextInt(MAX_TIMEOUT));
} }
catch (Exception e) { catch (Exception e) {
//TODO we should display some kind of error message
isRunning = false; isRunning = false;
} }
} }

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -75,7 +75,7 @@
<dependency> <dependency>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>extension-collector</artifactId> <artifactId>extension-collector</artifactId>
<version>1.6.4-Release</version> <version>${project.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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; package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent; import io.github.jwdeveloper.tiktok.data.events.TikTokCommentEvent;

View File

@@ -26,6 +26,8 @@ package io.github.jwdeveloper.tiktok;
import io.github.jwdeveloper.tiktok.extension.recorder.TikTokLiveRecorder; import io.github.jwdeveloper.tiktok.extension.recorder.TikTokLiveRecorder;
import io.github.jwdeveloper.tiktok.extension.recorder.impl.event.TikTokLiveRecorderStartedEvent; import io.github.jwdeveloper.tiktok.extension.recorder.impl.event.TikTokLiveRecorderStartedEvent;
import java.io.File;
public class RecorderExample { public class RecorderExample {
public static void main(String[] args) { public static void main(String[] args) {
@@ -39,11 +41,10 @@ public class RecorderExample {
{ {
event.getException().printStackTrace(); event.getException().printStackTrace();
}) })
.addListener(TikTokLiveRecorder.use(recorderSettings -> .addListener(TikTokLiveRecorder.use((recorderSettings, liveClient) ->
{ {
recorderSettings.setFfmpegPath("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\extension-recorder\\libs\\ffmpeg.exe"); recorderSettings.setFfmpegPath("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\extension-recorder\\libs\\ffmpeg.exe");
recorderSettings.setOutputPath("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\extension-recorder\\out"); recorderSettings.setOutputFile(new File("C:\\Users\\ja\\IdeaProjects\\TikTokLiveJava\\extension-recorder\\out", "test.flv"));
recorderSettings.setOutputFileName("test.flv");
})) }))
.onEvent(TikTokLiveRecorderStartedEvent.class, (liveClient, event) -> .onEvent(TikTokLiveRecorderStartedEvent.class, (liveClient, event) ->
{ {
@@ -52,4 +53,4 @@ public class RecorderExample {
.buildAndConnect(); .buildAndConnect();
} }
} }

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
@@ -33,7 +33,7 @@
<dependency> <dependency>
<groupId>io.github.jwdeveloper.tiktok</groupId> <groupId>io.github.jwdeveloper.tiktok</groupId>
<artifactId>API</artifactId> <artifactId>API</artifactId>
<version>1.6.4-Release</version> <version>1.7.2-Release</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.api; package io.github.jwdeveloper.tiktok.extension.collector.api;
import io.github.jwdeveloper.tiktok.live.LiveClient; import io.github.jwdeveloper.tiktok.live.LiveClient;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.api; package io.github.jwdeveloper.tiktok.extension.collector.api;
import org.bson.Document; import org.bson.Document;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.api.settings; package io.github.jwdeveloper.tiktok.extension.collector.api.settings;
import io.github.jwdeveloper.tiktok.extension.collector.api.CollectorEvent; import io.github.jwdeveloper.tiktok.extension.collector.api.CollectorEvent;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.impl; package io.github.jwdeveloper.tiktok.extension.collector.impl;
import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver; import io.github.jwdeveloper.tiktok.annotations.TikTokEventObserver;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.impl.storages; package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
import io.github.jwdeveloper.tiktok.extension.collector.api.Storage; import io.github.jwdeveloper.tiktok.extension.collector.api.Storage;

View File

@@ -1,3 +1,25 @@
/*
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* 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.extension.collector.impl.storages; package io.github.jwdeveloper.tiktok.extension.collector.impl.storages;
import com.mongodb.ConnectionString; import com.mongodb.ConnectionString;

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>extension-recorder</artifactId> <artifactId>extension-recorder</artifactId>

View File

@@ -25,18 +25,19 @@ package io.github.jwdeveloper.tiktok.extension.recorder;
import io.github.jwdeveloper.tiktok.extension.recorder.api.LiveRecorder; import io.github.jwdeveloper.tiktok.extension.recorder.api.LiveRecorder;
import io.github.jwdeveloper.tiktok.extension.recorder.impl.RecorderListener; import io.github.jwdeveloper.tiktok.extension.recorder.impl.RecorderListener;
import io.github.jwdeveloper.tiktok.extension.recorder.impl.data.RecorderSettings; import io.github.jwdeveloper.tiktok.extension.recorder.impl.data.RecorderSettings;
import io.github.jwdeveloper.tiktok.live.LiveClient;
import java.util.function.Consumer; import java.util.function.*;
public class TikTokLiveRecorder public class TikTokLiveRecorder
{ {
public static LiveRecorder use(Consumer<RecorderSettings> consumer) public static LiveRecorder use(BiConsumer<RecorderSettings, LiveClient> consumer)
{ {
return new RecorderListener(consumer); return new RecorderListener(consumer);
} }
public static LiveRecorder use() public static LiveRecorder use()
{ {
return use(x ->{}); return use((x,y) ->{});
} }
} }

View File

@@ -37,26 +37,23 @@ import io.github.jwdeveloper.tiktok.models.ConnectionState;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.util.concurrent.TimeUnit; import java.util.function.*;
import java.util.function.Consumer;
import static java.nio.charset.StandardCharsets.UTF_8;
public class RecorderListener implements LiveRecorder { public class RecorderListener implements LiveRecorder {
private final Consumer<RecorderSettings> consumer; private final BiConsumer<RecorderSettings, LiveClient> consumer;
private RecorderSettings settings; private RecorderSettings settings;
private DownloadData downloadData; private DownloadData downloadData;
private Thread liveDownloadThread; private Thread liveDownloadThread;
public RecorderListener(Consumer<RecorderSettings> consumer) { public RecorderListener(BiConsumer<RecorderSettings, LiveClient> consumer) {
this.consumer = consumer; this.consumer = consumer;
} }
@TikTokEventObserver @TikTokEventObserver
private void onResponse(LiveClient liveClient, TikTokRoomDataResponseEvent event) { private void onResponse(LiveClient liveClient, TikTokRoomDataResponseEvent event) {
settings = RecorderSettings.DEFAULT(); settings = RecorderSettings.DEFAULT();
consumer.accept(settings); consumer.accept(settings, liveClient);
var json = event.getLiveData().getJson(); var json = event.getLiveData().getJson();
@@ -76,10 +73,9 @@ public class RecorderListener implements LiveRecorder {
if (isConnected()) if (isConnected())
return; return;
liveDownloadThread = new Thread(() -> { liveDownloadThread = new Thread(() -> {
try { try {
liveClient.getLogger().info("Recording started"); liveClient.getLogger().info("Recording started "+liveClient.getRoomInfo().getHostName());
var url = new URL(downloadData.getFullUrl()); var url = new URL(downloadData.getFullUrl());
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
var headers = LiveClientSettings.DefaultRequestHeaders(); var headers = LiveClientSettings.DefaultRequestHeaders();
@@ -87,18 +83,17 @@ public class RecorderListener implements LiveRecorder {
connection.setRequestProperty(entry.getKey(), entry.getValue()); connection.setRequestProperty(entry.getKey(), entry.getValue());
} }
var path = settings.getOutputPath() + File.separator + settings.getOutputFileName(); var file = settings.getOutputFile();
var file = new File(path);
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
file.createNewFile(); file.createNewFile();
try ( try (
var in = connection.getInputStream(); var in = connection.getInputStream();
var fos = new FileOutputStream(file) var fos = new FileOutputStream(file)
) { ) {
byte[] dataBuffer = new byte[1024]; byte[] dataBuffer = new byte[1024];
int bytesRead; int bytesRead;
while (liveClient.getRoomInfo().getConnectionState() == ConnectionState.CONNECTED && (bytesRead = in.read(dataBuffer)) != -1) { while ((!settings.isStopOnDisconnect() || liveClient.getRoomInfo().getConnectionState() == ConnectionState.CONNECTED) && (bytesRead = in.read(dataBuffer)) != -1) {
fos.write(dataBuffer, 0, bytesRead); fos.write(dataBuffer, 0, bytesRead);
fos.flush(); fos.flush();
} }
@@ -113,11 +108,10 @@ public class RecorderListener implements LiveRecorder {
var recordingStartedEvent = new TikTokLiveRecorderStartedEvent(downloadData); var recordingStartedEvent = new TikTokLiveRecorderStartedEvent(downloadData);
liveClient.publishEvent(recordingStartedEvent); liveClient.publishEvent(recordingStartedEvent);
if (recordingStartedEvent.isCanceled()) { if (recordingStartedEvent.isCanceled())
liveClient.getLogger().info("Recording cancelled"); liveClient.getLogger().info("Recording cancelled");
return; else
} liveDownloadThread.start();
liveDownloadThread.start();
} }
@TikTokEventObserver @TikTokEventObserver

View File

@@ -27,6 +27,7 @@ import io.github.jwdeveloper.tiktok.extension.recorder.impl.enums.LiveFormat;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.io.File;
import java.util.function.Function; import java.util.function.Function;
@Getter @Getter
@@ -36,10 +37,8 @@ public class RecorderSettings {
private String ffmpegPath; private String ffmpegPath;
private String quality; private String quality;
private String format; private String format;
private String outputPath; private File outputFile;
private String outputFileName;
private Function<String,DownloadData> prepareDownloadData; private Function<String,DownloadData> prepareDownloadData;
private boolean startOnConnected;
private boolean stopOnDisconnect = true; private boolean stopOnDisconnect = true;
public static RecorderSettings DEFAULT() { public static RecorderSettings DEFAULT() {

View File

@@ -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.6.4-Release</version> <version>1.7.2-Release</version>
<modules> <modules>
<module>API</module> <module>API</module>
<module>Client</module> <module>Client</module>