mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-16 13:23:42 +00:00
init v1.0.0
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.enums.ClientStatusEnums;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.client.KuaishouLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.config.KuaishouLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.listener.IKuaishouMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.netty.handler.KuaishouBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.PayloadTypeOuterClass;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
public class ClientModeExample {
|
||||
static Logger log = LoggerFactory.getLogger(ClientModeExample.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 1. 创建配置
|
||||
KuaishouLiveChatClientConfig config = KuaishouLiveChatClientConfig.builder()
|
||||
// TODO 浏览器Cookie
|
||||
.cookie("did=web_6c4ac2a8ef8855d35df4d564baeaa8e8; kuaishou.live.bfb1s=7206d814e5c089a58c910ed8bf52ace5; clientid=3; did=web_6c4ac2a8ef8855d35df4d564baeaa8e8; client_key=65890b29; kpn=GAME_ZONE; userId=3941614875; kuaishou.live.web_st=ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAbRhgemDxM_Z_lBn7EZ_-5unvtslsh7ci5VY_eg80qqjxy5yb7oBFrdcWSPlz6jMIBz9h_yoLzATE3ngj2WawpxvbJhmq0EnRYIHv308kTBmg4KN2JQf7w2mfrsp1vusFbZ3NkfsEO4PrGQfX0L6mJRbgXeBqyz4tUM5O0q2Jte_NzWkaOnezvIGRAG8Y6yA1dxGUmiA9syTrPrdnSOzZvAaEoJNhwQ4OUDtgURWN6k9Xgm8PSIgAfV-ZvahtgaYhopZno6OuS2pkaFZjrz4ymoEZ1DSnj0oBTAB; kuaishou.live.web_ph=a287be6ab01dce264c0554eed94c2d6ac991; userId=3941614875")
|
||||
// TODO 直播间id(支持短id)
|
||||
.roomId("tianci666")
|
||||
.build();
|
||||
|
||||
// 2. 创建Client并传入配置、添加消息回调
|
||||
KuaishouLiveChatClient client = new KuaishouLiveChatClient(config, new IKuaishouMsgListener() {
|
||||
@Override
|
||||
public void onMsg(IMsg msg) {
|
||||
log.debug("收到{}消息 {}", msg.getClass(), msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCmdMsg(PayloadTypeOuterClass.PayloadType cmd, ICmdMsg<PayloadTypeOuterClass.PayloadType> cmdMsg) {
|
||||
log.debug("收到CMD消息{} {}", cmd, cmdMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOtherCmdMsg(PayloadTypeOuterClass.PayloadType cmd, ICmdMsg<PayloadTypeOuterClass.PayloadType> cmdMsg) {
|
||||
log.debug("收到其他CMD消息 {}", cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownCmd(String cmdString, IMsg msg) {
|
||||
log.debug("收到未知CMD消息 {}", cmdString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDanmuMsg(KuaishouBinaryFrameHandler binaryFrameHandler, KuaishouDanmuMsg msg) {
|
||||
log.info("{} 收到弹幕 [{}] {}({}):{}", binaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid(), msg.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGiftMsg(KuaishouBinaryFrameHandler binaryFrameHandler, KuaishouGiftMsg msg) {
|
||||
log.info("{} 收到礼物 [{}] {}({}) {} {}({})x{}({}) mergeKey:{},comboCount:{}, batchSize:{}", binaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid(), "赠送", msg.getGiftName(), msg.getGiftId(), msg.getGiftCount(), msg.getGiftPrice(), msg.getMsg().getMergeKey(), msg.getMsg().getComboCount(), msg.getMsg().getBatchSize());
|
||||
}
|
||||
});
|
||||
// 3. 开始监听直播间
|
||||
client.connect();
|
||||
|
||||
// 客户端连接状态回调
|
||||
client.addStatusChangeListener(evt -> {
|
||||
if (evt.getNewValue().equals(ClientStatusEnums.CONNECTED)) {
|
||||
// TODO 要发送的弹幕内容,请注意控制发送频率;框架内置支持设置发送弹幕的最少时间间隔,小于时将忽略该次发送
|
||||
client.sendDanmu("666666" + RandomUtil.randomNumbers(1));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.api;
|
||||
|
||||
import cn.hutool.cache.impl.TimedCache;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.*;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import lombok.*;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.util.OrLiveChatCookieUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg.OBJECT_MAPPER;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
public class KuaishouApis {
|
||||
|
||||
/**
|
||||
* 接口返回结果缓存
|
||||
* {@link #KEY_RESULT_CACHE_GIFT_ITEMS}:所有礼物信息
|
||||
*/
|
||||
public static final TimedCache<String, Map<String, GiftInfo>> RESULT_CACHE = new TimedCache<>(TimeUnit.DAYS.toMillis(1));
|
||||
public static final String KEY_RESULT_CACHE_GIFT_ITEMS = "GIFT_ITEMS";
|
||||
|
||||
public static final String PATTERN_LIVE_STREAM_ID = "\"liveStream\":\\{\"id\":\"([\\w\\d-_]+)\"";
|
||||
public static final String USER_AGENT = GlobalHeaders.INSTANCE.header(Header.USER_AGENT).replace("Hutool", "");
|
||||
|
||||
public static RoomInitResult roomInit(Object roomId, String cookie) {
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://live.kuaishou.com/u/" + roomId, cookie)
|
||||
.execute();
|
||||
|
||||
if (StrUtil.isBlank(cookie)) {
|
||||
cookie = OrLiveChatCookieUtil.toString(response.getCookies());
|
||||
}
|
||||
|
||||
String body = response.body();
|
||||
String liveStreamId = ReUtil.getGroup1(PATTERN_LIVE_STREAM_ID, body);
|
||||
JsonNode websocketinfo = websocketinfo(roomId, liveStreamId, cookie);
|
||||
if (!websocketinfo.has("token")) {
|
||||
throwExceptionWithTip("主播未开播,token获取失败 " + websocketinfo);
|
||||
}
|
||||
ArrayNode websocketUrls = websocketinfo.withArray("websocketUrls");
|
||||
ArrayList<String> websocketUrlList = CollUtil.newArrayList();
|
||||
for (JsonNode websocketUrl : websocketUrls) {
|
||||
websocketUrlList.add(websocketUrl.asText());
|
||||
}
|
||||
return RoomInitResult.builder()
|
||||
.token(websocketinfo.required("token").asText())
|
||||
.websocketUrls(websocketUrlList)
|
||||
.liveStreamId(liveStreamId)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static RoomInitResult roomInit(Object roomId) {
|
||||
return roomInit(roomId, null);
|
||||
}
|
||||
|
||||
public static JsonNode websocketinfo(Object roomId, String liveStreamId, String cookie) {
|
||||
if (StrUtil.isBlank(liveStreamId)) {
|
||||
throwExceptionWithTip("主播未开播,liveStreamId为空");
|
||||
}
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://live.kuaishou.com/live_api/liveroom/websocketinfo?liveStreamId=" + liveStreamId, cookie)
|
||||
.header(Header.REFERER, "https://live.kuaishou.com/u/" + roomId)
|
||||
.execute();
|
||||
return responseInterceptor(response.body());
|
||||
}
|
||||
|
||||
public static Map<String, GiftInfo> allgifts() {
|
||||
Map<String, GiftInfo> map = new HashMap<>();
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://live.kuaishou.com/live_api/emoji/allgifts", null).execute();
|
||||
JsonNode jsonNode = responseInterceptor(response.body());
|
||||
jsonNode.fields().forEachRemaining(new Consumer<Map.Entry<String, JsonNode>>() {
|
||||
@Override
|
||||
public void accept(Map.Entry<String, JsonNode> stringJsonNodeEntry) {
|
||||
map.put(stringJsonNodeEntry.getKey(), OBJECT_MAPPER.convertValue(stringJsonNodeEntry.getValue(), GiftInfo.class));
|
||||
}
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据礼物ID获取礼物信息
|
||||
*
|
||||
* @param id 礼物ID
|
||||
* @return 礼物信息
|
||||
*/
|
||||
public static GiftInfo getGiftInfoById(String id) {
|
||||
if (!RESULT_CACHE.containsKey(KEY_RESULT_CACHE_GIFT_ITEMS)) {
|
||||
RESULT_CACHE.put(KEY_RESULT_CACHE_GIFT_ITEMS, allgifts());
|
||||
}
|
||||
return RESULT_CACHE.get(KEY_RESULT_CACHE_GIFT_ITEMS).get(id);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static JsonNode sendComment(String cookie, Object roomId, SendCommentRequest request) {
|
||||
@Cleanup
|
||||
HttpResponse response = createPostRequest("https://live.kuaishou.com/live_api/liveroom/sendComment", cookie)
|
||||
.body(OBJECT_MAPPER.writeValueAsString(request), ContentType.JSON.getValue())
|
||||
.header(Header.REFERER, "https://live.kuaishou.com/u/" + roomId)
|
||||
.execute();
|
||||
return responseInterceptor(response.body());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static JsonNode clickLike(String cookie, Object roomId, String liveStreamId, int count) {
|
||||
@Cleanup
|
||||
HttpResponse response = createPostRequest("https://live.kuaishou.com/live_api/liveroom/like", cookie)
|
||||
.body(OBJECT_MAPPER.createObjectNode()
|
||||
.put("liveStreamId", liveStreamId)
|
||||
.put("count", count)
|
||||
.toString(), ContentType.JSON.getValue()
|
||||
)
|
||||
.header(Header.ORIGIN, "https://live.kuaishou.com")
|
||||
.header(Header.REFERER, "https://live.kuaishou.com/u/" + roomId)
|
||||
.execute();
|
||||
return responseInterceptor(response.body());
|
||||
}
|
||||
|
||||
public static HttpRequest createRequest(Method method, String url, String cookie) {
|
||||
return HttpUtil.createRequest(method, url)
|
||||
.cookie(cookie)
|
||||
.header(Header.HOST, URLUtil.url(url).getHost())
|
||||
.header(Header.USER_AGENT, USER_AGENT);
|
||||
}
|
||||
|
||||
public static HttpRequest createGetRequest(String url, String cookie) {
|
||||
return createRequest(Method.GET, url, cookie);
|
||||
}
|
||||
|
||||
public static HttpRequest createPostRequest(String url, String cookie) {
|
||||
return createRequest(Method.POST, url, cookie);
|
||||
}
|
||||
|
||||
private static JsonNode responseInterceptor(String responseString) {
|
||||
try {
|
||||
JsonNode jsonNode = OBJECT_MAPPER.readTree(responseString);
|
||||
JsonNode data = jsonNode.required("data");
|
||||
if (data.has("result")) {
|
||||
int result = data.get("result").asInt();
|
||||
if (result != 1) {
|
||||
String message = "";
|
||||
switch (result) {
|
||||
case 2: {
|
||||
message = "请求过快,请稍后重试";
|
||||
break;
|
||||
}
|
||||
case 400002: {
|
||||
message = "需要进行验证";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
throwExceptionWithTip("接口访问失败:" + message + ",返回结果:" + jsonNode);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void throwExceptionWithTip(String message) {
|
||||
throw new BaseException("『可能已触发滑块验证,建议配置Cookie或打开浏览器进行滑块验证后重试』" + message);
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class SendCommentRequest {
|
||||
private String liveStreamId;
|
||||
private String content;
|
||||
private String color;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class RoomInitResult {
|
||||
private String token;
|
||||
private String liveStreamId;
|
||||
private List<String> websocketUrls;
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class GiftInfo {
|
||||
private String giftName;
|
||||
private String giftUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.client;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.api.KuaishouApis;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.config.KuaishouLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.listener.IKuaishouConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.listener.IKuaishouMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.base.IKuaishouMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.netty.handler.KuaishouBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.netty.handler.KuaishouConnectionHandler;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.PayloadTypeOuterClass;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.base.BaseNettyClient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
@Slf4j
|
||||
public class KuaishouLiveChatClient extends BaseNettyClient<
|
||||
KuaishouLiveChatClientConfig,
|
||||
PayloadTypeOuterClass.PayloadType,
|
||||
IKuaishouMsg,
|
||||
IKuaishouMsgListener,
|
||||
KuaishouConnectionHandler,
|
||||
KuaishouBinaryFrameHandler> {
|
||||
|
||||
@Getter
|
||||
KuaishouApis.RoomInitResult roomInitResult = new KuaishouApis.RoomInitResult();
|
||||
|
||||
public KuaishouLiveChatClient(KuaishouLiveChatClientConfig config, List<IKuaishouMsgListener> msgListeners, IKuaishouConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListeners(msgListeners);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public KuaishouLiveChatClient(KuaishouLiveChatClientConfig config, IKuaishouMsgListener msgListener, IKuaishouConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListener(msgListener);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public KuaishouLiveChatClient(KuaishouLiveChatClientConfig config, IKuaishouMsgListener msgListener, IKuaishouConnectionListener connectionListener) {
|
||||
this(config, msgListener, connectionListener, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public KuaishouLiveChatClient(KuaishouLiveChatClientConfig config, IKuaishouMsgListener msgListener) {
|
||||
this(config, msgListener, null, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public KuaishouLiveChatClient(KuaishouLiveChatClientConfig config) {
|
||||
this(config, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
roomInitResult = KuaishouApis.roomInit(getConfig().getRoomId(), getConfig().getCookie());
|
||||
super.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWebSocketUriString() {
|
||||
List<String> websocketUrls = roomInitResult.getWebsocketUrls();
|
||||
return CollUtil.get(websocketUrls, RandomUtil.randomInt(0, websocketUrls.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public KuaishouConnectionHandler initConnectionHandler(IBaseConnectionListener<KuaishouConnectionHandler> clientConnectionListener) {
|
||||
return new KuaishouConnectionHandler(
|
||||
WebSocketClientHandshakerFactory.newHandshaker(getWebsocketUri(), WebSocketVersion.V13, null, true, new DefaultHttpHeaders(), getConfig().getMaxFramePayloadLength()),
|
||||
KuaishouLiveChatClient.this, clientConnectionListener
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KuaishouBinaryFrameHandler initBinaryFrameHandler() {
|
||||
return new KuaishouBinaryFrameHandler(super.msgListeners, KuaishouLiveChatClient.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed) {
|
||||
if (!checkCanSendDanmu()) {
|
||||
return;
|
||||
}
|
||||
if (danmu instanceof String) {
|
||||
String msg = (String) danmu;
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("{} kuaishou发送弹幕 {}", getConfig().getRoomId(), danmu);
|
||||
}
|
||||
|
||||
boolean sendSuccess = false;
|
||||
try {
|
||||
KuaishouApis.sendComment(getConfig().getCookie(),
|
||||
getConfig().getRoomId(),
|
||||
KuaishouApis.SendCommentRequest.builder()
|
||||
.liveStreamId(roomInitResult.getLiveStreamId())
|
||||
.content(msg)
|
||||
.build()
|
||||
);
|
||||
sendSuccess = true;
|
||||
} catch (Exception e) {
|
||||
log.error("kuaishou弹幕发送失败", e);
|
||||
if (failed != null) {
|
||||
failed.accept(e);
|
||||
}
|
||||
}
|
||||
if (!sendSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("kuaishou弹幕发送成功 {}", danmu);
|
||||
}
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
finishSendDanmu();
|
||||
} catch (Exception e) {
|
||||
log.error("kuaishou弹幕发送失败", e);
|
||||
if (failed != null) {
|
||||
failed.accept(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.sendDanmu(danmu, success, failed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickLike(int count, Runnable success, Consumer<Throwable> failed) {
|
||||
if (count <= 0) {
|
||||
throw new BaseException("点赞次数必须大于0");
|
||||
}
|
||||
|
||||
boolean successfullyClicked = false;
|
||||
try {
|
||||
JsonNode jsonNode = KuaishouApis.clickLike(getConfig().getCookie(), getConfig().getRoomId(), roomInitResult.getLiveStreamId(), count);
|
||||
if (jsonNode.asBoolean()) {
|
||||
successfullyClicked = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("kuaishou为直播间点赞失败", e);
|
||||
if (failed != null) {
|
||||
failed.accept(e);
|
||||
}
|
||||
}
|
||||
if (!successfullyClicked) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("kuaishou为直播间点赞成功");
|
||||
}
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.config.BaseNettyClientConfig;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class KuaishouLiveChatClientConfig extends BaseNettyClientConfig {
|
||||
|
||||
@Builder.Default
|
||||
private long heartbeatPeriod = 20;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.listener;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.netty.handler.KuaishouConnectionHandler;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
public interface IKuaishouConnectionListener extends IBaseConnectionListener<KuaishouConnectionHandler> {
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.listener;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IDanmuMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IGiftMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.ILikeMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouLikeMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.netty.handler.KuaishouBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.PayloadTypeOuterClass;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
public interface IKuaishouMsgListener extends IBaseMsgListener<KuaishouBinaryFrameHandler, PayloadTypeOuterClass.PayloadType>,
|
||||
IDanmuMsgListener<KuaishouBinaryFrameHandler, KuaishouDanmuMsg>,
|
||||
IGiftMsgListener<KuaishouBinaryFrameHandler, KuaishouGiftMsg>,
|
||||
ILikeMsgListener<KuaishouBinaryFrameHandler, KuaishouLikeMsg> {
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.msg;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.UnknownFieldSet;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.base.IKuaishouMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.WebCommentFeedOuterClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class KuaishouDanmuMsg implements IKuaishouMsg, IDanmuMsg {
|
||||
|
||||
private WebCommentFeedOuterClass.WebCommentFeed msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
String badgeName = null;
|
||||
try {
|
||||
UnknownFieldSet.Field field21 = msg.getSenderState().getUnknownFields().asMap().get(21);
|
||||
List<ByteString> lengthDelimitedList = field21.getLengthDelimitedList();
|
||||
if (!lengthDelimitedList.isEmpty()) {
|
||||
UnknownFieldSet.Field field21_1 = UnknownFieldSet.parseFrom(
|
||||
lengthDelimitedList.size() > 1 ? lengthDelimitedList.get(1) : lengthDelimitedList.get(0)
|
||||
).getField(1);
|
||||
List<ByteString> lengthDelimitedList1 = field21_1.getLengthDelimitedList();
|
||||
if (!lengthDelimitedList1.isEmpty()) {
|
||||
UnknownFieldSet.Field field21_1_4 = UnknownFieldSet.parseFrom((lengthDelimitedList1.get(0))).getField(4);
|
||||
List<ByteString> lengthDelimitedList2 = field21_1_4.getLengthDelimitedList();
|
||||
if (!lengthDelimitedList2.isEmpty()) {
|
||||
badgeName = lengthDelimitedList2.get(0).toStringUtf8();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return badgeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return (byte) msg.getSenderState().getLiveFansGroupState().getIntimacyLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return msg.getUser().getPrincipalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getUserName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return msg.getUser().getHeadUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
return msg.getContent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.msg;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.api.KuaishouApis;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.base.IKuaishouMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.WebGiftFeedOuterClass;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class KuaishouGiftMsg implements IKuaishouMsg, IGiftMsg {
|
||||
|
||||
private WebGiftFeedOuterClass.WebGiftFeed msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
return IGiftMsg.super.getBadgeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return IGiftMsg.super.getBadgeLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return msg.getUser().getPrincipalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getUserName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return msg.getUser().getHeadUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftName() {
|
||||
return KuaishouApis.getGiftInfoById(this.getGiftId()).getGiftName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftImg() {
|
||||
return KuaishouApis.getGiftInfoById(this.getGiftId()).getGiftUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftId() {
|
||||
return Integer.toString(msg.getIntGiftId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftCount() {
|
||||
// TODO 礼物个数?网页上只显示赠送了什么东西,不显示个数,只会显示连击
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftPrice() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUid() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUsername() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.msg;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ILikeMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.base.IKuaishouMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.WebLikeFeedOuterClass;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class KuaishouLikeMsg implements IKuaishouMsg, ILikeMsg {
|
||||
|
||||
private WebLikeFeedOuterClass.WebLikeFeed msg;
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return msg.getUser().getPrincipalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getUserName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return msg.getUser().getHeadUrl();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.msg.base;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.PayloadTypeOuterClass;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
public interface IKuaishouCmdMsg extends IKuaishouMsg, ICmdMsg<PayloadTypeOuterClass.PayloadType> {
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.msg.base;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
public interface IKuaishouMsg extends IMsg {
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.netty.handler;
|
||||
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.client.KuaishouLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.listener.IKuaishouMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.KuaishouLikeMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.msg.base.IKuaishouMsg;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.*;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientBinaryFrameHandler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class KuaishouBinaryFrameHandler extends BaseNettyClientBinaryFrameHandler<KuaishouLiveChatClient, KuaishouBinaryFrameHandler, PayloadTypeOuterClass.PayloadType, IKuaishouMsg, IKuaishouMsgListener> {
|
||||
|
||||
public KuaishouBinaryFrameHandler(List<IKuaishouMsgListener> iKuaishouMsgListeners, KuaishouLiveChatClient client) {
|
||||
super(iKuaishouMsgListeners, client);
|
||||
}
|
||||
|
||||
public KuaishouBinaryFrameHandler(List<IKuaishouMsgListener> iKuaishouMsgListeners, long roomId) {
|
||||
super(iKuaishouMsgListeners, roomId);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onCmdMsg(PayloadTypeOuterClass.PayloadType cmd, ICmdMsg<PayloadTypeOuterClass.PayloadType> cmdMsg) {
|
||||
if (super.msgListeners.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SocketMessageOuterClass.SocketMessage socketMessage = (SocketMessageOuterClass.SocketMessage) cmdMsg;
|
||||
ByteString payloadByteString = socketMessage.getPayload();
|
||||
switch (socketMessage.getPayloadType()) {
|
||||
case SC_FEED_PUSH: {
|
||||
SCWebFeedPushOuterClass.SCWebFeedPush scWebFeedPush = SCWebFeedPushOuterClass.SCWebFeedPush.parseFrom(payloadByteString);
|
||||
if (scWebFeedPush.getCommentFeedsCount() > 0) {
|
||||
for (WebCommentFeedOuterClass.WebCommentFeed webCommentFeed : scWebFeedPush.getCommentFeedsList()) {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onDanmuMsg(KuaishouBinaryFrameHandler.this, new KuaishouDanmuMsg(webCommentFeed)));
|
||||
}
|
||||
}
|
||||
if (scWebFeedPush.getGiftFeedsCount() > 0) {
|
||||
for (WebGiftFeedOuterClass.WebGiftFeed webGiftFeed : scWebFeedPush.getGiftFeedsList()) {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onGiftMsg(KuaishouBinaryFrameHandler.this, new KuaishouGiftMsg(webGiftFeed)));
|
||||
}
|
||||
}
|
||||
if (scWebFeedPush.getLikeFeedsCount() > 0) {
|
||||
for (WebLikeFeedOuterClass.WebLikeFeed webLikeFeed : scWebFeedPush.getLikeFeedsList()) {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onLikeMsg(KuaishouBinaryFrameHandler.this, new KuaishouLikeMsg(webLikeFeed)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onOtherCmdMsg(KuaishouBinaryFrameHandler.this, cmd, socketMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<IKuaishouMsg> decode(ByteBuf byteBuf) {
|
||||
try {
|
||||
SocketMessageOuterClass.SocketMessage socketMessage = SocketMessageOuterClass.SocketMessage.parseFrom(byteBuf.nioBuffer());
|
||||
SocketMessageOuterClass.SocketMessage.CompressionType compressionType = socketMessage.getCompressionType();
|
||||
ByteString payloadByteString = socketMessage.getPayload();
|
||||
byte[] payload;
|
||||
switch (compressionType) {
|
||||
case NONE: {
|
||||
payload = payloadByteString.toByteArray();
|
||||
break;
|
||||
}
|
||||
case GZIP: {
|
||||
payload = ZipUtil.unGzip(payloadByteString.newInput());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("暂不支持的压缩方式 " + compressionType);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return Collections.singletonList(socketMessage.toBuilder().setPayload(ByteString.copyFrom(payload)).build());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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 tech.ordinaryroad.live.chat.client.kuaishou.netty.handler;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.api.KuaishouApis;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.client.KuaishouLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.config.KuaishouLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.CSHeartbeatOuterClass;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.CSWebEnterRoomOuterClass;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.PayloadTypeOuterClass;
|
||||
import tech.ordinaryroad.live.chat.client.kuaishou.protobuf.SocketMessageOuterClass;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientConnectionHandler;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/5
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class KuaishouConnectionHandler extends BaseNettyClientConnectionHandler<KuaishouLiveChatClient, KuaishouConnectionHandler> {
|
||||
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private final Object roomId;
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private String cookie;
|
||||
private final KuaishouApis.RoomInitResult roomInitResult;
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, KuaishouLiveChatClient client, IBaseConnectionListener<KuaishouConnectionHandler> listener) {
|
||||
super(handshaker, client, listener);
|
||||
this.roomId = client.getConfig().getRoomId();
|
||||
this.cookie = client.getConfig().getCookie();
|
||||
this.roomInitResult = client.getRoomInitResult();
|
||||
}
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, KuaishouLiveChatClient client) {
|
||||
this(handshaker, client, null);
|
||||
}
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, KuaishouApis.RoomInitResult roomInitResult, IBaseConnectionListener<KuaishouConnectionHandler> listener, String cookie) {
|
||||
super(handshaker, listener);
|
||||
this.roomId = roomId;
|
||||
this.cookie = cookie;
|
||||
this.roomInitResult = roomInitResult;
|
||||
}
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, KuaishouApis.RoomInitResult roomInitResult, IBaseConnectionListener<KuaishouConnectionHandler> listener) {
|
||||
this(handshaker, roomId, roomInitResult, listener, null);
|
||||
}
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, KuaishouApis.RoomInitResult roomInitResult, String cookie) {
|
||||
this(handshaker, roomId, roomInitResult, null, cookie);
|
||||
}
|
||||
|
||||
public KuaishouConnectionHandler(WebSocketClientHandshaker handshaker, KuaishouApis.RoomInitResult roomInitResult, long roomId) {
|
||||
this(handshaker, roomId, roomInitResult, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendHeartbeat(ChannelHandlerContext ctx) {
|
||||
ctx.writeAndFlush(
|
||||
new BinaryWebSocketFrame(
|
||||
Unpooled.wrappedBuffer(SocketMessageOuterClass.SocketMessage.newBuilder()
|
||||
.setPayloadType(PayloadTypeOuterClass.PayloadType.CS_HEARTBEAT)
|
||||
.setPayload(
|
||||
CSHeartbeatOuterClass.CSHeartbeat.newBuilder()
|
||||
.setTimestamp(System.currentTimeMillis())
|
||||
.build()
|
||||
.toByteString()
|
||||
)
|
||||
.build()
|
||||
.toByteArray()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAuthRequest(Channel channel) {
|
||||
channel.writeAndFlush(
|
||||
new BinaryWebSocketFrame(
|
||||
Unpooled.wrappedBuffer(SocketMessageOuterClass.SocketMessage.newBuilder()
|
||||
.setPayloadType(PayloadTypeOuterClass.PayloadType.CS_ENTER_ROOM)
|
||||
.setPayload(
|
||||
CSWebEnterRoomOuterClass.CSWebEnterRoom.newBuilder()
|
||||
.setToken(roomInitResult.getToken())
|
||||
.setLiveStreamId(roomInitResult.getLiveStreamId())
|
||||
.setPageId(RandomUtil.randomString(16) + System.currentTimeMillis())
|
||||
.build()
|
||||
.toByteString()
|
||||
)
|
||||
.build()
|
||||
.toByteArray()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatPeriod() {
|
||||
if (client == null) {
|
||||
return KuaishouLiveChatClientConfig.DEFAULT_HEARTBEAT_PERIOD;
|
||||
} else {
|
||||
return client.getConfig().getHeartbeatPeriod();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatInitialDelay() {
|
||||
if (client == null) {
|
||||
return KuaishouLiveChatClientConfig.DEFAULT_HEARTBEAT_INITIAL_DELAY;
|
||||
} else {
|
||||
return client.getConfig().getHeartbeatInitialDelay();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getRoomId() {
|
||||
return client != null ? client.getConfig().getRoomId() : roomId;
|
||||
}
|
||||
|
||||
private String getCookie() {
|
||||
return client != null ? client.getConfig().getCookie() : cookie;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: ClientId.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.kuaishou.protobuf;
|
||||
|
||||
public final class ClientIdOuterClass {
|
||||
private ClientIdOuterClass() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
/**
|
||||
* Protobuf enum {@code ClientId}
|
||||
*/
|
||||
public enum ClientId
|
||||
implements com.google.protobuf.ProtocolMessageEnum {
|
||||
/**
|
||||
* <code>NONE = 0;</code>
|
||||
*/
|
||||
NONE(0),
|
||||
/**
|
||||
* <code>IPHONE = 1;</code>
|
||||
*/
|
||||
IPHONE(1),
|
||||
/**
|
||||
* <code>ANDROID = 2;</code>
|
||||
*/
|
||||
ANDROID(2),
|
||||
/**
|
||||
* <code>WEB = 3;</code>
|
||||
*/
|
||||
WEB(3),
|
||||
/**
|
||||
* <code>PC = 6;</code>
|
||||
*/
|
||||
PC(6),
|
||||
/**
|
||||
* <code>IPHONE_LIVE_MATE = 8;</code>
|
||||
*/
|
||||
IPHONE_LIVE_MATE(8),
|
||||
/**
|
||||
* <code>ANDROID_LIVE_MATE = 9;</code>
|
||||
*/
|
||||
ANDROID_LIVE_MATE(9),
|
||||
UNRECOGNIZED(-1),
|
||||
;
|
||||
|
||||
/**
|
||||
* <code>NONE = 0;</code>
|
||||
*/
|
||||
public static final int NONE_VALUE = 0;
|
||||
/**
|
||||
* <code>IPHONE = 1;</code>
|
||||
*/
|
||||
public static final int IPHONE_VALUE = 1;
|
||||
/**
|
||||
* <code>ANDROID = 2;</code>
|
||||
*/
|
||||
public static final int ANDROID_VALUE = 2;
|
||||
/**
|
||||
* <code>WEB = 3;</code>
|
||||
*/
|
||||
public static final int WEB_VALUE = 3;
|
||||
/**
|
||||
* <code>PC = 6;</code>
|
||||
*/
|
||||
public static final int PC_VALUE = 6;
|
||||
/**
|
||||
* <code>IPHONE_LIVE_MATE = 8;</code>
|
||||
*/
|
||||
public static final int IPHONE_LIVE_MATE_VALUE = 8;
|
||||
/**
|
||||
* <code>ANDROID_LIVE_MATE = 9;</code>
|
||||
*/
|
||||
public static final int ANDROID_LIVE_MATE_VALUE = 9;
|
||||
|
||||
|
||||
public final int getNumber() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"Can't get the number of an unknown enum value.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
* @deprecated Use {@link #forNumber(int)} instead.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
public static ClientId valueOf(int value) {
|
||||
return forNumber(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
*/
|
||||
public static ClientId forNumber(int value) {
|
||||
switch (value) {
|
||||
case 0: return NONE;
|
||||
case 1: return IPHONE;
|
||||
case 2: return ANDROID;
|
||||
case 3: return WEB;
|
||||
case 6: return PC;
|
||||
case 8: return IPHONE_LIVE_MATE;
|
||||
case 9: return ANDROID_LIVE_MATE;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Internal.EnumLiteMap<ClientId>
|
||||
internalGetValueMap() {
|
||||
return internalValueMap;
|
||||
}
|
||||
private static final com.google.protobuf.Internal.EnumLiteMap<
|
||||
ClientId> internalValueMap =
|
||||
new com.google.protobuf.Internal.EnumLiteMap<ClientId>() {
|
||||
public ClientId findValueByNumber(int number) {
|
||||
return ClientId.forNumber(number);
|
||||
}
|
||||
};
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumValueDescriptor
|
||||
getValueDescriptor() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalStateException(
|
||||
"Can't get the descriptor of an unrecognized enum value.");
|
||||
}
|
||||
return getDescriptor().getValues().get(ordinal());
|
||||
}
|
||||
public final com.google.protobuf.Descriptors.EnumDescriptor
|
||||
getDescriptorForType() {
|
||||
return getDescriptor();
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.EnumDescriptor
|
||||
getDescriptor() {
|
||||
return tech.ordinaryroad.live.chat.client.kuaishou.protobuf.ClientIdOuterClass.getDescriptor().getEnumTypes().get(0);
|
||||
}
|
||||
|
||||
private static final ClientId[] VALUES = values();
|
||||
|
||||
public static ClientId valueOf(
|
||||
com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
|
||||
if (desc.getType() != getDescriptor()) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"EnumValueDescriptor is not for this type.");
|
||||
}
|
||||
if (desc.getIndex() == -1) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
return VALUES[desc.getIndex()];
|
||||
}
|
||||
|
||||
private final int value;
|
||||
|
||||
private ClientId(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(enum_scope:ClientId)
|
||||
}
|
||||
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\016ClientId.proto*k\n\010ClientId\022\010\n\004NONE\020\000\022\n" +
|
||||
"\n\006IPHONE\020\001\022\013\n\007ANDROID\020\002\022\007\n\003WEB\020\003\022\006\n\002PC\020\006" +
|
||||
"\022\024\n\020IPHONE_LIVE_MATE\020\010\022\025\n\021ANDROID_LIVE_M" +
|
||||
"ATE\020\tB6\n4tech.ordinaryroad.live.chat.cli" +
|
||||
"ent.kuaishou.protobufb\006proto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
});
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 OrdinaryRoad
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: ConfigSwitchType.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.kuaishou.protobuf;
|
||||
|
||||
public final class ConfigSwitchTypeOuterClass {
|
||||
private ConfigSwitchTypeOuterClass() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
/**
|
||||
* Protobuf enum {@code ConfigSwitchType}
|
||||
*/
|
||||
public enum ConfigSwitchType
|
||||
implements com.google.protobuf.ProtocolMessageEnum {
|
||||
/**
|
||||
* <code>UNKNOWN = 0;</code>
|
||||
*/
|
||||
UNKNOWN(0),
|
||||
/**
|
||||
* <code>HIDE_BARRAGE = 1;</code>
|
||||
*/
|
||||
HIDE_BARRAGE(1),
|
||||
/**
|
||||
* <code>HIDE_SPECIAL_EFFECT = 2;</code>
|
||||
*/
|
||||
HIDE_SPECIAL_EFFECT(2),
|
||||
UNRECOGNIZED(-1),
|
||||
;
|
||||
|
||||
/**
|
||||
* <code>UNKNOWN = 0;</code>
|
||||
*/
|
||||
public static final int UNKNOWN_VALUE = 0;
|
||||
/**
|
||||
* <code>HIDE_BARRAGE = 1;</code>
|
||||
*/
|
||||
public static final int HIDE_BARRAGE_VALUE = 1;
|
||||
/**
|
||||
* <code>HIDE_SPECIAL_EFFECT = 2;</code>
|
||||
*/
|
||||
public static final int HIDE_SPECIAL_EFFECT_VALUE = 2;
|
||||
|
||||
|
||||
public final int getNumber() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"Can't get the number of an unknown enum value.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
* @deprecated Use {@link #forNumber(int)} instead.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
public static ConfigSwitchType valueOf(int value) {
|
||||
return forNumber(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
*/
|
||||
public static ConfigSwitchType forNumber(int value) {
|
||||
switch (value) {
|
||||
case 0: return UNKNOWN;
|
||||
case 1: return HIDE_BARRAGE;
|
||||
case 2: return HIDE_SPECIAL_EFFECT;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Internal.EnumLiteMap<ConfigSwitchType>
|
||||
internalGetValueMap() {
|
||||
return internalValueMap;
|
||||
}
|
||||
private static final com.google.protobuf.Internal.EnumLiteMap<
|
||||
ConfigSwitchType> internalValueMap =
|
||||
new com.google.protobuf.Internal.EnumLiteMap<ConfigSwitchType>() {
|
||||
public ConfigSwitchType findValueByNumber(int number) {
|
||||
return ConfigSwitchType.forNumber(number);
|
||||
}
|
||||
};
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumValueDescriptor
|
||||
getValueDescriptor() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalStateException(
|
||||
"Can't get the descriptor of an unrecognized enum value.");
|
||||
}
|
||||
return getDescriptor().getValues().get(ordinal());
|
||||
}
|
||||
public final com.google.protobuf.Descriptors.EnumDescriptor
|
||||
getDescriptorForType() {
|
||||
return getDescriptor();
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.EnumDescriptor
|
||||
getDescriptor() {
|
||||
return tech.ordinaryroad.live.chat.client.kuaishou.protobuf.ConfigSwitchTypeOuterClass.getDescriptor().getEnumTypes().get(0);
|
||||
}
|
||||
|
||||
private static final ConfigSwitchType[] VALUES = values();
|
||||
|
||||
public static ConfigSwitchType valueOf(
|
||||
com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
|
||||
if (desc.getType() != getDescriptor()) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"EnumValueDescriptor is not for this type.");
|
||||
}
|
||||
if (desc.getIndex() == -1) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
return VALUES[desc.getIndex()];
|
||||
}
|
||||
|
||||
private final int value;
|
||||
|
||||
private ConfigSwitchType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(enum_scope:ConfigSwitchType)
|
||||
}
|
||||
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\026ConfigSwitchType.proto*J\n\020ConfigSwitch" +
|
||||
"Type\022\013\n\007UNKNOWN\020\000\022\020\n\014HIDE_BARRAGE\020\001\022\027\n\023H" +
|
||||
"IDE_SPECIAL_EFFECT\020\002B6\n4tech.ordinaryroa" +
|
||||
"d.live.chat.client.kuaishou.protobufb\006pr" +
|
||||
"oto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
});
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user