mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-27 16:59:39 -05:00
Compare commits
21 Commits
1.6.4-Rele
...
develop-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1954a708c | ||
|
|
14317337e9 | ||
|
|
947c9c49a2 | ||
|
|
f2bd07377b | ||
|
|
3f268f3a1a | ||
|
|
55fcf83870 | ||
|
|
8d3828cca8 | ||
|
|
1c88491b8c | ||
|
|
47b050d0ba | ||
|
|
cfef082d3b | ||
|
|
34ddc74189 | ||
|
|
9a66d240bc | ||
|
|
d825803187 | ||
|
|
77c9cd6b52 | ||
|
|
0329d3cfeb | ||
|
|
26659bb37d | ||
|
|
0b9852c4d4 | ||
|
|
31618a16ba | ||
|
|
243791f6b8 | ||
|
|
4f74a0f1b7 | ||
|
|
d1eec34fca |
@@ -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.3-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>
|
||||||
|
|||||||
@@ -50,16 +50,12 @@ public class ProxyData
|
|||||||
|
|
||||||
return new ProxyData(address, port);
|
return new ProxyData(address, port);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new IllegalArgumentException("Port must be a valid integer!");
|
throw new IllegalArgumentException("Port must be a valid integer!", e);
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
throw new IllegalArgumentException("Address must be valid IPv4, IPv6, or domain name!");
|
throw new IllegalArgumentException("Address must be valid IPv4, IPv6, or domain name!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyData clone() {
|
|
||||||
return new ProxyData(address, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InetSocketAddress toSocketAddress() {
|
public InetSocketAddress toSocketAddress() {
|
||||||
return new InetSocketAddress(address, port);
|
return new InetSocketAddress(address, port);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -27,18 +27,23 @@ import lombok.*;
|
|||||||
public class LiveUserData {
|
public class LiveUserData {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
|
||||||
public static class Request {
|
public static class Request {
|
||||||
private String userName;
|
private final String userName;
|
||||||
|
|
||||||
|
public Request(String userName) {
|
||||||
|
if (userName == null || userName.isBlank())
|
||||||
|
throw new IllegalArgumentException("Invalid empty username!");
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class Response {
|
public static class Response {
|
||||||
private String json;
|
private final String json;
|
||||||
private UserStatus userStatus;
|
private final UserStatus userStatus;
|
||||||
private String roomId;
|
private final String roomId;
|
||||||
private long startedAtTimeStamp;
|
private final long startTime;
|
||||||
|
|
||||||
public boolean isLiveOnline() {
|
public boolean isLiveOnline() {
|
||||||
return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused;
|
return userStatus == LiveUserData.UserStatus.Live || userStatus == LiveUserData.UserStatus.LivePaused;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class HttpClientSettings {
|
|||||||
newSettings.getHeaders().putAll(new TreeMap<>(this.headers));
|
newSettings.getHeaders().putAll(new TreeMap<>(this.headers));
|
||||||
newSettings.getCookies().putAll(new TreeMap<>(this.cookies));
|
newSettings.getCookies().putAll(new TreeMap<>(this.cookies));
|
||||||
newSettings.getParams().putAll(new TreeMap<>(this.params));
|
newSettings.getParams().putAll(new TreeMap<>(this.params));
|
||||||
newSettings.proxyClientSettings = this.proxyClientSettings;
|
newSettings.setProxyClientSettings(this.proxyClientSettings);
|
||||||
|
|
||||||
return newSettings;
|
return newSettings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,17 +31,17 @@ 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;
|
||||||
private final List<ProxyData> proxyList = new ArrayList<>();
|
private final List<ProxyData> proxyList = new ArrayList<>();
|
||||||
private int index = -1;
|
private int index;
|
||||||
private Proxy.Type type = Proxy.Type.DIRECT;
|
private Proxy.Type type = Proxy.Type.DIRECT;
|
||||||
private Consumer<ProxyData> onProxyUpdated = x -> {};
|
private Consumer<ProxyData> onProxyUpdated = x -> {};
|
||||||
|
|
||||||
public boolean addProxy(String addressPort) {
|
public boolean addProxy(String addressPort) {
|
||||||
return proxyList.add(ProxyData.map(addressPort));
|
return addProxy(ProxyData.map(addressPort).toSocketAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addProxy(String address, int port) {
|
public boolean addProxy(String address, int port) {
|
||||||
@@ -57,33 +57,27 @@ public class ProxyClientSettings implements Iterator<ProxyData>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public synchronized boolean hasNext() {
|
||||||
return !proxyList.isEmpty();
|
return !proxyList.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProxyData next() {
|
public synchronized ProxyData next() {
|
||||||
var nextProxy = switch (rotation)
|
try {
|
||||||
{
|
var nextProxy = proxyList.get(index);
|
||||||
case CONSECUTIVE -> {
|
onProxyUpdated.accept(nextProxy);
|
||||||
index = (index+1) % proxyList.size();
|
return nextProxy;
|
||||||
yield proxyList.get(index).clone();
|
} finally {
|
||||||
|
switch (rotation) {
|
||||||
|
case CONSECUTIVE -> index = ++index % proxyList.size();
|
||||||
|
case RANDOM -> index = (int) (Math.random() * proxyList.size());
|
||||||
|
case NONE -> index = Math.max(index, 0);
|
||||||
}
|
}
|
||||||
case RANDOM -> {
|
}
|
||||||
index = new Random().nextInt(proxyList.size());
|
}
|
||||||
yield proxyList.get(index).clone();
|
|
||||||
}
|
|
||||||
case NONE -> {
|
|
||||||
index = Math.max(index, 0);
|
|
||||||
yield proxyList.get(index).clone();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
onProxyUpdated.accept(nextProxy);
|
|
||||||
return nextProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public synchronized void remove() {
|
||||||
proxyList.remove(index);
|
proxyList.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +91,8 @@ public class ProxyClientSettings implements Iterator<ProxyData>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyClientSettings clone()
|
@Override
|
||||||
{
|
public ProxyClientSettings clone() {
|
||||||
ProxyClientSettings settings = new ProxyClientSettings();
|
ProxyClientSettings settings = new ProxyClientSettings();
|
||||||
settings.setEnabled(enabled);
|
settings.setEnabled(enabled);
|
||||||
settings.setRotation(rotation);
|
settings.setRotation(rotation);
|
||||||
@@ -109,6 +103,27 @@ public class ProxyClientSettings implements Iterator<ProxyData>
|
|||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyClientSettings{" +
|
||||||
|
"enabled=" + enabled +
|
||||||
|
", autoDiscard=" + autoDiscard +
|
||||||
|
", fallback=" + fallback +
|
||||||
|
", rotation=" + rotation +
|
||||||
|
", proxyList=" + proxyList +
|
||||||
|
", index=" + index +
|
||||||
|
", type=" + type +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With {@code Iterable<ProxyData>} 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. */
|
||||||
|
|||||||
@@ -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.*;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -52,77 +52,70 @@ public interface EventsBuilder<T> {
|
|||||||
/**
|
/**
|
||||||
* Invoked whenever any event is triggered
|
* Invoked whenever any event is triggered
|
||||||
*
|
*
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onEvent(EventConsumer<TikTokEvent> action);
|
T onEvent(EventConsumer<TikTokEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when information about room (live) got updated such as viewer count, etc..
|
* Invoked when information about room (live) got updated such as viewer count, etc..
|
||||||
*
|
*
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onRoomInfo(EventConsumer<TikTokRoomInfoEvent> action);
|
T onRoomInfo(EventConsumer<TikTokRoomInfoEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when someone send message to chat
|
* Invoked when someone send message to chat
|
||||||
*
|
* @param action consumable action
|
||||||
* @param action
|
* @return self instance
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
T onComment(EventConsumer<TikTokCommentEvent> action);
|
T onComment(EventConsumer<TikTokCommentEvent> action);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when TikTokLiveJava makes http request and getting response
|
* Invoked when TikTokLiveJava makes http request and getting response
|
||||||
*
|
* @param action consumable action
|
||||||
* @param action
|
* @return self instance
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
T onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action);
|
T onHttpResponse(EventConsumer<TikTokHttpResponseEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when TikTok protocolBuffer data "message" was successfully mapped to event
|
* Invoked when TikTok protocolBuffer data "message" was successfully mapped to event
|
||||||
* events contains protocol-buffer "Message" and TikTokLiveJava "Event"
|
* events contains protocol-buffer "Message" and TikTokLiveJava "Event"
|
||||||
*
|
* @param action consumable action
|
||||||
* @param action
|
* @return self instance
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
T onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> action);
|
T onWebsocketMessage(EventConsumer<TikTokWebsocketMessageEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when there was not found event mapper for TikTok protocolBuffer data "message"
|
* Invoked when there was not found event mapper for TikTok protocolBuffer data "message"
|
||||||
*
|
* @param action consumable action
|
||||||
* @param action
|
* @return self instance
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> action);
|
T onWebsocketUnhandledMessage(EventConsumer<TikTokWebsocketUnhandledMessageEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked every time TikTok sends protocolBuffer data to websocket
|
* Invoked every time TikTok sends protocolBuffer data to websocket
|
||||||
* Response contains list of messages that are later mapped to events
|
* Response contains list of messages that are later mapped to events
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> action);
|
T onWebsocketResponse(EventConsumer<TikTokWebsocketResponseEvent> action);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked for gifts that has no combo, or when combo finishes
|
* Invoked for gifts that has no combo, or when combo finishes
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onGift(EventConsumer<TikTokGiftEvent> action);
|
T onGift(EventConsumer<TikTokGiftEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked for gifts that has combo options such as roses
|
* Invoked for gifts that has combo options such as roses
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action);
|
T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action);
|
||||||
|
|
||||||
|
|
||||||
T onQuestion(EventConsumer<TikTokQuestionEvent> action);
|
T onQuestion(EventConsumer<TikTokQuestionEvent> action);
|
||||||
|
|
||||||
T onSubscribe(EventConsumer<TikTokSubscribeEvent> action);
|
T onSubscribe(EventConsumer<TikTokSubscribeEvent> action);
|
||||||
@@ -145,36 +138,36 @@ public interface EventsBuilder<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when client has been successfully connected to live
|
* Invoked when client has been successfully connected to live
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onConnected(EventConsumer<TikTokConnectedEvent> action);
|
T onConnected(EventConsumer<TikTokConnectedEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked before client has been successfully connected to live
|
* Invoked before client has been successfully connected to live
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onPreConnection(EventConsumer<TikTokPreConnectionEvent> action);
|
T onPreConnection(EventConsumer<TikTokPreConnectionEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when client tries to reconnect
|
* Invoked when client tries to reconnect
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onReconnecting(EventConsumer<TikTokReconnectingEvent> action);
|
T onReconnecting(EventConsumer<TikTokReconnectingEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when client disconnected
|
* Invoked when client disconnected
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onDisconnected(EventConsumer<TikTokDisconnectedEvent> action);
|
T onDisconnected(EventConsumer<TikTokDisconnectedEvent> action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when exception was throed inside client or event handler
|
* Invoked when exception was throed inside client or event handler
|
||||||
* @param action
|
* @param action consumable action
|
||||||
* @return
|
* @return self instance
|
||||||
*/
|
*/
|
||||||
T onError(EventConsumer<TikTokErrorEvent> action);
|
T onError(EventConsumer<TikTokErrorEvent> action);
|
||||||
|
|
||||||
|
|||||||
@@ -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.3-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>
|
||||||
|
|||||||
@@ -23,19 +23,21 @@
|
|||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
|
|
||||||
|
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
||||||
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
import io.github.jwdeveloper.tiktok.gifts.TikTokGiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
import io.github.jwdeveloper.tiktok.http.LiveHttpClient;
|
||||||
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
import io.github.jwdeveloper.tiktok.live.GiftsManager;
|
||||||
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
import io.github.jwdeveloper.tiktok.live.builder.LiveClientBuilder;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class TikTokLive {
|
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 +47,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 +57,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 +67,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,20 +77,29 @@ 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) {
|
||||||
return CompletableFuture.supplyAsync(() -> isHostNameValid(hostName));
|
return CompletableFuture.supplyAsync(() -> isHostNameValid(hostName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use to get some data from TikTok about users are lives
|
||||||
|
*
|
||||||
|
* @return LiveHttpClient
|
||||||
|
*/
|
||||||
|
public static LiveHttpClient requests(Consumer<LiveClientSettings> consumer) {
|
||||||
|
return new TikTokLiveHttpClient(consumer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use to get some data from TikTok about users are lives
|
* Use to get some data from TikTok about users are lives
|
||||||
*
|
*
|
||||||
* @return LiveHttpClient
|
* @return LiveHttpClient
|
||||||
*/
|
*/
|
||||||
public static LiveHttpClient requests() {
|
public static LiveHttpClient requests() {
|
||||||
return new TikTokLiveHttpClient();
|
return requests(liveClientSettings -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GiftsManager giftsManager;
|
private static GiftsManager giftsManager;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -125,7 +127,7 @@ public class TikTokLiveClient implements LiveClient {
|
|||||||
tikTokEventHandler.publish(this, new TikTokConnectingEvent());
|
tikTokEventHandler.publish(this, new TikTokConnectingEvent());
|
||||||
var userDataRequest = new LiveUserData.Request(liveRoomInfo.getHostName());
|
var userDataRequest = new LiveUserData.Request(liveRoomInfo.getHostName());
|
||||||
var userData = httpClient.fetchLiveUserData(userDataRequest);
|
var userData = httpClient.fetchLiveUserData(userDataRequest);
|
||||||
liveRoomInfo.setStartTime(userData.getStartedAtTimeStamp());
|
liveRoomInfo.setStartTime(userData.getStartTime());
|
||||||
liveRoomInfo.setRoomId(userData.getRoomId());
|
liveRoomInfo.setRoomId(userData.getRoomId());
|
||||||
|
|
||||||
if (clientSettings.isFetchGifts())
|
if (clientSettings.isFetchGifts())
|
||||||
|
|||||||
@@ -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,81 @@ 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();
|
//Docs: https://github.com/jwdeveloper/DepenDance?tab=readme-ov-file#01-basic
|
||||||
tiktokRoomInfo.setHostName(clientSettings.getHostName());
|
var dependance = Dependance.newContainer();
|
||||||
|
|
||||||
var listenerManager = new TikTokListenersManager(listeners, eventHandler);
|
//config
|
||||||
|
dependance.registerSingleton(LiveClientSettings.class, clientSettings);
|
||||||
|
dependance.registerSingleton(Logger.class, LoggerFactory.create(clientSettings.getHostName(), clientSettings));
|
||||||
|
dependance.registerSingleton(TikTokRoomInfo.class, container ->
|
||||||
|
{
|
||||||
|
var roomInfo = new TikTokRoomInfo();
|
||||||
|
roomInfo.setHostName(clientSettings.getHostName());
|
||||||
|
return roomInfo;
|
||||||
|
});
|
||||||
|
|
||||||
var httpClientFactory = new HttpClientFactory(clientSettings);
|
//messages
|
||||||
|
dependance.registerSingleton(TikTokLiveEventHandler.class, eventHandler);
|
||||||
|
dependance.registerSingleton(TikTokLiveMessageHandler.class);
|
||||||
|
|
||||||
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() ?
|
/* TODO in future, custom proxy implementation that can be provided via builder
|
||||||
new TikTokWebSocketOfflineClient(eventHandler) :
|
* if(customProxy != null)
|
||||||
new TikTokWebSocketClient(
|
* dependance.registerSingleton(TikTokProxyProvider.class,customProxy);
|
||||||
clientSettings,
|
* else
|
||||||
messageHandler,
|
* dependance.registerSingleton(TikTokProxyProvider.class,DefaultProxyProvider.class);
|
||||||
eventHandler);
|
*/
|
||||||
|
|
||||||
return new TikTokLiveClient(
|
//gifts
|
||||||
messageHandler,
|
if (clientSettings.isFetchGifts()) {
|
||||||
giftsManager,
|
dependance.registerSingleton(GiftsManager.class, TikTokLive.gifts());
|
||||||
tiktokRoomInfo,
|
} else {
|
||||||
liveHttpClient,
|
dependance.registerSingleton(GiftsManager.class, new TikTokGiftsManager(List.of()));
|
||||||
webSocketClient,
|
}
|
||||||
eventHandler,
|
|
||||||
clientSettings,
|
//mapper
|
||||||
listenerManager,
|
dependance.registerSingleton(TikTokGenericEventMapper.class);
|
||||||
logger);
|
dependance.registerSingleton(TikTokMapperHelper.class, TikTokLiveMapperHelper.class);
|
||||||
|
dependance.registerSingleton(TikTokMapper.class, (container) ->
|
||||||
|
{
|
||||||
|
var dependace = (DependanceContainer) container.find(DependanceContainer.class);
|
||||||
|
var mapper = MessagesMapperFactory.create(dependace);
|
||||||
|
onCustomMappings.forEach(action -> action.accept(mapper));
|
||||||
|
return mapper;
|
||||||
|
});
|
||||||
|
|
||||||
|
//mapper handlers
|
||||||
|
dependance.registerSingleton(TikTokCommonEventHandler.class);
|
||||||
|
dependance.registerSingleton(TikTokGiftEventHandler.class);
|
||||||
|
dependance.registerSingleton(TikTokRoomInfoEventHandler.class);
|
||||||
|
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 +189,10 @@ public class TikTokLiveClientBuilder implements LiveClientBuilder {
|
|||||||
return build().connectAsync();
|
return build().connectAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To do figure out how to use Annotation processor.
|
||||||
|
* Goal is to 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;
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
|||||||
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
import io.github.jwdeveloper.tiktok.live.builder.EventConsumer;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TikTokLiveEventHandler {
|
public class TikTokLiveEventHandler {
|
||||||
private final Map<Class<?>, Set<EventConsumer>> events;
|
private final Map<Class<?>, Set<EventConsumer>> events;
|
||||||
@@ -39,21 +36,8 @@ public class TikTokLiveEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) {
|
public void publish(LiveClient tikTokLiveClient, TikTokEvent tikTokEvent) {
|
||||||
if (events.containsKey(TikTokEvent.class)) {
|
Optional.ofNullable(events.get(TikTokEvent.class)).ifPresent(handlers -> handlers.forEach(handler -> handler.onEvent(tikTokLiveClient, tikTokEvent)));
|
||||||
var handlers = events.get(TikTokEvent.class);
|
Optional.ofNullable(events.get(tikTokEvent.getClass())).ifPresent(handlers -> handlers.forEach(handler -> handler.onEvent(tikTokLiveClient, tikTokEvent)));
|
||||||
for (var handle : handlers) {
|
|
||||||
handle.onEvent(tikTokLiveClient, tikTokEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!events.containsKey(tikTokEvent.getClass())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var handlers = events.get(tikTokEvent.getClass());
|
|
||||||
for (var handler : handlers) {
|
|
||||||
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) {
|
||||||
@@ -65,22 +49,10 @@ public class TikTokLiveEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TikTokEvent> void unsubscribe(EventConsumer<T> consumer) {
|
public <T extends TikTokEvent> void unsubscribe(EventConsumer<T> consumer) {
|
||||||
for (var entry : events.entrySet()) {
|
events.forEach((key, value) -> value.remove(consumer));
|
||||||
entry.getValue().remove(consumer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends TikTokEvent> void unsubscribe(Class<?> clazz, EventConsumer<T> consumer) {
|
public <T extends TikTokEvent> void unsubscribe(Class<?> clazz, EventConsumer<T> consumer) {
|
||||||
if (clazz == null) {
|
Optional.ofNullable(clazz).map(events::get).ifPresent(consumers -> consumers.remove(consumer));
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!events.containsKey(clazz)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var eventSet = events.get(clazz);
|
|
||||||
eventSet.remove(consumer);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
package io.github.jwdeveloper.tiktok;
|
package io.github.jwdeveloper.tiktok;
|
||||||
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import io.github.jwdeveloper.dependance.injector.api.annotations.Inject;
|
||||||
import io.github.jwdeveloper.tiktok.common.*;
|
import io.github.jwdeveloper.tiktok.common.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.requests.*;
|
import io.github.jwdeveloper.tiktok.data.requests.*;
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
import io.github.jwdeveloper.tiktok.data.settings.LiveClientSettings;
|
||||||
@@ -32,6 +33,7 @@ import io.github.jwdeveloper.tiktok.http.mappers.*;
|
|||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
|
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class TikTokLiveHttpClient implements LiveHttpClient
|
public class TikTokLiveHttpClient implements LiveHttpClient
|
||||||
@@ -53,17 +55,19 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
private final GiftsDataMapper giftsDataMapper;
|
private final GiftsDataMapper giftsDataMapper;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
|
||||||
public TikTokLiveHttpClient(HttpClientFactory factory, LiveClientSettings settings) {
|
@Inject
|
||||||
|
public TikTokLiveHttpClient(HttpClientFactory factory) {
|
||||||
this.httpFactory = factory;
|
this.httpFactory = factory;
|
||||||
this.clientSettings = settings;
|
this.clientSettings = factory.getLiveClientSettings();
|
||||||
this.logger = LoggerFactory.create("HttpClient-"+hashCode(), clientSettings);
|
this.logger = LoggerFactory.create("HttpClient-"+hashCode(), clientSettings);
|
||||||
liveUserDataMapper = new LiveUserDataMapper();
|
liveUserDataMapper = new LiveUserDataMapper();
|
||||||
liveDataMapper = new LiveDataMapper();
|
liveDataMapper = new LiveDataMapper();
|
||||||
giftsDataMapper = new GiftsDataMapper();
|
giftsDataMapper = new GiftsDataMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TikTokLiveHttpClient() {
|
public TikTokLiveHttpClient(Consumer<LiveClientSettings> consumer) {
|
||||||
this(new HttpClientFactory(LiveClientSettings.createDefault()), LiveClientSettings.createDefault());
|
this(new HttpClientFactory(LiveClientSettings.createDefault()));
|
||||||
|
consumer.accept(clientSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GiftsData.Response fetchRoomGiftsData(String room_id) {
|
public GiftsData.Response fetchRoomGiftsData(String room_id) {
|
||||||
@@ -191,7 +195,7 @@ public class TikTokLiveHttpClient implements LiveHttpClient
|
|||||||
.withParam("internal_ext", webcastResponse.getInternalExt())
|
.withParam("internal_ext", webcastResponse.getInternalExt())
|
||||||
.withParams(webcastResponse.getRouteParamsMapMap())
|
.withParams(webcastResponse.getRouteParamsMapMap())
|
||||||
.build()
|
.build()
|
||||||
.toUrl();
|
.toUri();
|
||||||
|
|
||||||
return new LiveConnectionData.Response(websocketCookie, webSocketUrl, webcastResponse);
|
return new LiveConnectionData.Response(websocketCookie, webSocketUrl, webcastResponse);
|
||||||
} catch (InvalidProtocolBufferException e) {
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import io.github.jwdeveloper.tiktok.data.events.websocket.TikTokWebsocketUnhandl
|
|||||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveMessageException;
|
||||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.TikTokLiveMapper;
|
import io.github.jwdeveloper.tiktok.mappers.TikTokLiveMapper;
|
||||||
|
import io.github.jwdeveloper.tiktok.mappers.TikTokMapper;
|
||||||
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastResponse;
|
||||||
import io.github.jwdeveloper.tiktok.utils.Stopwatch;
|
import io.github.jwdeveloper.tiktok.utils.Stopwatch;
|
||||||
|
|
||||||
@@ -41,9 +42,9 @@ public class TikTokLiveMessageHandler {
|
|||||||
private final TikTokLiveEventHandler tikTokEventHandler;
|
private final TikTokLiveEventHandler tikTokEventHandler;
|
||||||
private final TikTokLiveMapper mapper;
|
private final TikTokLiveMapper mapper;
|
||||||
|
|
||||||
public TikTokLiveMessageHandler(TikTokLiveEventHandler tikTokEventHandler, TikTokLiveMapper mapper) {
|
public TikTokLiveMessageHandler(TikTokLiveEventHandler tikTokEventHandler, TikTokMapper mapper) {
|
||||||
this.tikTokEventHandler = tikTokEventHandler;
|
this.tikTokEventHandler = tikTokEventHandler;
|
||||||
this.mapper = mapper;
|
this.mapper = (TikTokLiveMapper) mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(LiveClient client, WebcastResponse webcastResponse) {
|
public void handle(LiveClient client, WebcastResponse webcastResponse) {
|
||||||
@@ -61,20 +62,19 @@ public class TikTokLiveMessageHandler {
|
|||||||
public void handleSingleMessage(LiveClient client, WebcastResponse.Message message)
|
public void handleSingleMessage(LiveClient client, WebcastResponse.Message message)
|
||||||
{
|
{
|
||||||
var messageClassName = message.getMethod();
|
var messageClassName = message.getMethod();
|
||||||
if (!mapper.isRegistered(messageClassName)) {
|
if (!mapper.isRegistered(messageClassName))
|
||||||
tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message));
|
tikTokEventHandler.publish(client, new TikTokWebsocketUnhandledMessageEvent(message));
|
||||||
return;
|
else {
|
||||||
}
|
var stopwatch = new Stopwatch();
|
||||||
var stopwatch = new Stopwatch();
|
stopwatch.start();
|
||||||
stopwatch.start();
|
var events = mapper.handleMapping(messageClassName, message.getPayload().toByteArray());
|
||||||
var events = mapper.handleMapping(messageClassName, message.getPayload().toByteArray());
|
var handlingTimeInMs = stopwatch.stop();
|
||||||
var handlingTimeInMs = stopwatch.stop();
|
var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs));
|
||||||
var metadata = new MessageMetaData(Duration.ofNanos(handlingTimeInMs));
|
|
||||||
|
|
||||||
for (var event : events) {
|
for (var event : events) {
|
||||||
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata));
|
tikTokEventHandler.publish(client, new TikTokWebsocketMessageEvent(message, event, metadata));
|
||||||
tikTokEventHandler.publish(client, event);
|
tikTokEventHandler.publish(client, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,14 @@ public class HttpClient {
|
|||||||
return toResponse().map(HttpResponse::body);
|
return toResponse().map(HttpResponse::body);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI toUrl() {
|
public URI toUri() {
|
||||||
var stringUrl = prepareUrlWithParameters(url, httpClientSettings.getParams());
|
var stringUrl = prepareUrlWithParameters(url, httpClientSettings.getParams());
|
||||||
return URI.create(stringUrl);
|
return URI.create(stringUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpRequest prepareGetRequest() {
|
protected HttpRequest prepareGetRequest() {
|
||||||
var requestBuilder = HttpRequest.newBuilder().GET();
|
var requestBuilder = HttpRequest.newBuilder().GET();
|
||||||
requestBuilder.uri(toUrl());
|
requestBuilder.uri(toUri());
|
||||||
requestBuilder.timeout(httpClientSettings.getTimeout());
|
requestBuilder.timeout(httpClientSettings.getTimeout());
|
||||||
httpClientSettings.getHeaders().forEach(requestBuilder::setHeader);
|
httpClientSettings.getHeaders().forEach(requestBuilder::setHeader);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
package io.github.jwdeveloper.tiktok.http;
|
package io.github.jwdeveloper.tiktok.http;
|
||||||
|
|
||||||
import io.github.jwdeveloper.tiktok.data.settings.*;
|
import io.github.jwdeveloper.tiktok.data.settings.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
public class HttpClientFactory {
|
public class HttpClientFactory {
|
||||||
private final LiveClientSettings liveClientSettings;
|
private final LiveClientSettings liveClientSettings;
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class HttpProxyClient extends HttpClient {
|
|||||||
public X509Certificate[] getAcceptedIssuers() { return null; }
|
public X509Certificate[] getAcceptedIssuers() { return null; }
|
||||||
}}, null);
|
}}, null);
|
||||||
|
|
||||||
URL url = toUrl().toURL();
|
URL url = toUri().toURL();
|
||||||
|
|
||||||
if (proxySettings.hasNext()) {
|
if (proxySettings.hasNext()) {
|
||||||
try {
|
try {
|
||||||
@@ -117,7 +117,7 @@ public class HttpProxyClient extends HttpClient {
|
|||||||
|
|
||||||
var responseInfo = createResponseInfo(socksConnection.getResponseCode(), headers);
|
var responseInfo = createResponseInfo(socksConnection.getResponseCode(), headers);
|
||||||
|
|
||||||
var response = createHttpResponse(body, toUrl(), responseInfo);
|
var response = createHttpResponse(body, toUri(), responseInfo);
|
||||||
|
|
||||||
return ActionResult.success(response);
|
return ActionResult.success(response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -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.*;
|
||||||
|
|||||||
@@ -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.*;
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* 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 helper = container.find(TikTokMapperHelper.class);
|
||||||
|
var mapper = new TikTokLiveMapper(helper);
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,14 +23,10 @@
|
|||||||
package io.github.jwdeveloper.tiktok.mappers;
|
package io.github.jwdeveloper.tiktok.mappers;
|
||||||
|
|
||||||
import com.google.protobuf.GeneratedMessageV3;
|
import com.google.protobuf.GeneratedMessageV3;
|
||||||
import io.github.jwdeveloper.tiktok.TikTokLive;
|
|
||||||
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
import io.github.jwdeveloper.tiktok.data.events.common.TikTokEvent;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.data.MappingAction;
|
import io.github.jwdeveloper.tiktok.mappers.data.*;
|
||||||
import io.github.jwdeveloper.tiktok.mappers.data.MappingResult;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class TikTokLiveMapper implements TikTokMapper {
|
public class TikTokLiveMapper implements TikTokMapper {
|
||||||
@@ -47,11 +43,7 @@ public class TikTokLiveMapper implements TikTokMapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokMapperModel forMessage(String messageName) {
|
public TikTokMapperModel forMessage(String messageName) {
|
||||||
if (!isRegistered(messageName)) {
|
return mappers.computeIfAbsent(messageName, TikTokLiveMapperModel::new);
|
||||||
var model = new TikTokLiveMapperModel(messageName);
|
|
||||||
mappers.put(messageName, model);
|
|
||||||
}
|
|
||||||
return mappers.get(messageName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,7 +58,6 @@ public class TikTokLiveMapper implements TikTokMapper {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TikTokMapperModel forMessage(Class<? extends GeneratedMessageV3> mapperName, MappingAction<MappingResult> onMapping) {
|
public TikTokMapperModel forMessage(Class<? extends GeneratedMessageV3> mapperName, MappingAction<MappingResult> onMapping) {
|
||||||
var model = forMessage(mapperName);
|
var model = forMessage(mapperName);
|
||||||
@@ -84,7 +75,6 @@ public class TikTokLiveMapper implements TikTokMapper {
|
|||||||
return globalMapperModel;
|
return globalMapperModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isRegistered(String mapperName) {
|
public boolean isRegistered(String mapperName) {
|
||||||
return mappers.containsKey(mapperName);
|
return mappers.containsKey(mapperName);
|
||||||
}
|
}
|
||||||
@@ -94,23 +84,19 @@ public class TikTokLiveMapper implements TikTokMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<TikTokEvent> handleMapping(String messageName, byte[] bytes) {
|
public List<TikTokEvent> handleMapping(String messageName, byte[] bytes) {
|
||||||
if (!isRegistered(messageName)) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
var mapperModel = mappers.get(messageName);
|
var mapperModel = mappers.get(messageName);
|
||||||
|
if (mapperModel == null)
|
||||||
|
return List.of();
|
||||||
|
|
||||||
var inputBytes = mapperModel.getOnBeforeMapping().onMapping(bytes, messageName, mapperUtils);
|
var inputBytes = mapperModel.getOnBeforeMapping().onMapping(bytes, messageName, mapperUtils);
|
||||||
var globalInputBytes = globalMapperModel.getOnBeforeMapping().onMapping(inputBytes, messageName, mapperUtils);
|
var globalInputBytes = globalMapperModel.getOnBeforeMapping().onMapping(inputBytes, messageName, mapperUtils);
|
||||||
|
|
||||||
|
|
||||||
var mappingResult = mapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
|
var mappingResult = mapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
|
||||||
|
|
||||||
if (mappingResult == null) {
|
if (mappingResult == null)
|
||||||
mappingResult = globalMapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
|
mappingResult = globalMapperModel.getOnMapping().onMapping(globalInputBytes, messageName, mapperUtils);
|
||||||
}
|
|
||||||
|
|
||||||
var afterMappingResult = mapperModel.getOnAfterMapping().apply(mappingResult);
|
var afterMappingResult = mapperModel.getOnAfterMapping().apply(mappingResult);
|
||||||
var globalAfterMappingResult = globalMapperModel.getOnAfterMapping().apply(MappingResult.of(mappingResult.getSource(), afterMappingResult));
|
return globalMapperModel.getOnAfterMapping().apply(MappingResult.of(mappingResult.getSource(), afterMappingResult));
|
||||||
return globalAfterMappingResult;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,5 +75,4 @@ public class TikTokLiveMapperModel implements TikTokMapperModel {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -1,9 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class TikTokWebSocketPingingTask
|
public class TikTokWebSocketPingingTask
|
||||||
{
|
{
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
@@ -14,7 +34,7 @@ public class TikTokWebSocketPingingTask
|
|||||||
public void run(WebSocket webSocket, long pingTaskTime)
|
public void run(WebSocket webSocket, long pingTaskTime)
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
thread = new Thread(() -> pingTask(webSocket, pingTaskTime));
|
thread = new Thread(() -> pingTask(webSocket, pingTaskTime), "pinging-task");
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
@@ -28,18 +48,16 @@ public class TikTokWebSocketPingingTask
|
|||||||
|
|
||||||
private void pingTask(WebSocket webSocket, long pingTaskTime)
|
private void pingTask(WebSocket webSocket, long pingTaskTime)
|
||||||
{
|
{
|
||||||
var random = new Random();
|
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
try {
|
try {
|
||||||
if (!webSocket.isOpen()) {
|
if (webSocket.isOpen()) {
|
||||||
|
webSocket.sendPing();
|
||||||
|
Thread.sleep(pingTaskTime+(int)(Math.random() * MAX_TIMEOUT));
|
||||||
|
} else
|
||||||
Thread.sleep(SLEEP_TIME);
|
Thread.sleep(SLEEP_TIME);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
webSocket.sendPing();
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.3-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.3-Release</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import java.time.Duration;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class ConnectionExample {
|
public class ConnectionExample {
|
||||||
public static String TIKTOK_HOSTNAME = "kvadromama_marina1";
|
public static String TIKTOK_HOSTNAME = "yttvandroid";
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -47,9 +69,7 @@ public class Events_And_Gifts_Testing_Example
|
|||||||
|
|
||||||
var fakeGift = TikTokGiftEvent.of(roseGift);
|
var fakeGift = TikTokGiftEvent.of(roseGift);
|
||||||
var fakeComboGift = TikTokGiftComboEvent.of(roseGift, 12, GiftComboStateType.Begin);
|
var fakeComboGift = TikTokGiftComboEvent.of(roseGift, 12, GiftComboStateType.Begin);
|
||||||
|
|
||||||
var fakeMessage = TikTokCommentEvent.of("Mark", "Hello world");
|
var fakeMessage = TikTokCommentEvent.of("Mark", "Hello world");
|
||||||
|
|
||||||
var fakeSubscriber = TikTokSubscribeEvent.of("Mark");
|
var fakeSubscriber = TikTokSubscribeEvent.of("Mark");
|
||||||
var fakeFollow = TikTokFollowEvent.of("Mark");
|
var fakeFollow = TikTokFollowEvent.of("Mark");
|
||||||
var fakeLike = TikTokLikeEvent.of("Mark", 12);
|
var fakeLike = TikTokLikeEvent.of("Mark", 12);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ Maven
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
<groupId>com.github.jwdeveloper.TikTok-Live-Java</groupId>
|
||||||
<artifactId>Client</artifactId>
|
<artifactId>Client</artifactId>
|
||||||
<version>1.6.0-Release</version>
|
<version>1.7.0-Release</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -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.3-Release</version>
|
<version>1.7.2-Release</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
<artifactId>TikTokLiveJava</artifactId>
|
||||||
<version>1.6.3-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.3-Release</version>
|
<version>1.7.2-Release</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.3-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>
|
||||||
|
|||||||
@@ -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) ->{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -7,7 +7,7 @@
|
|||||||
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
<groupId>io.github.jwdeveloper.tiktok</groupId>
|
||||||
<artifactId>TikTokLiveJava</artifactId>
|
<artifactId>TikTokLiveJava</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.6.3-Release</version>
|
<version>1.7.2-Release</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>API</module>
|
<module>API</module>
|
||||||
<module>Client</module>
|
<module>Client</module>
|
||||||
|
|||||||
Reference in New Issue
Block a user