mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-03 15:06:11 +00:00
refactor: 移除个人微信模块,移除直播模
This commit is contained in:
@@ -25,9 +25,9 @@ spring:
|
||||
master:
|
||||
type: ${spring.datasource.type}
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: ry-vue
|
||||
password: xx
|
||||
url: jdbc:mysql://122.51.75.95:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: ruoyi-ai
|
||||
password: zkHBnmAK4fmx6YnS
|
||||
|
||||
hikari:
|
||||
# 最大连接池数量
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>live-chat-client-commons-base</artifactId>
|
||||
<name>ordinaryroad-live-chat-client-commons-base</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.constant;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public class Constants {
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.exception;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/5
|
||||
*/
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
public BaseException() {
|
||||
}
|
||||
|
||||
public BaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BaseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public BaseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 连接回调
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public interface IBaseConnectionListener<T> {
|
||||
|
||||
/**
|
||||
* 连接建立成功
|
||||
*/
|
||||
default void onConnected(T t) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接建立失败
|
||||
*
|
||||
* @param t
|
||||
*/
|
||||
default void onConnectFailed(T t) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接断开
|
||||
*
|
||||
* @param t
|
||||
*/
|
||||
default void onDisconnected(T t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseCmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
|
||||
/**
|
||||
* Base消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public interface IBaseMsgListener<T, CmdEnum extends Enum<CmdEnum>> {
|
||||
|
||||
/**
|
||||
* 收到消息(所有消息)
|
||||
*
|
||||
* @param msg IMsg
|
||||
*/
|
||||
default void onMsg(T t, IMsg msg) {
|
||||
this.onMsg(msg);
|
||||
}
|
||||
|
||||
default void onMsg(IMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到cmd消息(所有cmd)
|
||||
*
|
||||
* @param cmd CmdEnum
|
||||
* @param cmdMsg BaseCmdMsg
|
||||
*/
|
||||
default void onCmdMsg(T t, CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
|
||||
this.onCmdMsg(cmd, cmdMsg);
|
||||
}
|
||||
|
||||
default void onCmdMsg(CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到其他cmd消息(存在Enum,但Listener没有对应的回调)
|
||||
*
|
||||
* @param cmd CmdEnum
|
||||
* @param cmdMsg BaseCmdMsg
|
||||
*/
|
||||
default void onOtherCmdMsg(T t, CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
|
||||
this.onOtherCmdMsg(cmd, cmdMsg);
|
||||
}
|
||||
|
||||
default void onOtherCmdMsg(CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到未知cmd消息
|
||||
*
|
||||
* @param cmdString 实际收到的cmd字符串
|
||||
* @param msg BaseMsg
|
||||
*/
|
||||
default void onUnknownCmd(T t, String cmdString, IMsg msg) {
|
||||
this.onUnknownCmd(cmdString, msg);
|
||||
}
|
||||
|
||||
default void onUnknownCmd(String cmdString, IMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到cmd消息(所有cmd)
|
||||
*
|
||||
* @param cmd CmdEnum
|
||||
* @param cmdMsg BaseCmdMsg
|
||||
* @deprecated use {@link #onCmdMsg(T, Enum, ICmdMsg)}
|
||||
*/
|
||||
default void onCmdMsg(T t, CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
|
||||
this.onCmdMsg(cmd, cmdMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #onCmdMsg(Enum, ICmdMsg)}
|
||||
*/
|
||||
default void onCmdMsg(CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到其他cmd消息(存在Enum,但Listener没有对应的回调)
|
||||
*
|
||||
* @param cmd CmdEnum
|
||||
* @param cmdMsg BaseCmdMsg
|
||||
* @deprecated use {@link #onOtherCmdMsg(T, Enum, ICmdMsg)}
|
||||
*/
|
||||
default void onOtherCmdMsg(T t, CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
|
||||
this.onOtherCmdMsg(cmd, cmdMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #onOtherCmdMsg(Enum, ICmdMsg)}
|
||||
*/
|
||||
default void onOtherCmdMsg(CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 收到未知cmd消息
|
||||
*
|
||||
* @param cmdString 实际收到的cmd字符串
|
||||
* @param msg BaseMsg
|
||||
* @deprecated use {@link #onUnknownCmd(T, String, IMsg)}
|
||||
*/
|
||||
default void onUnknownCmd(T t, String cmdString, BaseMsg msg) {
|
||||
this.onUnknownCmd(cmdString, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #onUnknownCmd(String, IMsg)}
|
||||
*/
|
||||
default void onUnknownCmd(String cmdString, BaseMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 弹幕消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @since 0.0.6
|
||||
*/
|
||||
public interface IDanmuMsgListener<T, DanmuMsg> {
|
||||
|
||||
/**
|
||||
* 收到弹幕
|
||||
*/
|
||||
default void onDanmuMsg(T t, DanmuMsg msg) {
|
||||
this.onDanmuMsg(msg);
|
||||
}
|
||||
|
||||
default void onDanmuMsg(DanmuMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 进入房间消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/12/14
|
||||
* @since 0.0.16
|
||||
*/
|
||||
public interface IEnterRoomMsgListener<T, EnterRoomMsg> {
|
||||
|
||||
/**
|
||||
* 用户进入房间
|
||||
*/
|
||||
default void onEnterRoomMsg(T t, EnterRoomMsg msg) {
|
||||
this.onEnterRoomMsg(msg);
|
||||
}
|
||||
|
||||
default void onEnterRoomMsg(EnterRoomMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 礼物消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @since 0.0.8
|
||||
*/
|
||||
public interface IGiftMsgListener<T, GiftMsg> {
|
||||
|
||||
|
||||
/**
|
||||
* 收到礼物
|
||||
*/
|
||||
default void onGiftMsg(T t, GiftMsg msg) {
|
||||
this.onGiftMsg(msg);
|
||||
}
|
||||
|
||||
default void onGiftMsg(GiftMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 点赞消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @since 0.2.0
|
||||
*/
|
||||
public interface ILikeMsgListener<T, LikeMsg> {
|
||||
|
||||
/**
|
||||
* 收到点赞
|
||||
*/
|
||||
default void onLikeMsg(T t, LikeMsg msg) {
|
||||
this.onLikeMsg(msg);
|
||||
}
|
||||
|
||||
default void onLikeMsg(LikeMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.listener;
|
||||
|
||||
|
||||
/**
|
||||
* 醒目留言消息回调
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/9/24
|
||||
* @since 0.0.11
|
||||
*/
|
||||
public interface ISuperChatMsgListener<T, SuperChatMsg> {
|
||||
|
||||
/**
|
||||
* 收到醒目留言
|
||||
*/
|
||||
default void onSuperChatMsg(T t, SuperChatMsg msg) {
|
||||
this.onSuperChatMsg(msg);
|
||||
}
|
||||
|
||||
default void onSuperChatMsg(SuperChatMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public abstract class BaseCmdMsg<CmdEnum extends Enum<CmdEnum>> extends BaseMsg
|
||||
implements ICmdMsg<CmdEnum> {
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public abstract class BaseMsg implements IMsg {
|
||||
|
||||
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return OBJECT_MAPPER.writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/10/2
|
||||
*/
|
||||
public interface ICmdMsg<CmdEnum extends Enum<CmdEnum>> extends IMsg {
|
||||
|
||||
String getCmd();
|
||||
|
||||
void setCmd(String cmd);
|
||||
|
||||
CmdEnum getCmdEnum();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/8
|
||||
*/
|
||||
public interface IDanmuMsg extends IMsg {
|
||||
|
||||
/**
|
||||
* 粉丝牌名称
|
||||
*/
|
||||
String getBadgeName();
|
||||
|
||||
/**
|
||||
* 粉丝牌等级
|
||||
*/
|
||||
byte getBadgeLevel();
|
||||
|
||||
/**
|
||||
* 弹幕发送者id
|
||||
*/
|
||||
String getUid();
|
||||
|
||||
/**
|
||||
* 弹幕发送者用户名
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* 弹幕发送者头像地址
|
||||
*
|
||||
* @since 0.0.11
|
||||
*/
|
||||
default String getUserAvatar() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹幕内容
|
||||
*/
|
||||
String getContent();
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* 入房消息
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/12/26
|
||||
* @since 0.0.16
|
||||
*/
|
||||
public interface IEnterRoomMsg extends IMsg {
|
||||
|
||||
/**
|
||||
* 粉丝牌名称
|
||||
*/
|
||||
String getBadgeName();
|
||||
|
||||
/**
|
||||
* 粉丝牌等级
|
||||
*/
|
||||
byte getBadgeLevel();
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
String getUid();
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* 头像地址
|
||||
*/
|
||||
default String getUserAvatar() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/8
|
||||
*/
|
||||
public interface IGiftMsg extends IMsg {
|
||||
|
||||
/**
|
||||
* 粉丝牌名称
|
||||
*/
|
||||
default String getBadgeName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 粉丝牌等级
|
||||
*/
|
||||
default byte getBadgeLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送方id
|
||||
*/
|
||||
String getUid();
|
||||
|
||||
/**
|
||||
* 发送方用户名
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* 发送方头像地址
|
||||
*
|
||||
* @since 0.0.11
|
||||
*/
|
||||
default String getUserAvatar() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 礼物名称
|
||||
*/
|
||||
String getGiftName();
|
||||
|
||||
/**
|
||||
* 礼物图像地址
|
||||
*/
|
||||
String getGiftImg();
|
||||
|
||||
/**
|
||||
* 礼物id
|
||||
*/
|
||||
String getGiftId();
|
||||
|
||||
/**
|
||||
* 礼物数量
|
||||
*/
|
||||
int getGiftCount();
|
||||
|
||||
/**
|
||||
* 单个礼物价格
|
||||
*/
|
||||
int getGiftPrice();
|
||||
|
||||
/**
|
||||
* 接收方id
|
||||
*/
|
||||
String getReceiveUid();
|
||||
|
||||
/**
|
||||
* 接收方用户名
|
||||
*/
|
||||
String getReceiveUsername();
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/31
|
||||
* @since 0.2.0
|
||||
*/
|
||||
public interface ILikeMsg extends IMsg {
|
||||
|
||||
/**
|
||||
* 粉丝牌名称
|
||||
*/
|
||||
default String getBadgeName(){
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 粉丝牌等级
|
||||
*/
|
||||
default byte getBadgeLevel(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 点赞者id
|
||||
*/
|
||||
String getUid();
|
||||
|
||||
/**
|
||||
* 点赞者用户名
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* 点赞者头像地址
|
||||
*/
|
||||
default String getUserAvatar() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 点赞数
|
||||
*/
|
||||
default int getClickCount() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public interface IMsg extends Serializable {
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.commons.base.msg;
|
||||
|
||||
/**
|
||||
* 醒目留言
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/9/22
|
||||
*/
|
||||
public interface ISuperChatMsg extends IDanmuMsg {
|
||||
|
||||
/**
|
||||
* 醒目留言持续时间,单位秒
|
||||
*/
|
||||
int getDuration();
|
||||
|
||||
@Override
|
||||
default String getBadgeName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
default byte getBadgeLevel() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-commons-client</artifactId>
|
||||
<name>live-chat-client-commons-client</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons-base</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons-util</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
* 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.commons.client;
|
||||
|
||||
import lombok.Getter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.config.BaseLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.enums.ClientStatusEnums;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public abstract class BaseLiveChatClient<
|
||||
Config extends BaseLiveChatClientConfig,
|
||||
MsgListener extends IBaseMsgListener<?, ?>
|
||||
> implements IBaseLiveChatClient<MsgListener> {
|
||||
|
||||
private final Config config;
|
||||
@Getter
|
||||
private volatile ClientStatusEnums status = ClientStatusEnums.NEW;
|
||||
protected PropertyChangeSupport statusChangeSupport = new PropertyChangeSupport(status);
|
||||
protected volatile boolean cancelReconnect = false;
|
||||
protected final List<MsgListener> msgListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
protected BaseLiveChatClient(Config config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(Runnable success) {
|
||||
this.connect(success, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() {
|
||||
this.connect(null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(boolean cancelReconnect) {
|
||||
this.cancelReconnect = cancelReconnect;
|
||||
this.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object msg) {
|
||||
this.send(msg, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object msg, Runnable success) {
|
||||
this.send(msg, success, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object msg, Consumer<Throwable> failed) {
|
||||
this.send(msg, null, failed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu) {
|
||||
this.sendDanmu(danmu, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu, Runnable success) {
|
||||
this.sendDanmu(danmu, success, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu, Consumer<Throwable> failed) {
|
||||
this.sendDanmu(danmu, null, failed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickLike(int count) {
|
||||
this.clickLike(count, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickLike(int count, Runnable success) {
|
||||
this.clickLike(count, success, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickLike(int count, Consumer<Throwable> failed) {
|
||||
this.clickLike(count, null, failed);
|
||||
}
|
||||
|
||||
protected abstract void tryReconnect();
|
||||
|
||||
protected abstract String getWebSocketUriString();
|
||||
|
||||
/**
|
||||
* 判断是否处于某个状态,或者处于后续状态
|
||||
*
|
||||
* @param status {@link ClientStatusEnums}
|
||||
* @return false: 还没有到达该状态
|
||||
*/
|
||||
protected boolean checkStatus(ClientStatusEnums status) {
|
||||
return this.status.getCode() >= Objects.requireNonNull(status).getCode();
|
||||
}
|
||||
|
||||
protected void setStatus(ClientStatusEnums status) {
|
||||
ClientStatusEnums oldStatus = this.status;
|
||||
if (oldStatus != status) {
|
||||
this.status = status;
|
||||
this.statusChangeSupport.firePropertyChange("status", oldStatus, status);
|
||||
}
|
||||
}
|
||||
|
||||
public void addStatusChangeListener(PropertyChangeListener listener) {
|
||||
this.statusChangeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void removeStatusChangeListener(PropertyChangeListener listener) {
|
||||
this.statusChangeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
for (PropertyChangeListener propertyChangeListener : this.statusChangeSupport.getPropertyChangeListeners()) {
|
||||
this.statusChangeSupport.removePropertyChangeListener(propertyChangeListener);
|
||||
}
|
||||
this.msgListeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addMsgListener(MsgListener msgListener) {
|
||||
if (msgListener == null) {
|
||||
return false;
|
||||
}
|
||||
return this.msgListeners.add(msgListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addMsgListeners(List<MsgListener> msgListeners) {
|
||||
if (msgListeners == null || msgListeners.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return this.msgListeners.addAll(msgListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMsgListener(MsgListener msgListener) {
|
||||
if (msgListener == null) {
|
||||
return false;
|
||||
}
|
||||
return this.msgListeners.remove(msgListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMsgListeners(List<MsgListener> msgListeners) {
|
||||
if (msgListeners == null || msgListeners.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return this.msgListeners.removeAll(msgListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllMsgListeners() {
|
||||
this.msgListeners.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* 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.commons.client;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseMsgListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/5
|
||||
*/
|
||||
public interface IBaseLiveChatClient<MsgListener extends IBaseMsgListener<?, ?>> {
|
||||
|
||||
void init();
|
||||
|
||||
boolean addMsgListener(MsgListener msgListener);
|
||||
|
||||
boolean addMsgListeners(List<MsgListener> msgListeners);
|
||||
|
||||
boolean removeMsgListener(MsgListener msgListener);
|
||||
|
||||
boolean removeMsgListeners(List<MsgListener> msgListeners);
|
||||
|
||||
void removeAllMsgListeners();
|
||||
|
||||
void connect(Runnable success, Consumer<Throwable> failed);
|
||||
|
||||
void connect(Runnable success);
|
||||
|
||||
void connect();
|
||||
|
||||
/**
|
||||
* 手动断开连接
|
||||
*
|
||||
* @param cancelReconnect 取消本次的自动重连(如果启用自动重连)
|
||||
*/
|
||||
void disconnect(boolean cancelReconnect);
|
||||
|
||||
void disconnect();
|
||||
|
||||
void destroy();
|
||||
|
||||
void send(Object msg);
|
||||
|
||||
void send(Object msg, Runnable success, Consumer<Throwable> failed);
|
||||
|
||||
void send(Object msg, Runnable success);
|
||||
|
||||
void send(Object msg, Consumer<Throwable> failed);
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param danmu 弹幕内容
|
||||
* @since 0.0.6
|
||||
*/
|
||||
void sendDanmu(Object danmu);
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param danmu 弹幕内容
|
||||
* @since 0.0.6
|
||||
*/
|
||||
void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed);
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param danmu 弹幕内容
|
||||
* @since 0.0.6
|
||||
*/
|
||||
void sendDanmu(Object danmu, Runnable success);
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param danmu 弹幕内容
|
||||
* @since 0.0.6
|
||||
*/
|
||||
void sendDanmu(Object danmu, Consumer<Throwable> failed);
|
||||
|
||||
/**
|
||||
* 为直播间点赞
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
void clickLike(int count);
|
||||
|
||||
/**
|
||||
* 为直播间点赞
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
void clickLike(int count, Runnable success, Consumer<Throwable> failed);
|
||||
|
||||
/**
|
||||
* 为直播间点赞
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
void clickLike(int count, Runnable success);
|
||||
|
||||
/**
|
||||
* 为直播间点赞
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
void clickLike(int count, Consumer<Throwable> failed);
|
||||
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* 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.commons.client.config;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
/**
|
||||
* 直播间弹幕客户端配置
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public abstract class BaseLiveChatClientConfig {
|
||||
|
||||
protected PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
public static final long DEFAULT_HEARTBEAT_INITIAL_DELAY = 15;
|
||||
public static final long DEFAULT_HEARTBEAT_PERIOD = 25;
|
||||
public static final long DEFAULT_MIN_SEND_DANMU_PERIOD = 3000L;
|
||||
|
||||
private String websocketUri;
|
||||
|
||||
/**
|
||||
* 浏览器中的Cookie
|
||||
*/
|
||||
private String cookie;
|
||||
|
||||
/**
|
||||
* 直播间id
|
||||
*/
|
||||
private Object roomId;
|
||||
|
||||
/**
|
||||
* 是否启用自动重连
|
||||
*/
|
||||
@Builder.Default
|
||||
private boolean autoReconnect = Boolean.TRUE;
|
||||
|
||||
/**
|
||||
* 重试延迟时间(秒),默认5s后重试
|
||||
*/
|
||||
@Builder.Default
|
||||
private int reconnectDelay = 5;
|
||||
|
||||
/**
|
||||
* 首次发送心跳包的延迟时间(秒)
|
||||
*/
|
||||
@Builder.Default
|
||||
private long heartbeatInitialDelay = DEFAULT_HEARTBEAT_INITIAL_DELAY;
|
||||
|
||||
/**
|
||||
* 心跳包发送周期(秒)
|
||||
*/
|
||||
@Builder.Default
|
||||
private long heartbeatPeriod = DEFAULT_HEARTBEAT_PERIOD;
|
||||
|
||||
/**
|
||||
* 最小发送弹幕时间间隔(毫秒)
|
||||
*/
|
||||
@Builder.Default
|
||||
private long minSendDanmuPeriod = DEFAULT_MIN_SEND_DANMU_PERIOD;
|
||||
|
||||
public void setCookie(String cookie) {
|
||||
String oldValue = this.cookie;
|
||||
this.cookie = cookie;
|
||||
this.propertyChangeSupport.firePropertyChange("cookie", oldValue, cookie);
|
||||
}
|
||||
|
||||
public void setRoomId(Object roomId) {
|
||||
if (!(roomId instanceof Number || roomId instanceof String)) {
|
||||
throw new BaseException("房间ID仅支持数字或字符串,所传参数类型:" + roomId.getClass() + "值:" + roomId);
|
||||
}
|
||||
Object oldValue = this.roomId;
|
||||
this.roomId = roomId;
|
||||
this.propertyChangeSupport.firePropertyChange("roomId", oldValue, roomId);
|
||||
}
|
||||
|
||||
public void setWebsocketUri(String websocketUri) {
|
||||
String oldValue = this.websocketUri;
|
||||
this.websocketUri = websocketUri;
|
||||
this.propertyChangeSupport.firePropertyChange("websocketUri", oldValue, websocketUri);
|
||||
}
|
||||
|
||||
public void setMinSendDanmuPeriod(long minSendDanmuPeriod) {
|
||||
long oldValue = this.minSendDanmuPeriod;
|
||||
this.minSendDanmuPeriod = minSendDanmuPeriod;
|
||||
this.propertyChangeSupport.firePropertyChange("minSendDanmuPeriod", oldValue, minSendDanmuPeriod);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
this.propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
this.propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
this.propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
this.propertyChangeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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.commons.client.enums;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public enum ClientStatusEnums {
|
||||
/**
|
||||
* 新创建
|
||||
*/
|
||||
NEW(0),
|
||||
|
||||
/**
|
||||
* 已初始化
|
||||
*/
|
||||
INITIALIZED(1),
|
||||
|
||||
/**
|
||||
* 连接中
|
||||
*/
|
||||
CONNECTING(100),
|
||||
|
||||
/**
|
||||
* 重新连接中
|
||||
*/
|
||||
RECONNECTING(101),
|
||||
|
||||
/**
|
||||
* 已连接
|
||||
*/
|
||||
CONNECTED(200),
|
||||
|
||||
/**
|
||||
* 连接失败
|
||||
*/
|
||||
CONNECT_FAILED(401),
|
||||
|
||||
/**
|
||||
* 已断开连接
|
||||
*/
|
||||
DISCONNECTED(400),
|
||||
|
||||
/**
|
||||
* 已销毁
|
||||
*/
|
||||
DESTROYED(-1),
|
||||
;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
ClientStatusEnums(int order) {
|
||||
this.code = order;
|
||||
}
|
||||
|
||||
private final int code;
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-commons-util</artifactId>
|
||||
<name>live-chat-client-commons-util</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* 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.commons.util;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.net.HttpCookie;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/27
|
||||
*/
|
||||
public class OrLiveChatCookieUtil {
|
||||
|
||||
public static String toString(List<HttpCookie> cookies) {
|
||||
if (CollUtil.isEmpty(cookies)) {
|
||||
return StrUtil.EMPTY;
|
||||
}
|
||||
|
||||
return cookies.stream().map(httpCookie -> {
|
||||
httpCookie.setVersion(0);
|
||||
return httpCookie.toString();
|
||||
}).collect(Collectors.joining("; "));
|
||||
}
|
||||
|
||||
public static Map<String, String> parseCookieString(String cookies) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (StrUtil.isNotBlank(cookies) && !StrUtil.isNullOrUndefined(cookies)) {
|
||||
try {
|
||||
String[] split = cookies.split("; ");
|
||||
for (String s : split) {
|
||||
String[] split1 = s.split("=");
|
||||
map.put(split1[0], split1[1]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("cookie解析失败 " + cookies, e);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static String getCookieByName(Map<String, String> cookieMap, String name, Supplier<String> supplier) {
|
||||
String str = MapUtil.getStr(cookieMap, name);
|
||||
return str == null ? supplier.get() : str;
|
||||
}
|
||||
|
||||
public static String getCookieByName(String cookie, String name, Supplier<String> supplier) {
|
||||
String str = MapUtil.getStr(parseCookieString(cookie), name);
|
||||
return str == null ? supplier.get() : str;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.commons.util;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/12/2
|
||||
*/
|
||||
public class OrLiveChatNumberUtil extends NumberUtil {
|
||||
|
||||
public static long parseLong(Object object){
|
||||
return NumberUtil.parseLong(StrUtil.toStringOrNull(object));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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.commons.util;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/28
|
||||
*/
|
||||
public class OrLiveChatReflectUtil extends ReflectUtil {
|
||||
|
||||
public static Method getGetterMethod(Class<?> objectClass, String key) {
|
||||
Method method;
|
||||
if (key.startsWith("is")) {
|
||||
method = ReflectUtil.getMethodByNameIgnoreCase(objectClass, key);
|
||||
if (method == null) {
|
||||
ReflectUtil.getMethodByNameIgnoreCase(objectClass, "get" + key);
|
||||
}
|
||||
} else {
|
||||
method = ReflectUtil.getMethodByNameIgnoreCase(objectClass, "get" + key);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.commons.util;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/7
|
||||
*/
|
||||
public class OrLocalDateTimeUtil extends LocalDateTimeUtil {
|
||||
|
||||
public static ZoneId ZONE_ID_CTT = ZoneId.of(ZoneId.SHORT_IDS.get("CTT"));
|
||||
|
||||
/**
|
||||
* 获取中国标准时间的当前时间戳(毫秒)
|
||||
*/
|
||||
public static long zonedCurrentTimeMillis() {
|
||||
ZonedDateTime now = ZonedDateTime.now(ZONE_ID_CTT);
|
||||
return now.toEpochSecond() * 1000 + now.getNano() / 1_000_000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取中国标准时间的当前时间戳(秒)
|
||||
*/
|
||||
public static long zonedCurrentTimeSecs() {
|
||||
return ZonedDateTime.now(ZONE_ID_CTT).toEpochSecond();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common-live</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>live-chat-client-commons</artifactId>
|
||||
|
||||
<modules>
|
||||
<module>live-chat-client-commons-base</module>
|
||||
<module>live-chat-client-commons-util</module>
|
||||
<module>live-chat-client-commons-client</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -1,55 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-servers</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-servers-netty-client</artifactId>
|
||||
<name>live-chat-client-servers-netty</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-servers-netty</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.client.base;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.http.HttpClientCodec;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
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.commons.base.listener.IBaseMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.BaseLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.enums.ClientStatusEnums;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.config.BaseNettyClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.handler.base.BaseBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.handler.base.BaseConnectionHandler;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseNettyClient
|
||||
<Config extends BaseNettyClientConfig,
|
||||
CmdEnum extends Enum<CmdEnum>,
|
||||
Msg extends IMsg,
|
||||
MsgListener extends IBaseMsgListener<BinaryFrameHandler, CmdEnum>,
|
||||
ConnectionHandler extends BaseConnectionHandler<ConnectionHandler>,
|
||||
BinaryFrameHandler extends BaseBinaryFrameHandler<BinaryFrameHandler, CmdEnum, Msg, MsgListener>
|
||||
>
|
||||
extends BaseLiveChatClient<Config, MsgListener> {
|
||||
|
||||
@Getter
|
||||
private final EventLoopGroup workerGroup;
|
||||
@Getter
|
||||
private final Bootstrap bootstrap = new Bootstrap();
|
||||
private BinaryFrameHandler binaryFrameHandler;
|
||||
private ConnectionHandler connectionHandler;
|
||||
private IBaseConnectionListener<ConnectionHandler> connectionListener;
|
||||
private Channel channel;
|
||||
@Getter
|
||||
private URI websocketUri;
|
||||
protected IBaseConnectionListener<ConnectionHandler> clientConnectionListener;
|
||||
/**
|
||||
* 控制弹幕发送频率
|
||||
*/
|
||||
private volatile long lastSendDanmuTimeInMillis;
|
||||
|
||||
public abstract ConnectionHandler initConnectionHandler(IBaseConnectionListener<ConnectionHandler> clientConnectionListener);
|
||||
|
||||
public abstract BinaryFrameHandler initBinaryFrameHandler();
|
||||
|
||||
protected BaseNettyClient(Config config, EventLoopGroup workerGroup, IBaseConnectionListener<ConnectionHandler> connectionListener) {
|
||||
super(config);
|
||||
this.workerGroup = workerGroup;
|
||||
this.connectionListener = connectionListener;
|
||||
}
|
||||
|
||||
public void onConnected(ConnectionHandler connectionHandler) {
|
||||
this.setStatus(ClientStatusEnums.CONNECTED);
|
||||
if (this.connectionListener != null) {
|
||||
this.connectionListener.onConnected(connectionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
public void onConnectFailed(ConnectionHandler connectionHandler) {
|
||||
this.setStatus(ClientStatusEnums.CONNECT_FAILED);
|
||||
tryReconnect();
|
||||
if (this.connectionListener != null) {
|
||||
this.connectionListener.onConnectFailed(connectionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisconnected(ConnectionHandler connectionHandler) {
|
||||
this.setStatus(ClientStatusEnums.DISCONNECTED);
|
||||
tryReconnect();
|
||||
if (this.connectionListener != null) {
|
||||
this.connectionListener.onDisconnected(connectionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (checkStatus(ClientStatusEnums.INITIALIZED)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.websocketUri = new URI(getWebSocketUriString());
|
||||
SslContext sslCtx = SslContextBuilder.forClient().build();
|
||||
|
||||
this.clientConnectionListener = new IBaseConnectionListener<ConnectionHandler>() {
|
||||
@Override
|
||||
public void onConnected(ConnectionHandler connectionHandler) {
|
||||
BaseNettyClient.this.onConnected(connectionHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectFailed(ConnectionHandler connectionHandler) {
|
||||
BaseNettyClient.this.onConnectFailed(connectionHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(ConnectionHandler connectionHandler) {
|
||||
BaseNettyClient.this.onDisconnected(connectionHandler);
|
||||
}
|
||||
};
|
||||
this.binaryFrameHandler = this.initBinaryFrameHandler();
|
||||
this.connectionHandler = this.initConnectionHandler(this.clientConnectionListener);
|
||||
|
||||
this.bootstrap.group(this.workerGroup)
|
||||
// 创建Channel
|
||||
.channel(NioSocketChannel.class)
|
||||
.remoteAddress(this.websocketUri.getHost(), getInetPort())
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.option(ChannelOption.SO_KEEPALIVE, true)
|
||||
// Channel配置
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
// 责任链
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
|
||||
// 放到第一位 addFirst 支持wss链接服务端
|
||||
pipeline.addFirst(sslCtx.newHandler(ch.alloc(), BaseNettyClient.this.websocketUri.getHost(), getInetPort()));
|
||||
|
||||
// 添加一个http的编解码器
|
||||
pipeline.addLast(new HttpClientCodec());
|
||||
// 添加一个用于支持大数据流的支持
|
||||
pipeline.addLast(new ChunkedWriteHandler());
|
||||
// 添加一个聚合器,这个聚合器主要是将HttpMessage聚合成FullHttpRequest/Response
|
||||
pipeline.addLast(new HttpObjectAggregator(BaseNettyClient.this.getConfig().getAggregatorMaxContentLength()));
|
||||
|
||||
// 连接处理器
|
||||
pipeline.addLast(BaseNettyClient.this.connectionHandler);
|
||||
// 弹幕处理器
|
||||
pipeline.addLast(BaseNettyClient.this.binaryFrameHandler);
|
||||
}
|
||||
});
|
||||
this.setStatus(ClientStatusEnums.INITIALIZED);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new BaseException(e);
|
||||
} catch (SSLException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private int getInetPort() {
|
||||
int port = this.websocketUri.getPort();
|
||||
return port == -1 ? "wss".equalsIgnoreCase(websocketUri.getScheme()) ? 443 : 80 : port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(Runnable success, Consumer<Throwable> failed) {
|
||||
if (this.cancelReconnect) {
|
||||
this.cancelReconnect = false;
|
||||
}
|
||||
if (!checkStatus(ClientStatusEnums.INITIALIZED)) {
|
||||
return;
|
||||
}
|
||||
if (getStatus() == ClientStatusEnums.CONNECTED) {
|
||||
return;
|
||||
}
|
||||
if (getStatus() != ClientStatusEnums.RECONNECTING) {
|
||||
this.setStatus(ClientStatusEnums.CONNECTING);
|
||||
}
|
||||
this.bootstrap.connect().addListener((ChannelFutureListener) connectFuture -> {
|
||||
if (connectFuture.isSuccess()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("连接建立成功!");
|
||||
}
|
||||
this.channel = connectFuture.channel();
|
||||
// 监听是否握手成功
|
||||
this.connectionHandler.getHandshakeFuture().addListener((ChannelFutureListener) handshakeFuture -> {
|
||||
try {
|
||||
connectionHandler.sendAuthRequest(channel);
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("认证包发送失败,断开连接", e);
|
||||
this.disconnect();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
log.error("连接建立失败", connectFuture.cause());
|
||||
this.onConnectFailed(this.connectionHandler);
|
||||
if (failed != null) {
|
||||
failed.accept(connectFuture.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
if (this.channel == null) {
|
||||
return;
|
||||
}
|
||||
this.channel.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tryReconnect() {
|
||||
if (this.cancelReconnect) {
|
||||
this.cancelReconnect = false;
|
||||
return;
|
||||
}
|
||||
if (!getConfig().isAutoReconnect()) {
|
||||
return;
|
||||
}
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("{}s后将重新连接 {}", getConfig().getReconnectDelay(), getConfig().getRoomId());
|
||||
}
|
||||
workerGroup.schedule(() -> {
|
||||
this.setStatus(ClientStatusEnums.RECONNECTING);
|
||||
this.connect();
|
||||
}, getConfig().getReconnectDelay(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object msg, Runnable success, Consumer<Throwable> failed) {
|
||||
ChannelFuture future = this.channel.writeAndFlush(msg);
|
||||
if (success != null || failed != null) {
|
||||
future.addListener((ChannelFutureListener) channelFuture -> {
|
||||
if (channelFuture.isSuccess()) {
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
} else {
|
||||
if (failed != null) {
|
||||
failed.accept(channelFuture.cause());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
|
||||
// 销毁时不需要重连
|
||||
this.cancelReconnect = true;
|
||||
workerGroup.shutdownGracefully().addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
this.setStatus(ClientStatusEnums.DESTROYED);
|
||||
} else {
|
||||
throw new BaseException("client销毁失败", future.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWebSocketUriString() {
|
||||
return getConfig().getWebsocketUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStatus(ClientStatusEnums status) {
|
||||
if (log.isDebugEnabled()) {
|
||||
if (getStatus() != status) {
|
||||
log.debug("{} 状态变化 {} => {}\n", getClass().getSimpleName(), getStatus(), status);
|
||||
}
|
||||
}
|
||||
super.setStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed) {
|
||||
throw new BaseException("暂未支持该功能");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clickLike(int count, Runnable success, Consumer<Throwable> failed) {
|
||||
throw new BaseException("暂未支持该功能");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送弹幕前判断是否可以发送
|
||||
*
|
||||
* @param checkConnected 是否检查Client连接状态
|
||||
*/
|
||||
protected boolean checkCanSendDanmu(boolean checkConnected) {
|
||||
if (checkConnected && getStatus() != ClientStatusEnums.CONNECTED) {
|
||||
throw new BaseException("连接未建立,无法发送弹幕");
|
||||
}
|
||||
if (System.currentTimeMillis() - this.lastSendDanmuTimeInMillis <= getConfig().getMinSendDanmuPeriod()) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("发送弹幕频率过快,忽略该次发送");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean checkCanSendDanmu() {
|
||||
return checkCanSendDanmu(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送弹幕后调用该方法
|
||||
*/
|
||||
protected void finishSendDanmu() {
|
||||
this.lastSendDanmuTimeInMillis = System.currentTimeMillis();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("弹幕发送完成");
|
||||
}
|
||||
}
|
||||
|
||||
public void iteratorMsgListeners(Consumer<MsgListener> consumer) {
|
||||
binaryFrameHandler.iteratorMsgListeners(consumer);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.client.config;
|
||||
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import tech.ordinaryroad.live.chat.client.commons.client.config.BaseLiveChatClientConfig;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public abstract class BaseNettyClientConfig extends BaseLiveChatClientConfig {
|
||||
|
||||
/**
|
||||
* 聚合器允许的最大消息体长度,默认 64*1024 byte
|
||||
*
|
||||
* @see HttpObjectAggregator#HttpObjectAggregator(int)
|
||||
*/
|
||||
@Builder.Default
|
||||
private int aggregatorMaxContentLength = 64 * 1024;
|
||||
|
||||
/**
|
||||
* WebSocketClientHandshaker最大消息体长度,默认 64*1024 byte
|
||||
*
|
||||
* @see WebSocketClientHandshakerFactory#newHandshaker(URI, WebSocketVersion, String, boolean, HttpHeaders, int)
|
||||
*/
|
||||
@Builder.Default
|
||||
private int maxFramePayloadLength = 64 * 1024;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.client.handler;
|
||||
|
||||
import lombok.Getter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.base.BaseNettyClient;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.handler.base.BaseBinaryFrameHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BaseClientBinaryFrameHandler
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/30
|
||||
*/
|
||||
public abstract class BaseNettyClientBinaryFrameHandler<
|
||||
Client extends BaseNettyClient<?, ?, ?, ?, ?, ?>,
|
||||
BinaryFrameHandler extends BaseBinaryFrameHandler<BinaryFrameHandler, CmdEnum, Msg, MsgListener>,
|
||||
CmdEnum extends Enum<CmdEnum>,
|
||||
Msg extends IMsg,
|
||||
MsgListener extends IBaseMsgListener<BinaryFrameHandler, CmdEnum>>
|
||||
extends BaseBinaryFrameHandler<BinaryFrameHandler, CmdEnum, Msg, MsgListener> {
|
||||
|
||||
@Getter
|
||||
protected final Client client;
|
||||
|
||||
public BaseNettyClientBinaryFrameHandler(List<MsgListener> msgListeners, Client client, long roomId) {
|
||||
super(msgListeners, roomId);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public BaseNettyClientBinaryFrameHandler(List<MsgListener> msgListeners, Client client) {
|
||||
super(msgListeners, client.getConfig().getRoomId());
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public BaseNettyClientBinaryFrameHandler(List<MsgListener> msgListeners, long roomId) {
|
||||
super(msgListeners, roomId);
|
||||
this.client = null;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.client.handler;
|
||||
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||
import lombok.Getter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.base.BaseNettyClient;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.handler.base.BaseConnectionHandler;
|
||||
|
||||
/**
|
||||
* BaseClientConnectionHandler
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/27
|
||||
*/
|
||||
public abstract class BaseNettyClientConnectionHandler<
|
||||
Client extends BaseNettyClient<?, ?, ?, ?, ?, ?>,
|
||||
ConnectionHandler extends BaseConnectionHandler<ConnectionHandler>>
|
||||
extends BaseConnectionHandler<ConnectionHandler> {
|
||||
|
||||
@Getter
|
||||
protected final Client client;
|
||||
|
||||
public BaseNettyClientConnectionHandler(WebSocketClientHandshaker handshaker, Client client, IBaseConnectionListener<ConnectionHandler> listener) {
|
||||
super(handshaker, listener);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public BaseNettyClientConnectionHandler(WebSocketClientHandshaker handshaker, Client client) {
|
||||
this(handshaker, client, null);
|
||||
}
|
||||
|
||||
public BaseNettyClientConnectionHandler(WebSocketClientHandshaker handshaker, IBaseConnectionListener<ConnectionHandler> listener) {
|
||||
super(handshaker, listener);
|
||||
this.client = null;
|
||||
}
|
||||
|
||||
public BaseNettyClientConnectionHandler(WebSocketClientHandshaker handshaker, long roomId) {
|
||||
super(handshaker, null);
|
||||
this.client = null;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-servers</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-servers-netty</artifactId>
|
||||
<name>live-chat-client-servers-netty</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-commons-base</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.frame.base;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
public abstract class BaseBinaryWebSocketFrame extends BinaryWebSocketFrame {
|
||||
|
||||
public BaseBinaryWebSocketFrame(ByteBuf byteBuf) {
|
||||
super(byteBuf);
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.handler.base;
|
||||
|
||||
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseCmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
/**
|
||||
* 消息处理器
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/1/4
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseBinaryFrameHandler<
|
||||
T extends BaseBinaryFrameHandler<?, ?, ?, ?>,
|
||||
CmdEnum extends Enum<CmdEnum>,
|
||||
Msg extends IMsg,
|
||||
MsgListener extends IBaseMsgListener<T, CmdEnum>
|
||||
> extends SimpleChannelInboundHandler<BinaryWebSocketFrame>
|
||||
implements IBaseMsgListener<T, CmdEnum> {
|
||||
|
||||
@Getter
|
||||
private final Object roomId;
|
||||
protected final List<MsgListener> msgListeners;
|
||||
|
||||
public BaseBinaryFrameHandler(List<MsgListener> msgListeners, Object roomId) {
|
||||
this.msgListeners = msgListeners;
|
||||
this.roomId = roomId;
|
||||
if (this.msgListeners == null || this.msgListeners.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("listener not set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码收到的二进制流
|
||||
*
|
||||
* @param byteBuf ByteBuf
|
||||
* @return List<Msg>
|
||||
*/
|
||||
protected abstract List<Msg> decode(ByteBuf byteBuf);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame message) {
|
||||
ByteBuf byteBuf = message.content();
|
||||
List<Msg> msgList = this.decode(byteBuf);
|
||||
if (msgList == null || msgList.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("msgList is empty");
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (Msg msg : msgList) {
|
||||
this.onMsg((T) BaseBinaryFrameHandler.this, msg);
|
||||
if (msg instanceof ICmdMsg<?>) {
|
||||
ICmdMsg<?> cmdMsg = (ICmdMsg<?>) msg;
|
||||
Enum<?> cmdEnum = cmdMsg.getCmdEnum();
|
||||
if (cmdEnum == null) {
|
||||
this.onUnknownCmd((T) BaseBinaryFrameHandler.this, cmdMsg.getCmd(), cmdMsg);
|
||||
} else {
|
||||
this.onCmdMsg((T) BaseBinaryFrameHandler.this, (CmdEnum) cmdEnum, (ICmdMsg<CmdEnum>) cmdMsg);
|
||||
}
|
||||
}
|
||||
if (msg instanceof BaseCmdMsg<?>) {
|
||||
BaseCmdMsg<?> cmdMsg = (BaseCmdMsg<?>) msg;
|
||||
Enum<?> cmdEnum = cmdMsg.getCmdEnum();
|
||||
if (cmdEnum == null) {
|
||||
this.onUnknownCmd((T) BaseBinaryFrameHandler.this, cmdMsg.getCmd(), cmdMsg);
|
||||
} else {
|
||||
this.onCmdMsg((T) BaseBinaryFrameHandler.this, (CmdEnum) cmdEnum, (BaseCmdMsg<CmdEnum>) cmdMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (cause.getCause() instanceof UnrecognizedPropertyException) {
|
||||
log.error("缺少字段:{}", cause.getMessage());
|
||||
} else {
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsg(T t, IMsg msg) {
|
||||
IBaseMsgListener.super.onMsg(t, msg);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onMsg(t, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写该方法,判断CMD,或者调用{@link IBaseMsgListener#onOtherCmdMsg(Object, Enum, ICmdMsg)}
|
||||
*
|
||||
* @param t BaseBinaryFrameHandler
|
||||
* @param cmd CmdEnum
|
||||
* @param cmdMsg BaseMsg
|
||||
*/
|
||||
@Override
|
||||
public void onCmdMsg(T t, CmdEnum cmd, ICmdMsg<CmdEnum> cmdMsg) {
|
||||
IBaseMsgListener.super.onCmdMsg(t, cmd, cmdMsg);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onCmdMsg(t, cmd, cmdMsg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownCmd(T t, String cmdString, IMsg msg) {
|
||||
IBaseMsgListener.super.onUnknownCmd(t, cmdString, msg);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onUnknownCmd(t, cmdString, msg));
|
||||
}
|
||||
|
||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||
public void iteratorMsgListeners(Consumer<MsgListener> consumer) {
|
||||
if (msgListeners.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < msgListeners.size(); i++) {
|
||||
consumer.accept(msgListeners.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCmdMsg(T t, CmdEnum cmd, BaseCmdMsg<CmdEnum> cmdMsg) {
|
||||
IBaseMsgListener.super.onCmdMsg(t, cmd, cmdMsg);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onCmdMsg(t, cmd, cmdMsg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownCmd(T t, String cmdString, BaseMsg msg) {
|
||||
IBaseMsgListener.super.onUnknownCmd(t, cmdString, msg);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onUnknownCmd(t, cmdString, msg));
|
||||
}
|
||||
|
||||
public String getRoomIdAsString() {
|
||||
if (this.roomId == null) {
|
||||
return "";
|
||||
}
|
||||
return this.roomId.toString();
|
||||
}
|
||||
|
||||
public long getRoomIdAsLong() {
|
||||
String roomIdAsString = this.getRoomIdAsString();
|
||||
if (roomIdAsString.trim().isEmpty()) {
|
||||
return 0L;
|
||||
}
|
||||
return Long.parseLong(roomIdAsString);
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* 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.servers.netty.handler.base;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException;
|
||||
import io.netty.handler.ssl.SslCloseCompletionEvent;
|
||||
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
||||
import io.netty.util.concurrent.ScheduledFuture;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* 连接处理器
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/21
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseConnectionHandler<ConnectionHandler extends BaseConnectionHandler<?>> extends SimpleChannelInboundHandler<FullHttpResponse> {
|
||||
|
||||
private final WebSocketClientHandshaker handshaker;
|
||||
@Getter
|
||||
private ChannelPromise handshakeFuture;
|
||||
private final IBaseConnectionListener<ConnectionHandler> listener;
|
||||
/**
|
||||
* 客户端发送心跳包
|
||||
*/
|
||||
private ScheduledFuture<?> scheduledFuture = null;
|
||||
|
||||
public BaseConnectionHandler(WebSocketClientHandshaker handshaker, IBaseConnectionListener<ConnectionHandler> listener) {
|
||||
this.handshaker = handshaker;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public BaseConnectionHandler(WebSocketClientHandshaker handshaker) {
|
||||
this(handshaker, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handlerAdded(ChannelHandlerContext ctx) {
|
||||
this.handshakeFuture = ctx.newPromise();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) {
|
||||
this.handshaker.handshake(ctx.channel());
|
||||
}
|
||||
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception {
|
||||
// 判断是否正确握手
|
||||
if (this.handshaker.isHandshakeComplete()) {
|
||||
handshakeSuccessfully(ctx, msg);
|
||||
} else {
|
||||
try {
|
||||
handshakeSuccessfully(ctx, msg);
|
||||
} catch (WebSocketHandshakeException e) {
|
||||
handshakeFailed(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("userEventTriggered {}", evt.getClass());
|
||||
}
|
||||
if (evt instanceof SslHandshakeCompletionEvent) {
|
||||
heartbeatCancel();
|
||||
heartbeatStart(ctx);
|
||||
if (this.listener != null) {
|
||||
listener.onConnected((ConnectionHandler) BaseConnectionHandler.this);
|
||||
}
|
||||
} else if (evt instanceof SslCloseCompletionEvent) {
|
||||
heartbeatCancel();
|
||||
if (this.listener != null) {
|
||||
listener.onDisconnected((ConnectionHandler) BaseConnectionHandler.this);
|
||||
}
|
||||
} else {
|
||||
log.error("待处理 {}", evt.getClass());
|
||||
}
|
||||
super.userEventTriggered(ctx, evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始发送心跳包
|
||||
*/
|
||||
private void heartbeatStart(ChannelHandlerContext ctx) {
|
||||
scheduledFuture = ctx.executor().scheduleAtFixedRate(() -> {
|
||||
sendHeartbeat(ctx);
|
||||
}, getHeartbeatInitialDelay(), getHeartbeatPeriod(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消发送心跳包
|
||||
*/
|
||||
private void heartbeatCancel() {
|
||||
if (null != scheduledFuture && !scheduledFuture.isCancelled()) {
|
||||
scheduledFuture.cancel(true);
|
||||
scheduledFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void sendHeartbeat(ChannelHandlerContext ctx);
|
||||
|
||||
public abstract void sendAuthRequest(Channel channel);
|
||||
|
||||
protected abstract long getHeartbeatPeriod();
|
||||
|
||||
protected abstract long getHeartbeatInitialDelay();
|
||||
|
||||
private void handshakeSuccessfully(ChannelHandlerContext ctx, FullHttpResponse msg) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("握手完成!");
|
||||
}
|
||||
this.handshaker.finishHandshake(ctx.channel(), msg);
|
||||
this.handshakeFuture.setSuccess();
|
||||
}
|
||||
|
||||
private void handshakeFailed(FullHttpResponse msg, WebSocketHandshakeException e) {
|
||||
log.error("握手失败!status:" + msg.status(), e);
|
||||
this.handshakeFuture.setFailure(e);
|
||||
if (listener != null) {
|
||||
this.listener.onConnectFailed((ConnectionHandler) this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
log.error("exceptionCaught", cause);
|
||||
if (!this.handshakeFuture.isDone()) {
|
||||
this.handshakeFuture.setFailure(cause);
|
||||
}
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common-live</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>live-chat-client-servers</artifactId>
|
||||
<name>live-chat-client-servers</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>live-chat-client-servers-netty</module>
|
||||
<module>live-chat-client-servers-netty-client</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -1,71 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-clients</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-bilibili</artifactId>
|
||||
<name>live-chat-client-bilibili</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-servers-netty-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aayushatharva.brotli4j</groupId>
|
||||
<artifactId>brotli4j</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.api;
|
||||
|
||||
import cn.hutool.cache.impl.TimedCache;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.api.request.BilibiliLikeReportV3Request;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.api.request.BilibiliSendMsgRequest;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.util.OrLiveChatCookieUtil;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg.OBJECT_MAPPER;
|
||||
|
||||
/**
|
||||
* B站API简易版
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/5/5
|
||||
*/
|
||||
@Slf4j
|
||||
public class BilibiliApis {
|
||||
|
||||
public static final TimedCache<Long, String> GIFT_IMG_CACHE = new TimedCache<>(TimeUnit.DAYS.toMillis(1));
|
||||
public static final String KEY_COOKIE_CSRF = "bili_jct";
|
||||
public static final String KEY_UID = "DedeUserID";
|
||||
|
||||
@SneakyThrows
|
||||
public static RoomInitResult roomInit(long roomId, String cookie) {
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://api.live.bilibili.com/room/v1/Room/room_init?id=" + roomId, cookie).execute();
|
||||
JsonNode dataJsonNode = responseInterceptor(response.body());
|
||||
return OBJECT_MAPPER.readValue(dataJsonNode.toString(), RoomInitResult.class);
|
||||
}
|
||||
|
||||
public static JsonNode roomGiftConfig(long roomId, String cookie) {
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/roomGiftConfig?platform=pc&source=live&build=0&global_version=0&room_id=" + roomId, cookie).execute();
|
||||
return responseInterceptor(response.body());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roomId
|
||||
* @param type 直播间用0
|
||||
* @return <pre>{@code
|
||||
* {
|
||||
* "group": "live",
|
||||
* "business_id": 0,
|
||||
* "refresh_row_factor": 0.125,
|
||||
* "refresh_rate": 100,
|
||||
* "max_delay": 5000,
|
||||
* "token": "-wm5-Qo4BBAztd1qp5ZJpgyTMRBhCc7yikz5d9rAd63PV46G9BMwl0R10kMM8Ilb-UieZGjLtipPrz4Cvi0DdhGFwOi8PJpFN9K-LoXh6Z_4yjEIwgRerDiMIstHzJ80J3B7wnRisAYkWA==",
|
||||
* "host_list": [{
|
||||
* "host": "ali-bj-live-comet-09.chat.bilibili.com",
|
||||
* "port": 2243,
|
||||
* "wss_port": 443,
|
||||
* "ws_port": 2244
|
||||
* }, {
|
||||
* "host": "ali-gz-live-comet-02.chat.bilibili.com",
|
||||
* "port": 2243,
|
||||
* "wss_port": 443,
|
||||
* "ws_port": 2244
|
||||
* }, {
|
||||
* "host": "broadcastlv.chat.bilibili.com",
|
||||
* "port": 2243,
|
||||
* "wss_port": 443,
|
||||
* "ws_port": 2244
|
||||
* }]
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public static JsonNode getDanmuInfo(long roomId, int type, String cookie) {
|
||||
@Cleanup
|
||||
HttpResponse response = createGetRequest("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo?id=" + roomId + "&type=" + type, cookie).execute();
|
||||
return responseInterceptor(response.body());
|
||||
}
|
||||
|
||||
public static String getGiftImgById(long giftId, long roomId) {
|
||||
if (!GIFT_IMG_CACHE.containsKey(giftId)) {
|
||||
ThreadUtil.execAsync(() -> {
|
||||
updateGiftImgCache(roomId, null);
|
||||
});
|
||||
}
|
||||
|
||||
return GIFT_IMG_CACHE.get(giftId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新礼物图片缓存
|
||||
*/
|
||||
public static void updateGiftImgCache(long roomId, String cookie) {
|
||||
JsonNode jsonNode = roomGiftConfig(roomId, cookie);
|
||||
for (JsonNode node : jsonNode.get("global_gift").get("list")) {
|
||||
long giftId = node.get("id").asLong();
|
||||
String giftImgUrl = node.get("webp").asText();
|
||||
GIFT_IMG_CACHE.put(giftId, giftImgUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param request {@link BilibiliSendMsgRequest}
|
||||
* @param cookie Cookie
|
||||
*/
|
||||
public static void sendMsg(BilibiliSendMsgRequest request, String cookie) {
|
||||
if (StrUtil.isBlank(cookie)) {
|
||||
throw new BaseException("发送弹幕接口cookie不能为空");
|
||||
}
|
||||
Map<String, Object> stringObjectMap = BeanUtil.beanToMap(request);
|
||||
@Cleanup HttpResponse execute = HttpUtil.createPost("https://api.live.bilibili.com/msg/send")
|
||||
.cookie(cookie)
|
||||
.form(stringObjectMap)
|
||||
.execute();
|
||||
responseInterceptor(execute.body());
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送弹幕
|
||||
*
|
||||
* @param msg 内容
|
||||
* @param realRoomId 真实房间id
|
||||
* @param cookie Cookie
|
||||
*/
|
||||
public static void sendMsg(String msg, long realRoomId, String cookie) {
|
||||
String biliJct = OrLiveChatCookieUtil.getCookieByName(cookie, KEY_COOKIE_CSRF, () -> {
|
||||
throw new BaseException("cookie中缺少参数" + KEY_COOKIE_CSRF);
|
||||
});
|
||||
BilibiliSendMsgRequest request = new BilibiliSendMsgRequest(msg, StrUtil.toString(ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).toEpochSecond()), realRoomId, biliJct, biliJct);
|
||||
sendMsg(request, cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为主播点赞
|
||||
*
|
||||
* @param request {@link BilibiliLikeReportV3Request}
|
||||
* @param cookie Cookie
|
||||
*/
|
||||
public static void likeReportV3(BilibiliLikeReportV3Request request, String cookie) {
|
||||
if (StrUtil.isBlank(cookie)) {
|
||||
throw new BaseException("为主播点赞接口cookie不能为空");
|
||||
}
|
||||
Map<String, Object> stringObjectMap = BeanUtil.beanToMap(request);
|
||||
@Cleanup HttpResponse execute = HttpUtil.createPost("https://api.live.bilibili.com/xlive/app-ucenter/v1/like_info_v3/like/likeReportV3")
|
||||
.cookie(cookie)
|
||||
.form(stringObjectMap)
|
||||
.execute();
|
||||
responseInterceptor(execute.body());
|
||||
}
|
||||
|
||||
/**
|
||||
* 为主播点赞
|
||||
*
|
||||
* @param anchor_id 主播Uid {@link RoomInitResult#uid}
|
||||
* @param realRoomId 真实房间Id {@link RoomInitResult#room_id}
|
||||
* @param cookie Cookie
|
||||
*/
|
||||
public static void likeReportV3(long anchor_id, long realRoomId, String cookie) {
|
||||
String uid = OrLiveChatCookieUtil.getCookieByName(cookie, KEY_UID, () -> {
|
||||
throw new BaseException("cookie中缺少参数" + KEY_UID);
|
||||
});
|
||||
String biliJct = OrLiveChatCookieUtil.getCookieByName(cookie, KEY_COOKIE_CSRF, () -> {
|
||||
throw new BaseException("cookie中缺少参数" + KEY_COOKIE_CSRF);
|
||||
});
|
||||
BilibiliLikeReportV3Request request = new BilibiliLikeReportV3Request(realRoomId, uid, anchor_id, biliJct, biliJct);
|
||||
likeReportV3(request, cookie);
|
||||
}
|
||||
|
||||
public static HttpRequest createGetRequest(String url, String cookies) {
|
||||
return HttpUtil.createGet(url)
|
||||
.cookie(cookies);
|
||||
}
|
||||
|
||||
private static JsonNode responseInterceptor(String responseString) {
|
||||
try {
|
||||
JsonNode jsonNode = OBJECT_MAPPER.readTree(responseString);
|
||||
int code = jsonNode.get("code").asInt();
|
||||
if (code == 0) {
|
||||
// 成功
|
||||
return jsonNode.get("data");
|
||||
} else {
|
||||
throw new BaseException(jsonNode.get("message").asText());
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class RoomInitResult {
|
||||
private long room_id;
|
||||
private int short_id;
|
||||
private long uid;
|
||||
private int need_p2p;
|
||||
private boolean is_hidden;
|
||||
private boolean is_locked;
|
||||
private boolean is_portrait;
|
||||
private int live_status;
|
||||
private int hidden_till;
|
||||
private int lock_till;
|
||||
private boolean encrypted;
|
||||
private boolean pwd_verified;
|
||||
private long live_time;
|
||||
private int room_shield;
|
||||
private int is_sp;
|
||||
private int special_type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.api.request;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/31
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class BilibiliLikeReportV3Request {
|
||||
/**
|
||||
* 本次点赞次数
|
||||
*/
|
||||
private int click_time = 1;
|
||||
/**
|
||||
* 房间真实ID
|
||||
*/
|
||||
private long room_id;
|
||||
/**
|
||||
* Cookie中的DedeUserID
|
||||
*/
|
||||
private String uid;
|
||||
/**
|
||||
* RoomInitResult中的uid
|
||||
*/
|
||||
private long anchor_id;
|
||||
/**
|
||||
* Cookie中的bili_jct
|
||||
*/
|
||||
private String csrf;
|
||||
/**
|
||||
* Cookie中的bili_jct
|
||||
*/
|
||||
private String csrf_token;
|
||||
/**
|
||||
* 暂时留空
|
||||
*/
|
||||
private String visit_id = StrUtil.EMPTY;
|
||||
|
||||
public BilibiliLikeReportV3Request(long room_id, String uid, long anchor_id, String csrf, String csrf_token) {
|
||||
this.room_id = room_id;
|
||||
this.uid = uid;
|
||||
this.anchor_id = anchor_id;
|
||||
this.csrf = csrf;
|
||||
this.csrf_token = csrf_token;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.api.request;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/7
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class BilibiliSendMsgRequest {
|
||||
private String bubble = "0";
|
||||
/**
|
||||
* 弹幕内容
|
||||
*/
|
||||
private String msg;
|
||||
/**
|
||||
* 弹幕颜色
|
||||
*/
|
||||
private String color = "16777215";
|
||||
private String mode = "1";
|
||||
private String room_type = "0";
|
||||
private String jumpfrom = "0";
|
||||
/**
|
||||
* 字体大小
|
||||
*/
|
||||
private String fontsize = "25";
|
||||
/**
|
||||
* 时间戳(秒)
|
||||
*/
|
||||
private String rnd;
|
||||
/**
|
||||
* 房间真实ID
|
||||
*/
|
||||
private long roomid;
|
||||
/**
|
||||
* Cookie中的bili_jct
|
||||
*/
|
||||
private String csrf;
|
||||
/**
|
||||
* Cookie中的bili_jct
|
||||
*/
|
||||
private String csrf_token;
|
||||
|
||||
public BilibiliSendMsgRequest(String msg, String rnd, long roomid, String csrf, String csrf_token) {
|
||||
this.msg = msg;
|
||||
this.rnd = rnd;
|
||||
this.roomid = roomid;
|
||||
this.csrf = csrf;
|
||||
this.csrf_token = csrf_token;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.client;
|
||||
|
||||
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.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.api.BilibiliApis;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.config.BilibiliLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.listener.IBilibiliConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.listener.IBilibiliMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.IBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliConnectionHandler;
|
||||
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.servers.netty.client.base.BaseNettyClient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* B站直播间弹幕客户端
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/20
|
||||
*/
|
||||
@Slf4j
|
||||
public class BilibiliLiveChatClient extends BaseNettyClient<
|
||||
BilibiliLiveChatClientConfig,
|
||||
BilibiliCmdEnum,
|
||||
IBilibiliMsg,
|
||||
IBilibiliMsgListener,
|
||||
BilibiliConnectionHandler,
|
||||
BilibiliBinaryFrameHandler
|
||||
> {
|
||||
|
||||
private BilibiliApis.RoomInitResult roomInitResult = new BilibiliApis.RoomInitResult();
|
||||
|
||||
public BilibiliLiveChatClient(BilibiliLiveChatClientConfig config, List<IBilibiliMsgListener> msgListeners, IBilibiliConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListeners(msgListeners);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public BilibiliLiveChatClient(BilibiliLiveChatClientConfig config, IBilibiliMsgListener msgListener, IBilibiliConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListener(msgListener);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public BilibiliLiveChatClient(BilibiliLiveChatClientConfig config, IBilibiliMsgListener msgListener, IBilibiliConnectionListener connectionListener) {
|
||||
this(config, msgListener, connectionListener, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public BilibiliLiveChatClient(BilibiliLiveChatClientConfig config, IBilibiliMsgListener msgListener) {
|
||||
this(config, msgListener, null, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public BilibiliLiveChatClient(BilibiliLiveChatClientConfig config) {
|
||||
this(config, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
roomInitResult = BilibiliApis.roomInit(getConfig().getRoomId(), getConfig().getCookie());
|
||||
super.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BilibiliConnectionHandler initConnectionHandler(IBaseConnectionListener<BilibiliConnectionHandler> clientConnectionListener) {
|
||||
return new BilibiliConnectionHandler(
|
||||
WebSocketClientHandshakerFactory.newHandshaker(getWebsocketUri(), WebSocketVersion.V13, null, true, new DefaultHttpHeaders(), getConfig().getMaxFramePayloadLength()),
|
||||
BilibiliLiveChatClient.this, clientConnectionListener
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BilibiliBinaryFrameHandler initBinaryFrameHandler() {
|
||||
return new BilibiliBinaryFrameHandler(super.msgListeners, BilibiliLiveChatClient.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed) {
|
||||
if (!checkCanSendDanmu(false)) {
|
||||
return;
|
||||
}
|
||||
if (danmu instanceof String) {
|
||||
String msg = (String) danmu;
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("{} bilibili发送弹幕 {}", getConfig().getRoomId(), danmu);
|
||||
}
|
||||
|
||||
boolean sendSuccess = false;
|
||||
try {
|
||||
BilibiliApis.sendMsg(msg, roomInitResult.getRoom_id(), getConfig().getCookie());
|
||||
sendSuccess = true;
|
||||
} catch (Exception e) {
|
||||
log.error("bilibili弹幕发送失败", e);
|
||||
if (failed != null) {
|
||||
failed.accept(e);
|
||||
}
|
||||
}
|
||||
if (!sendSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("bilibili弹幕发送成功 {}", danmu);
|
||||
}
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
finishSendDanmu();
|
||||
} catch (Exception e) {
|
||||
log.error("bilibili弹幕发送失败", 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 {
|
||||
BilibiliApis.likeReportV3(roomInitResult.getUid(), roomInitResult.getRoom_id(), getConfig().getCookie());
|
||||
successfullyClicked = true;
|
||||
} catch (Exception e) {
|
||||
log.error("Bilibili为直播间点赞失败", e);
|
||||
if (failed != null) {
|
||||
failed.accept(e);
|
||||
}
|
||||
}
|
||||
if (!successfullyClicked) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Bilibili为直播间点赞成功");
|
||||
}
|
||||
if (success != null) {
|
||||
success.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.commons.util.OrLiveChatNumberUtil;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.config.BaseNettyClientConfig;
|
||||
|
||||
/**
|
||||
* B站直播间弹幕客户端配置
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/21
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class BilibiliLiveChatClientConfig extends BaseNettyClientConfig {
|
||||
|
||||
/**
|
||||
* @see ProtoverEnum
|
||||
*/
|
||||
@Builder.Default
|
||||
private ProtoverEnum protover = ProtoverEnum.NORMAL_ZLIB;
|
||||
|
||||
@Builder.Default
|
||||
private String websocketUri = "wss://broadcastlv.chat.bilibili.com:443/sub";
|
||||
|
||||
@Override
|
||||
public Long getRoomId() {
|
||||
return OrLiveChatNumberUtil.parseLong(super.getRoomId());
|
||||
}
|
||||
|
||||
public void setProtover(ProtoverEnum protover) {
|
||||
ProtoverEnum oldValue = this.protover;
|
||||
this.protover = protover;
|
||||
super.propertyChangeSupport.firePropertyChange("protover", oldValue, protover);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.constant;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum BilibiliCmdEnum {
|
||||
/**
|
||||
* 游客状态下,5分钟后会出现登录提示,弹幕中的用户名、用户id等信息将不再可见
|
||||
*/
|
||||
LOG_IN_NOTICE,
|
||||
/**
|
||||
* 收到弹幕
|
||||
*/
|
||||
DANMU_MSG,
|
||||
/**
|
||||
* 收到礼物
|
||||
*/
|
||||
SEND_GIFT,
|
||||
/**
|
||||
* 有人上舰
|
||||
*/
|
||||
GUARD_BUY,
|
||||
/**
|
||||
* 欢迎舰长
|
||||
*/
|
||||
WELCOME_GUARD,
|
||||
WELCOME,
|
||||
/**
|
||||
* 礼物连击
|
||||
*/
|
||||
COMBO_SEND,
|
||||
/**
|
||||
* 欢迎高能用户、(舰长?待验证)特殊消息
|
||||
*/
|
||||
ENTRY_EFFECT,
|
||||
HOT_RANK_CHANGED,
|
||||
HOT_RANK_CHANGED_V2,
|
||||
INTERACT_WORD,
|
||||
/**
|
||||
* 开始直播
|
||||
*/
|
||||
LIVE,
|
||||
LIVE_INTERACTIVE_GAME,
|
||||
NOTICE_MSG,
|
||||
/**
|
||||
* 高能榜数量更新
|
||||
*/
|
||||
ONLINE_RANK_COUNT,
|
||||
ONLINE_RANK_TOP3,
|
||||
ONLINE_RANK_V2,
|
||||
PK_BATTLE_END,
|
||||
PK_BATTLE_FINAL_PROCESS,
|
||||
PK_BATTLE_PROCESS,
|
||||
PK_BATTLE_PROCESS_NEW,
|
||||
PK_BATTLE_SETTLE,
|
||||
PK_BATTLE_SETTLE_USER,
|
||||
PK_BATTLE_SETTLE_V2,
|
||||
/**
|
||||
* 主播准备中
|
||||
*/
|
||||
PREPARING,
|
||||
ROOM_REAL_TIME_MESSAGE_UPDATE,
|
||||
/**
|
||||
* 停止直播的房间ID列表
|
||||
*/
|
||||
STOP_LIVE_ROOM_LIST,
|
||||
/**
|
||||
* 醒目留言
|
||||
*/
|
||||
SUPER_CHAT_MESSAGE,
|
||||
SUPER_CHAT_MESSAGE_JPN,
|
||||
/**
|
||||
* 删除醒目留言
|
||||
*/
|
||||
SUPER_CHAT_MESSAGE_DELETE,
|
||||
WIDGET_BANNER,
|
||||
/**
|
||||
* 点赞数更新
|
||||
*/
|
||||
LIKE_INFO_V3_UPDATE,
|
||||
/**
|
||||
* 为主播点赞
|
||||
*/
|
||||
LIKE_INFO_V3_CLICK,
|
||||
HOT_ROOM_NOTIFY,
|
||||
/**
|
||||
* 观看人数变化
|
||||
*/
|
||||
WATCHED_CHANGE,
|
||||
POPULAR_RANK_CHANGED,
|
||||
COMMON_NOTICE_DANMAKU,
|
||||
LIVE_MULTI_VIEW_CHANGE,
|
||||
RECOMMEND_CARD,
|
||||
PK_BATTLE_START_NEW,
|
||||
PK_BATTLE_ENTRANCE,
|
||||
AREA_RANK_CHANGED,
|
||||
ROOM_BLOCK_MSG,
|
||||
USER_TOAST_MSG,
|
||||
PK_BATTLE_PRE_NEW,
|
||||
PK_BATTLE_RANK_CHANGE,
|
||||
PK_BATTLE_START,
|
||||
PK_BATTLE_PRE,
|
||||
PLAY_TAG,
|
||||
;
|
||||
|
||||
public static BilibiliCmdEnum getByString(String cmd) {
|
||||
try {
|
||||
return BilibiliCmdEnum.valueOf(cmd);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.constant;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum OperationEnum {
|
||||
HANDSHAKE(0),
|
||||
HANDSHAKE_REPLY(1),
|
||||
/**
|
||||
* 心跳包
|
||||
*/
|
||||
HEARTBEAT(2),
|
||||
/**
|
||||
* 心跳包回复(人气值)
|
||||
*/
|
||||
HEARTBEAT_REPLY(3),
|
||||
SEND_MSG(4),
|
||||
|
||||
/**
|
||||
* 普通包(命令)
|
||||
*/
|
||||
SEND_SMS_REPLY(5),
|
||||
DISCONNECT_REPLY(6),
|
||||
|
||||
/**
|
||||
* 认证包
|
||||
*/
|
||||
AUTH(7),
|
||||
|
||||
/**
|
||||
* 认证包回复
|
||||
*/
|
||||
AUTH_REPLY(8),
|
||||
RAW(9),
|
||||
PROTO_READY(10),
|
||||
PROTO_FINISH(11),
|
||||
CHANGE_ROOM(12),
|
||||
CHANGE_ROOM_REPLY(13),
|
||||
REGISTER(14),
|
||||
REGISTER_REPLY(15),
|
||||
UNREGISTER(16),
|
||||
UNREGISTER_REPLY(17),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
||||
public static OperationEnum getByCode(int code) {
|
||||
for (OperationEnum value : OperationEnum.values()) {
|
||||
if (value.code == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.constant;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum ProtoverEnum {
|
||||
/**
|
||||
* 普通包正文不使用压缩
|
||||
*/
|
||||
NORMAL_NO_COMPRESSION(0),
|
||||
/**
|
||||
* 心跳及认证包正文不使用压缩
|
||||
*/
|
||||
HEARTBEAT_AUTH_NO_COMPRESSION(1),
|
||||
/**
|
||||
* 普通包正文使用zlib压缩
|
||||
*/
|
||||
NORMAL_ZLIB(2),
|
||||
/**
|
||||
* 普通包正文使用brotli压缩,解压为一个带头部的协议0普通包
|
||||
*/
|
||||
NORMAL_BROTLI(3),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
||||
|
||||
public static ProtoverEnum getByCode(int code) {
|
||||
for (ProtoverEnum value : ProtoverEnum.values()) {
|
||||
if (value.code == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.listener;
|
||||
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliConnectionHandler;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
|
||||
/**
|
||||
* 连接回调
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/21
|
||||
*/
|
||||
public interface IBilibiliConnectionListener extends IBaseConnectionListener<BilibiliConnectionHandler> {
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.listener;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.*;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.*;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/7
|
||||
*/
|
||||
public interface IBilibiliMsgListener extends IBaseMsgListener<BilibiliBinaryFrameHandler, BilibiliCmdEnum>,
|
||||
IDanmuMsgListener<BilibiliBinaryFrameHandler, DanmuMsgMsg>,
|
||||
IGiftMsgListener<BilibiliBinaryFrameHandler, SendGiftMsg>,
|
||||
ISuperChatMsgListener<BilibiliBinaryFrameHandler, SuperChatMessageMsg>,
|
||||
IEnterRoomMsgListener<BilibiliBinaryFrameHandler, InteractWordMsg>,
|
||||
ILikeMsgListener<BilibiliBinaryFrameHandler, LikeInfoV3ClickMsg> {
|
||||
|
||||
/**
|
||||
* 收到礼物
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param msg SendSmsReplyMsg
|
||||
* @deprecated use {@link IGiftMsgListener#onGiftMsg(Object, Object)}
|
||||
*/
|
||||
default void onSendGift(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg msg) {
|
||||
this.onSendGift(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link IGiftMsgListener#onGiftMsg(Object)}
|
||||
*/
|
||||
default void onSendGift(SendSmsReplyMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通用户进入直播间
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param msg SendSmsReplyMsg
|
||||
* @deprecated use {@link IEnterRoomMsgListener#onEnterRoomMsg}
|
||||
*/
|
||||
default void onEnterRoom(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg msg) {
|
||||
this.onEnterRoom(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link IEnterRoomMsgListener#onEnterRoomMsg}
|
||||
*/
|
||||
default void onEnterRoom(SendSmsReplyMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 入场效果(高能用户)
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param sendSmsReplyMsg SendSmsReplyMsg
|
||||
*/
|
||||
default void onEntryEffect(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg sendSmsReplyMsg) {
|
||||
this.onEntryEffect(sendSmsReplyMsg);
|
||||
}
|
||||
|
||||
default void onEntryEffect(SendSmsReplyMsg sendSmsReplyMsg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 观看人数变化
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param msg SendSmsReplyMsg
|
||||
*/
|
||||
default void onWatchedChange(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg msg) {
|
||||
this.onWatchedChange(msg);
|
||||
}
|
||||
|
||||
default void onWatchedChange(SendSmsReplyMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 为主播点赞
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param msg SendSmsReplyMsg
|
||||
* @deprecated use {@link ILikeMsgListener#onLikeMsg}
|
||||
*/
|
||||
default void onClickLike(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg msg) {
|
||||
this.onClickLike(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ILikeMsgListener#onLikeMsg}
|
||||
*/
|
||||
default void onClickLike(SendSmsReplyMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* 点赞数更新
|
||||
*
|
||||
* @param binaryFrameHandler BilibiliBinaryFrameHandler
|
||||
* @param msg SendSmsReplyMsg
|
||||
*/
|
||||
default void onClickUpdate(BilibiliBinaryFrameHandler binaryFrameHandler, SendSmsReplyMsg msg) {
|
||||
this.onClickUpdate(msg);
|
||||
}
|
||||
|
||||
default void onClickUpdate(SendSmsReplyMsg msg) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
public class AuthMsg extends BaseBilibiliMsg {
|
||||
|
||||
/**
|
||||
* 用户uid,0代表游客
|
||||
*/
|
||||
private long uid;
|
||||
|
||||
/**
|
||||
* 房间id room_id,不是短id short_id
|
||||
* 可以通过将url参数id改为直播地址中的数字来查询房间真实id
|
||||
* example: <a href="https://api.live.bilibili.com/room/v1/Room/room_init?id=6">https://api.live.bilibili.com/room/v1/Room/room_init?id=6</a>
|
||||
*/
|
||||
private final long roomid;
|
||||
|
||||
/**
|
||||
* 协议版本
|
||||
*
|
||||
* @see ProtoverEnum#getCode()
|
||||
*/
|
||||
private final int protover;
|
||||
|
||||
/**
|
||||
* 平台标识
|
||||
*/
|
||||
private String platform = "web";
|
||||
private int type = 2;
|
||||
|
||||
/**
|
||||
* 必须字段
|
||||
*
|
||||
* @since 2023-08-19
|
||||
*/
|
||||
private final String buvid;
|
||||
|
||||
/**
|
||||
* 认证秘钥(必须字段)
|
||||
*
|
||||
* @since @since 2023-08-19
|
||||
*/
|
||||
private final String key;
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(this.protover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.AUTH;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class AuthReplyMsg extends BaseBilibiliMsg {
|
||||
|
||||
/**
|
||||
* 0: OK,-101: TOKEN_ERROR
|
||||
*/
|
||||
private int code;
|
||||
|
||||
@JsonIgnore
|
||||
private int protover;
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(protover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.AUTH_REPLY;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IDanmuMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/8
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DanmuMsgMsg extends BaseBilibiliMsg implements IDanmuMsg {
|
||||
|
||||
private JsonNode info;
|
||||
private String dm_v2;
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
JsonNode jsonNode3 = info.get(3);
|
||||
if (jsonNode3.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return jsonNode3.get(1).asText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
JsonNode jsonNode3 = info.get(3);
|
||||
if (jsonNode3.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return (byte) jsonNode3.get(0).asInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
JsonNode jsonNode2 = info.get(2);
|
||||
return jsonNode2.get(0).asText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
JsonNode jsonNode2 = info.get(2);
|
||||
return jsonNode2.get(1).asText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
String avatar = null;
|
||||
try {
|
||||
tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2 dmV2 = tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2.parseFrom(Base64.decode(dm_v2));
|
||||
avatar = dmV2.getDmV220().getAvatar();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return avatar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
JsonNode jsonNode1 = info.get(1);
|
||||
return jsonNode1.asText();
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HeartbeatMsg extends BaseBilibiliMsg {
|
||||
|
||||
@JsonIgnore
|
||||
private int protover;
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(protover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.HEARTBEAT;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HeartbeatReplyMsg extends BaseBilibiliMsg {
|
||||
|
||||
private int popularity;
|
||||
|
||||
@JsonIgnore
|
||||
private int protover;
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(protover);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.HEARTBEAT_REPLY;
|
||||
}
|
||||
}
|
||||
@@ -1,396 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IEnterRoomMsg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/12/26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class InteractWordMsg extends BaseBilibiliMsg implements IEnterRoomMsg {
|
||||
|
||||
private Data data;
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
if (data == null || data.fans_medal == null) {
|
||||
return null;
|
||||
}
|
||||
return data.fans_medal.medal_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
if (data == null || data.fans_medal == null) {
|
||||
return 0;
|
||||
}
|
||||
return data.fans_medal.medal_level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return Long.toString(data.uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
return data.uname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
if (data == null || data.uinfo == null || data.uinfo.base == null) {
|
||||
return null;
|
||||
}
|
||||
return data.uinfo.base.face;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Data {
|
||||
|
||||
private Contribution contribution;
|
||||
private Contribution_v2 contribution_v2;
|
||||
private int core_user_type;
|
||||
private int dmscore;
|
||||
private Fans_medal fans_medal;
|
||||
private String group_medal;
|
||||
private List<Integer> identities;
|
||||
private boolean is_mystery;
|
||||
private int is_spread;
|
||||
private int msg_type;
|
||||
private int privilege_type;
|
||||
private long roomid;
|
||||
private long score;
|
||||
private String spread_desc;
|
||||
private String spread_info;
|
||||
private int tail_icon;
|
||||
private String tail_text;
|
||||
private long timestamp;
|
||||
private long trigger_time;
|
||||
private long uid;
|
||||
private Uinfo uinfo;
|
||||
private String uname;
|
||||
private String uname_color;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Contribution {
|
||||
|
||||
private int grade;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Contribution_v2 {
|
||||
|
||||
private int grade;
|
||||
private String rank_type;
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Fans_medal {
|
||||
|
||||
private long anchor_roomid;
|
||||
private int guard_level;
|
||||
private int icon_id;
|
||||
private int is_lighted;
|
||||
private long medal_color;
|
||||
private long medal_color_border;
|
||||
private long medal_color_end;
|
||||
private long medal_color_start;
|
||||
private byte medal_level;
|
||||
private String medal_name;
|
||||
private long score;
|
||||
private String special;
|
||||
private long target_id;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Origin_info {
|
||||
|
||||
private String face;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Risk_ctrl_info {
|
||||
|
||||
private String face;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Official_info {
|
||||
|
||||
private int role;
|
||||
private String title;
|
||||
private String desc;
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Base {
|
||||
|
||||
private String face;
|
||||
private boolean is_mystery;
|
||||
private String name;
|
||||
private int name_color;
|
||||
private Origin_info origin_info;
|
||||
private Risk_ctrl_info risk_ctrl_info;
|
||||
private Official_info official_info;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Medal {
|
||||
|
||||
private String name;
|
||||
private int level;
|
||||
private long color_start;
|
||||
private long color_end;
|
||||
private long color_border;
|
||||
private long color;
|
||||
private int id;
|
||||
private int typ;
|
||||
private int is_light;
|
||||
private long ruid;
|
||||
private int guard_level;
|
||||
private int score;
|
||||
private String guard_icon;
|
||||
private String honor_icon;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Guard {
|
||||
|
||||
private int level;
|
||||
private String expired_str;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@lombok.Data
|
||||
public static class Uinfo {
|
||||
|
||||
private long uid;
|
||||
private Base base;
|
||||
private Medal medal;
|
||||
private String wealth;
|
||||
private String title;
|
||||
private Guard guard;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ILikeMsg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/31
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LikeInfoV3ClickMsg extends BaseBilibiliMsg implements ILikeMsg {
|
||||
|
||||
private Data data;
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
if (this.data == null || this.data.getFans_medal() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.data.getFans_medal().getMedal_name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
if (this.data == null || this.data.getFans_medal() == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.data.getFans_medal().getMedal_level();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
if (this.data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Long.toString(this.data.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
if (this.data == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.getUname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
if (this.data == null || this.data.getUinfo() == null || this.data.getUinfo().getBase() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.getUinfo().getBase().getFace();
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Data {
|
||||
|
||||
private int show_area;
|
||||
private int msg_type;
|
||||
private String like_icon;
|
||||
private long uid;
|
||||
private String like_text;
|
||||
private String uname;
|
||||
private String uname_color;
|
||||
private List<Integer> identities;
|
||||
private InteractWordMsg.Fans_medal fans_medal;
|
||||
private Contribution_info contribution_info;
|
||||
private int dmscore;
|
||||
private String group_medal;
|
||||
private boolean is_mystery;
|
||||
private InteractWordMsg.Uinfo uinfo;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Contribution_info {
|
||||
|
||||
private int grade;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.api.BilibiliApis;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.dto.MedalInfo;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IGiftMsg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/8
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SendGiftMsg extends BaseBilibiliMsg implements IGiftMsg {
|
||||
|
||||
private Data data;
|
||||
|
||||
/**
|
||||
* 额外属性,获取礼物图片时可能会用到
|
||||
*/
|
||||
private long roomId;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
if (data == null || data.medal_info == null) {
|
||||
return IGiftMsg.super.getBadgeName();
|
||||
}
|
||||
|
||||
return data.medal_info.getMedal_name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
if (data == null || data.medal_info == null) {
|
||||
return IGiftMsg.super.getBadgeLevel();
|
||||
}
|
||||
|
||||
return data.medal_info.getMedal_level();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
if (this.data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Long.toString(this.data.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
if (this.data == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.getUname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
if (this.data == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.getFace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftName() {
|
||||
if (this.data == null) {
|
||||
return "未知礼物";
|
||||
}
|
||||
|
||||
return this.data.getGiftName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftImg() {
|
||||
return BilibiliApis.getGiftImgById(this.data.giftId, this.roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftId() {
|
||||
if (this.data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Long.toString(data.getGiftId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftCount() {
|
||||
if (this.data == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return data.getNum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftPrice() {
|
||||
if (this.data == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return data.getPrice();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUid() {
|
||||
if (this.data == null || this.data.getReceive_user_info() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Long.toString(data.getReceive_user_info().getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUsername() {
|
||||
if (this.data == null || this.data.getReceive_user_info() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return data.getReceive_user_info().getUname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Data {
|
||||
|
||||
private int draw;
|
||||
private int gold;
|
||||
private int silver;
|
||||
private int num;
|
||||
private int total_coin;
|
||||
private int effect;
|
||||
private int broadcast_id;
|
||||
private int crit_prob;
|
||||
private int guard_level;
|
||||
private long rcost;
|
||||
private long uid;
|
||||
private long timestamp;
|
||||
private int giftId;
|
||||
private int giftType;
|
||||
@JsonProperty("super")
|
||||
private int _super;
|
||||
private int super_gift_num;
|
||||
private int super_batch_gift_num;
|
||||
private int remain;
|
||||
private int discount_price;
|
||||
private int price;
|
||||
private String beatId;
|
||||
private String biz_source;
|
||||
private String action;
|
||||
private String coin_type;
|
||||
private String uname;
|
||||
private String face;
|
||||
private String batch_combo_id;
|
||||
private String rnd;
|
||||
private String giftName;
|
||||
private String original_gift_name;
|
||||
private Combo_send combo_send;
|
||||
private Batch_combo_send batch_combo_send;
|
||||
private String tag_image;
|
||||
private String top_list;
|
||||
private String send_master;
|
||||
private boolean is_first;
|
||||
private int demarcation;
|
||||
private int combo_stay_time;
|
||||
private int combo_total_coin;
|
||||
private String tid;
|
||||
private int effect_block;
|
||||
private int is_special_batch;
|
||||
private int combo_resources_id;
|
||||
private int magnification;
|
||||
private String name_color;
|
||||
private MedalInfo medal_info;
|
||||
private int svga_block;
|
||||
private JsonNode blind_gift;
|
||||
private int float_sc_resource_id;
|
||||
@JsonProperty("switch")
|
||||
private boolean _switch;
|
||||
private int face_effect_type;
|
||||
private int face_effect_id;
|
||||
private boolean is_naming;
|
||||
private Receive_user_info receive_user_info;
|
||||
private boolean is_join_receiver;
|
||||
private Bag_gift bag_gift;
|
||||
private int wealth_level;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Combo_send {
|
||||
|
||||
private long uid;
|
||||
private int gift_num;
|
||||
private int combo_num;
|
||||
private int gift_id;
|
||||
private String combo_id;
|
||||
private String gift_name;
|
||||
private String action;
|
||||
private String uname;
|
||||
private String send_master;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Receive_user_info {
|
||||
|
||||
private String uname;
|
||||
private long uid;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Batch_combo_send {
|
||||
|
||||
private long uid;
|
||||
private int gift_num;
|
||||
private int batch_combo_num;
|
||||
private int gift_id;
|
||||
private String batch_combo_id;
|
||||
private String gift_name;
|
||||
private String action;
|
||||
private String uname;
|
||||
private String send_master;
|
||||
private JsonNode blind_gift;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Bag_gift {
|
||||
|
||||
private int show_price;
|
||||
private int price_for_show;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliCmdMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SendSmsReplyMsg extends BaseBilibiliCmdMsg {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private JsonNode full;
|
||||
|
||||
private JsonNode half;
|
||||
|
||||
private JsonNode side;
|
||||
|
||||
private JsonNode data;
|
||||
|
||||
private JsonNode info;
|
||||
|
||||
private JsonNode msg_common;
|
||||
|
||||
private JsonNode msg_self;
|
||||
|
||||
private JsonNode link_url;
|
||||
|
||||
private JsonNode msg_type;
|
||||
|
||||
private JsonNode shield_uid;
|
||||
|
||||
private JsonNode business_id;
|
||||
|
||||
private JsonNode scatter;
|
||||
|
||||
private long roomid;
|
||||
|
||||
private long real_roomid;
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.dto.MedalInfo;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ISuperChatMsg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/24
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SuperChatMessageMsg extends BaseBilibiliMsg implements ISuperChatMsg {
|
||||
|
||||
private long roomid;
|
||||
private Data data;
|
||||
|
||||
@Override
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.SEND_SMS_REPLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
if (this.data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Long.toString(this.data.uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
if (this.data == null || this.data.getUser_info() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.user_info.uname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
if (this.data == null || this.data.getUser_info() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.user_info.face;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
if (this.data == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return this.data.message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDuration() {
|
||||
if (this.data == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.data.time;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Data {
|
||||
private String background_bottom_color;
|
||||
private String background_color;
|
||||
private String background_color_end;
|
||||
private String background_color_start;
|
||||
private String background_icon;
|
||||
private String background_image;
|
||||
private String background_price_color;
|
||||
private double color_point;
|
||||
private int dmscore;
|
||||
private long end_time;
|
||||
private Gift gift;
|
||||
private long id;
|
||||
private int is_ranked;
|
||||
private int is_send_audit;
|
||||
private MedalInfo medal_info;
|
||||
private String message;
|
||||
private String message_font_color;
|
||||
private String message_trans;
|
||||
private int price;
|
||||
private int rate;
|
||||
private long start_time;
|
||||
private int time;
|
||||
private String token;
|
||||
private int trans_mark;
|
||||
private long ts;
|
||||
private long uid;
|
||||
private User_info user_info;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Gift {
|
||||
private int gift_id;
|
||||
private String gift_name;
|
||||
private int num;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class User_info {
|
||||
private String face;
|
||||
private String face_frame;
|
||||
private int guard_level;
|
||||
private int is_main_vip;
|
||||
private int is_svip;
|
||||
private int is_vip;
|
||||
private String level_color;
|
||||
private int manager;
|
||||
private String name_color;
|
||||
private String title;
|
||||
private String uname;
|
||||
private int user_level;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg.base;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseCmdMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public abstract class BaseBilibiliCmdMsg extends BaseCmdMsg<BilibiliCmdEnum> implements IBilibiliMsg {
|
||||
|
||||
private int protover;
|
||||
private String cmd;
|
||||
|
||||
@Override
|
||||
public String getCmd() {
|
||||
return this.cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCmd(String cmd) {
|
||||
this.cmd = cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BilibiliCmdEnum getCmdEnum() {
|
||||
return BilibiliCmdEnum.getByString(getCmd());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(this.protover);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg.base;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.BaseMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public abstract class BaseBilibiliMsg extends BaseMsg implements IBilibiliMsg {
|
||||
|
||||
private int protover;
|
||||
|
||||
@Override
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(protover);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg.base;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
public interface IBilibiliMsg extends IMsg {
|
||||
|
||||
@JsonIgnore
|
||||
ProtoverEnum getProtoverEnum();
|
||||
|
||||
@JsonIgnore
|
||||
OperationEnum getOperationEnum();
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.msg.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class MedalInfo {
|
||||
|
||||
private long target_id;
|
||||
private String special;
|
||||
private int icon_id;
|
||||
private String anchor_uname;
|
||||
private int anchor_roomid;
|
||||
private byte medal_level;
|
||||
private String medal_name;
|
||||
private String medal_color;
|
||||
private long medal_color_start;
|
||||
private long medal_color_end;
|
||||
private long medal_color_border;
|
||||
private int is_lighted;
|
||||
private int guard_level;
|
||||
|
||||
/**
|
||||
* 未知属性都放在这
|
||||
*/
|
||||
private final Map<String, JsonNode> unknownProperties = new HashMap<>();
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getUnknownProperties() {
|
||||
return unknownProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setOther(String key, JsonNode value) {
|
||||
this.unknownProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.frame;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.frame.base.BaseBilibiliWebSocketFrame;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
public class AuthWebSocketFrame extends BaseBilibiliWebSocketFrame {
|
||||
|
||||
public AuthWebSocketFrame(ByteBuf byteBuf) {
|
||||
super(byteBuf);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.frame;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.frame.base.BaseBilibiliWebSocketFrame;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
public class HeartbeatWebSocketFrame extends BaseBilibiliWebSocketFrame {
|
||||
|
||||
public HeartbeatWebSocketFrame(ByteBuf byteBuf) {
|
||||
super(byteBuf);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.frame.base;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
|
||||
/**
|
||||
* 实现Bilibili协议的BinaryWebSocketFrame
|
||||
* <a href="https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/live/message_stream.md#数据包格式">数据包格式</a>
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
public abstract class BaseBilibiliWebSocketFrame extends BinaryWebSocketFrame {
|
||||
|
||||
public static int sequence = 0;
|
||||
|
||||
public ProtoverEnum getProtoverEnum() {
|
||||
return ProtoverEnum.getByCode(super.content().getShort(6));
|
||||
}
|
||||
|
||||
public OperationEnum getOperationEnum() {
|
||||
return OperationEnum.getByCode(super.content().getInt(8));
|
||||
}
|
||||
|
||||
public BaseBilibiliWebSocketFrame(ByteBuf byteBuf) {
|
||||
super(byteBuf);
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.frame.factory;
|
||||
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.api.BilibiliApis;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.AuthMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.HeartbeatMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.frame.AuthWebSocketFrame;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.frame.HeartbeatWebSocketFrame;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.util.BilibiliCodecUtil;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.util.OrLiveChatCookieUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/5
|
||||
*/
|
||||
public class BilibiliWebSocketFrameFactory {
|
||||
|
||||
private static final ConcurrentHashMap<Long, BilibiliWebSocketFrameFactory> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 浏览器地址中的房间id,支持短id
|
||||
*/
|
||||
private final long roomId;
|
||||
private volatile static HeartbeatMsg heartbeatMsg;
|
||||
|
||||
public BilibiliWebSocketFrameFactory(long roomId) {
|
||||
this.roomId = roomId;
|
||||
}
|
||||
|
||||
public synchronized static BilibiliWebSocketFrameFactory getInstance(long roomId) {
|
||||
return CACHE.computeIfAbsent(roomId, aLong -> new BilibiliWebSocketFrameFactory(roomId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建认证包
|
||||
*
|
||||
* @param protover {@link ProtoverEnum}
|
||||
* @param cookie 浏览器cookie,仅用来维持登录状态
|
||||
* @return AuthWebSocketFrame
|
||||
*/
|
||||
public AuthWebSocketFrame createAuth(ProtoverEnum protover, String cookie) {
|
||||
try {
|
||||
Map<String, String> cookieMap = OrLiveChatCookieUtil.parseCookieString(cookie);
|
||||
String buvid3 = OrLiveChatCookieUtil.getCookieByName(cookieMap, "buvid3", () -> UUID.randomUUID().toString());
|
||||
String uid = OrLiveChatCookieUtil.getCookieByName(cookieMap, "DedeUserID", () -> "0");
|
||||
BilibiliApis.RoomInitResult data = BilibiliApis.roomInit(roomId, cookie);
|
||||
JsonNode danmuInfo = BilibiliApis.getDanmuInfo(roomId, 0, cookie);
|
||||
long realRoomId = data.getRoom_id();
|
||||
AuthMsg authMsg = new AuthMsg(realRoomId, protover.getCode(), buvid3, danmuInfo.get("token").asText());
|
||||
authMsg.setUid(NumberUtil.parseLong(uid));
|
||||
return new AuthWebSocketFrame(BilibiliCodecUtil.encode(authMsg));
|
||||
} catch (Exception e) {
|
||||
throw new BaseException(String.format("认证包创建失败,请检查房间号是否正确。roomId: %d, msg: %s", roomId, e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public AuthWebSocketFrame createAuth(ProtoverEnum protover) {
|
||||
return this.createAuth(protover, null);
|
||||
}
|
||||
|
||||
public HeartbeatWebSocketFrame createHeartbeat(ProtoverEnum protover) {
|
||||
return new HeartbeatWebSocketFrame(BilibiliCodecUtil.encode(this.getHeartbeatMsg(protover)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 心跳包单例模式
|
||||
*
|
||||
* @param protover {@link ProtoverEnum}
|
||||
* @return HeartbeatWebSocketFrame
|
||||
*/
|
||||
public HeartbeatMsg getHeartbeatMsg(ProtoverEnum protover) {
|
||||
if (heartbeatMsg == null) {
|
||||
synchronized (BilibiliWebSocketFrameFactory.this) {
|
||||
if (heartbeatMsg == null) {
|
||||
heartbeatMsg = new HeartbeatMsg(protover.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
return heartbeatMsg;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.client.BilibiliLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.listener.IBilibiliMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.*;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.IBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.util.BilibiliCodecUtil;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientBinaryFrameHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 消息处理器
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/1/4
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class BilibiliBinaryFrameHandler extends BaseNettyClientBinaryFrameHandler<BilibiliLiveChatClient, BilibiliBinaryFrameHandler, BilibiliCmdEnum, IBilibiliMsg, IBilibiliMsgListener> {
|
||||
|
||||
public BilibiliBinaryFrameHandler(List<IBilibiliMsgListener> msgListeners, BilibiliLiveChatClient client) {
|
||||
super(msgListeners, client);
|
||||
}
|
||||
|
||||
public BilibiliBinaryFrameHandler(List<IBilibiliMsgListener> msgListeners, long roomId) {
|
||||
super(msgListeners, roomId);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onCmdMsg(BilibiliCmdEnum cmd, ICmdMsg<BilibiliCmdEnum> cmdMsg) {
|
||||
if (super.msgListeners.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendSmsReplyMsg sendSmsReplyMsg = (SendSmsReplyMsg) cmdMsg;
|
||||
switch (cmd) {
|
||||
case DANMU_MSG: {
|
||||
DanmuMsgMsg danmuMsgMsg = new DanmuMsgMsg();
|
||||
danmuMsgMsg.setProtover(sendSmsReplyMsg.getProtover());
|
||||
danmuMsgMsg.setInfo(sendSmsReplyMsg.getInfo());
|
||||
danmuMsgMsg.setDm_v2(StrUtil.toStringOrNull(sendSmsReplyMsg.getUnknownProperties().get("dm_v2")));
|
||||
iteratorMsgListeners(msgListener -> msgListener.onDanmuMsg(BilibiliBinaryFrameHandler.this, danmuMsgMsg));
|
||||
break;
|
||||
}
|
||||
|
||||
case SEND_GIFT: {
|
||||
SendGiftMsg sendGiftMsg = new SendGiftMsg();
|
||||
sendGiftMsg.setRoomId(getRoomIdAsLong());
|
||||
sendGiftMsg.setProtover(sendSmsReplyMsg.getProtover());
|
||||
SendGiftMsg.Data data = BaseBilibiliMsg.OBJECT_MAPPER.treeToValue(sendSmsReplyMsg.getData(), SendGiftMsg.Data.class);
|
||||
sendGiftMsg.setData(data);
|
||||
iteratorMsgListeners(msgListener -> {
|
||||
msgListener.onGiftMsg(BilibiliBinaryFrameHandler.this, sendGiftMsg);
|
||||
msgListener.onSendGift(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case SUPER_CHAT_MESSAGE: {
|
||||
SuperChatMessageMsg superChatMessageMsg = new SuperChatMessageMsg();
|
||||
superChatMessageMsg.setProtover(sendSmsReplyMsg.getProtover());
|
||||
superChatMessageMsg.setRoomid(sendSmsReplyMsg.getRoomid());
|
||||
SuperChatMessageMsg.Data data = BaseBilibiliMsg.OBJECT_MAPPER.treeToValue(sendSmsReplyMsg.getData(), SuperChatMessageMsg.Data.class);
|
||||
superChatMessageMsg.setData(data);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onSuperChatMsg(BilibiliBinaryFrameHandler.this, superChatMessageMsg));
|
||||
break;
|
||||
}
|
||||
|
||||
case INTERACT_WORD: {
|
||||
InteractWordMsg interactWordMsg = new InteractWordMsg();
|
||||
interactWordMsg.setProtover(sendSmsReplyMsg.getProtover());
|
||||
InteractWordMsg.Data data = BaseBilibiliMsg.OBJECT_MAPPER.treeToValue(sendSmsReplyMsg.getData(), InteractWordMsg.Data.class);
|
||||
interactWordMsg.setData(data);
|
||||
iteratorMsgListeners(msgListener -> {
|
||||
msgListener.onEnterRoomMsg(BilibiliBinaryFrameHandler.this, interactWordMsg);
|
||||
msgListener.onEnterRoom(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case ENTRY_EFFECT: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onEntryEffect(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg));
|
||||
break;
|
||||
}
|
||||
|
||||
case WATCHED_CHANGE: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onWatchedChange(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg));
|
||||
break;
|
||||
}
|
||||
|
||||
case LIKE_INFO_V3_CLICK: {
|
||||
LikeInfoV3ClickMsg likeInfoV3ClickMsg = new LikeInfoV3ClickMsg();
|
||||
likeInfoV3ClickMsg.setProtover(sendSmsReplyMsg.getProtover());
|
||||
LikeInfoV3ClickMsg.Data data = BaseBilibiliMsg.OBJECT_MAPPER.treeToValue(sendSmsReplyMsg.getData(), LikeInfoV3ClickMsg.Data.class);
|
||||
likeInfoV3ClickMsg.setData(data);
|
||||
iteratorMsgListeners(msgListener -> {
|
||||
msgListener.onLikeMsg(BilibiliBinaryFrameHandler.this, likeInfoV3ClickMsg);
|
||||
msgListener.onClickLike(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case LIKE_INFO_V3_UPDATE: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onClickUpdate(BilibiliBinaryFrameHandler.this, sendSmsReplyMsg));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onOtherCmdMsg(BilibiliBinaryFrameHandler.this, cmd, cmdMsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<IBilibiliMsg> decode(ByteBuf byteBuf) {
|
||||
return BilibiliCodecUtil.decode(byteBuf);
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.netty.handler;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.client.BilibiliLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.config.BilibiliLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.frame.factory.BilibiliWebSocketFrameFactory;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientConnectionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* 连接处理器
|
||||
*
|
||||
* @author mjz
|
||||
* @date 2023/8/21
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class BilibiliConnectionHandler extends BaseNettyClientConnectionHandler<BilibiliLiveChatClient, BilibiliConnectionHandler> {
|
||||
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private final long roomId;
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private final ProtoverEnum protover;
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private String cookie;
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, BilibiliLiveChatClient client, IBaseConnectionListener<BilibiliConnectionHandler> listener) {
|
||||
super(handshaker, client, listener);
|
||||
this.roomId = client.getConfig().getRoomId();
|
||||
this.protover = client.getConfig().getProtover();
|
||||
this.cookie = client.getConfig().getCookie();
|
||||
}
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, BilibiliLiveChatClient client) {
|
||||
this(handshaker, client, null);
|
||||
}
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, ProtoverEnum protover, IBaseConnectionListener<BilibiliConnectionHandler> listener, String cookie) {
|
||||
super(handshaker, listener);
|
||||
this.roomId = roomId;
|
||||
this.protover = protover;
|
||||
this.cookie = cookie;
|
||||
}
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, ProtoverEnum protover, IBaseConnectionListener<BilibiliConnectionHandler> listener) {
|
||||
this(handshaker, roomId, protover, listener, null);
|
||||
}
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, ProtoverEnum protover, String cookie) {
|
||||
this(handshaker, roomId, protover, null, cookie);
|
||||
}
|
||||
|
||||
public BilibiliConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, ProtoverEnum protover) {
|
||||
this(handshaker, roomId, protover, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendHeartbeat(ChannelHandlerContext ctx) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("发送心跳包");
|
||||
}
|
||||
ctx.writeAndFlush(
|
||||
getWebSocketFrameFactory(getRoomId()).createHeartbeat(getProtover())
|
||||
).addListener((ChannelFutureListener) future -> {
|
||||
if (future.isSuccess()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("心跳包发送完成");
|
||||
}
|
||||
} else {
|
||||
log.error("心跳包发送失败", future.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static BilibiliWebSocketFrameFactory getWebSocketFrameFactory(long roomId) {
|
||||
return BilibiliWebSocketFrameFactory.getInstance(roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAuthRequest(Channel channel) {
|
||||
// 5s内认证
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("发送认证包");
|
||||
}
|
||||
channel.writeAndFlush(getWebSocketFrameFactory(getRoomId()).createAuth(getProtover(), getCookie()));
|
||||
}
|
||||
|
||||
public long getRoomId() {
|
||||
return client != null ? client.getConfig().getRoomId() : roomId;
|
||||
}
|
||||
|
||||
private ProtoverEnum getProtover() {
|
||||
return client != null ? client.getConfig().getProtover() : protover;
|
||||
}
|
||||
|
||||
private String getCookie() {
|
||||
return client != null ? client.getConfig().getCookie() : cookie;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatPeriod() {
|
||||
if (client == null) {
|
||||
return BilibiliLiveChatClientConfig.DEFAULT_HEARTBEAT_PERIOD;
|
||||
} else {
|
||||
return client.getConfig().getHeartbeatPeriod();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatInitialDelay() {
|
||||
if (client == null) {
|
||||
return BilibiliLiveChatClientConfig.DEFAULT_HEARTBEAT_INITIAL_DELAY;
|
||||
} else {
|
||||
return client.getConfig().getHeartbeatInitialDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
public final class Dm_v2Proto {
|
||||
private Dm_v2Proto() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
static final com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor;
|
||||
static final
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
String[] descriptorData = {
|
||||
"\n\013dm_v2.proto\0224tech.ordinaryroad.live.ch" +
|
||||
"at.client.bilibili.protobuf\032\016dm_v2_20.pr" +
|
||||
"oto\"Y\n\005dm_v2\022P\n\010dm_v2_20\030\024 \001(\0132>.tech.or" +
|
||||
"dinaryroad.live.chat.client.bilibili.pro" +
|
||||
"tobuf.dm_v2_20BJ\n4tech.ordinaryroad.live" +
|
||||
".chat.client.bilibili.protobufB\nDm_v2Pro" +
|
||||
"toP\001\242\002\003GPBb\006proto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
Dm_v2_20Proto.getDescriptor(),
|
||||
});
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor,
|
||||
new String[] { "DmV220", });
|
||||
Dm_v2_20Proto.getDescriptor();
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2_20.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
public final class Dm_v2_20Proto {
|
||||
private Dm_v2_20Proto() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
static final com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor;
|
||||
static final
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
String[] descriptorData = {
|
||||
"\n\016dm_v2_20.proto\0224tech.ordinaryroad.live" +
|
||||
".chat.client.bilibili.protobuf\"\032\n\010dm_v2_" +
|
||||
"20\022\016\n\006avatar\030\004 \001(\tBM\n4tech.ordinaryroad." +
|
||||
"live.chat.client.bilibili.protobufB\rDm_v" +
|
||||
"2_20ProtoP\001\242\002\003GPBb\006proto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
});
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor,
|
||||
new String[] { "Avatar", });
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
@@ -1,610 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
/**
|
||||
* Protobuf type {@code tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2}
|
||||
*/
|
||||
public final class dm_v2 extends
|
||||
com.google.protobuf.GeneratedMessageV3 implements
|
||||
// @@protoc_insertion_point(message_implements:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2)
|
||||
dm_v2OrBuilder {
|
||||
private static final long serialVersionUID = 0L;
|
||||
// Use dm_v2.newBuilder() to construct.
|
||||
private dm_v2(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||
super(builder);
|
||||
}
|
||||
private dm_v2() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unused"})
|
||||
protected Object newInstance(
|
||||
UnusedPrivateParameter unused) {
|
||||
return new dm_v2();
|
||||
}
|
||||
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return Dm_v2Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return Dm_v2Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
dm_v2.class, Builder.class);
|
||||
}
|
||||
|
||||
public static final int DM_V2_20_FIELD_NUMBER = 20;
|
||||
private dm_v2_20 dmV220_;
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return Whether the dmV220 field is set.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasDmV220() {
|
||||
return dmV220_ != null;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return The dmV220.
|
||||
*/
|
||||
@Override
|
||||
public dm_v2_20 getDmV220() {
|
||||
return dmV220_ == null ? dm_v2_20.getDefaultInstance() : dmV220_;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
@Override
|
||||
public dm_v2_20OrBuilder getDmV220OrBuilder() {
|
||||
return dmV220_ == null ? dm_v2_20.getDefaultInstance() : dmV220_;
|
||||
}
|
||||
|
||||
private byte memoizedIsInitialized = -1;
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized == 1) return true;
|
||||
if (isInitialized == 0) return false;
|
||||
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
if (dmV220_ != null) {
|
||||
output.writeMessage(20, getDmV220());
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (dmV220_ != null) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeMessageSize(20, getDmV220());
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof dm_v2)) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
dm_v2 other = (dm_v2) obj;
|
||||
|
||||
if (hasDmV220() != other.hasDmV220()) return false;
|
||||
if (hasDmV220()) {
|
||||
if (!getDmV220()
|
||||
.equals(other.getDmV220())) return false;
|
||||
}
|
||||
if (!getUnknownFields().equals(other.getUnknownFields())) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (memoizedHashCode != 0) {
|
||||
return memoizedHashCode;
|
||||
}
|
||||
int hash = 41;
|
||||
hash = (19 * hash) + getDescriptor().hashCode();
|
||||
if (hasDmV220()) {
|
||||
hash = (37 * hash) + DM_V2_20_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getDmV220().hashCode();
|
||||
}
|
||||
hash = (29 * hash) + getUnknownFields().hashCode();
|
||||
memoizedHashCode = hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static dm_v2 parseFrom(
|
||||
java.nio.ByteBuffer data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
java.nio.ByteBuffer data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2 parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2 parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
public static dm_v2 parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input);
|
||||
}
|
||||
|
||||
public static dm_v2 parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static dm_v2 parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder() {
|
||||
return DEFAULT_INSTANCE.toBuilder();
|
||||
}
|
||||
public static Builder newBuilder(dm_v2 prototype) {
|
||||
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||
}
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return this == DEFAULT_INSTANCE
|
||||
? new Builder() : new Builder().mergeFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder newBuilderForType(
|
||||
BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||
// @@protoc_insertion_point(builder_implements:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2)
|
||||
dm_v2OrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return Dm_v2Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return Dm_v2Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
dm_v2.class, Builder.class);
|
||||
}
|
||||
|
||||
// Construct using tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2.newBuilder()
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
private Builder(
|
||||
BuilderParent parent) {
|
||||
super(parent);
|
||||
|
||||
}
|
||||
@Override
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
bitField0_ = 0;
|
||||
dmV220_ = null;
|
||||
if (dmV220Builder_ != null) {
|
||||
dmV220Builder_.dispose();
|
||||
dmV220Builder_ = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return Dm_v2Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2 getDefaultInstanceForType() {
|
||||
return dm_v2.getDefaultInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2 build() {
|
||||
dm_v2 result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2 buildPartial() {
|
||||
dm_v2 result = new dm_v2(this);
|
||||
if (bitField0_ != 0) { buildPartial0(result); }
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void buildPartial0(dm_v2 result) {
|
||||
int from_bitField0_ = bitField0_;
|
||||
if (((from_bitField0_ & 0x00000001) != 0)) {
|
||||
result.dmV220_ = dmV220Builder_ == null
|
||||
? dmV220_
|
||||
: dmV220Builder_.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clone() {
|
||||
return super.clone();
|
||||
}
|
||||
@Override
|
||||
public Builder setField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.setField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder clearField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||
return super.clearField(field);
|
||||
}
|
||||
@Override
|
||||
public Builder clearOneof(
|
||||
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||
return super.clearOneof(oneof);
|
||||
}
|
||||
@Override
|
||||
public Builder setRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
int index, Object value) {
|
||||
return super.setRepeatedField(field, index, value);
|
||||
}
|
||||
@Override
|
||||
public Builder addRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.addRepeatedField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof dm_v2) {
|
||||
return mergeFrom((dm_v2)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(dm_v2 other) {
|
||||
if (other == dm_v2.getDefaultInstance()) return this;
|
||||
if (other.hasDmV220()) {
|
||||
mergeDmV220(other.getDmV220());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
if (extensionRegistry == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
case 162: {
|
||||
input.readMessage(
|
||||
getDmV220FieldBuilder().getBuilder(),
|
||||
extensionRegistry);
|
||||
bitField0_ |= 0x00000001;
|
||||
break;
|
||||
} // case 162
|
||||
default: {
|
||||
if (!super.parseUnknownField(input, extensionRegistry, tag)) {
|
||||
done = true; // was an endgroup tag
|
||||
}
|
||||
break;
|
||||
} // default:
|
||||
} // switch (tag)
|
||||
} // while (!done)
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.unwrapIOException();
|
||||
} finally {
|
||||
onChanged();
|
||||
} // finally
|
||||
return this;
|
||||
}
|
||||
private int bitField0_;
|
||||
|
||||
private dm_v2_20 dmV220_;
|
||||
private com.google.protobuf.SingleFieldBuilderV3<
|
||||
dm_v2_20, dm_v2_20.Builder, dm_v2_20OrBuilder> dmV220Builder_;
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return Whether the dmV220 field is set.
|
||||
*/
|
||||
public boolean hasDmV220() {
|
||||
return ((bitField0_ & 0x00000001) != 0);
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return The dmV220.
|
||||
*/
|
||||
public dm_v2_20 getDmV220() {
|
||||
if (dmV220Builder_ == null) {
|
||||
return dmV220_ == null ? dm_v2_20.getDefaultInstance() : dmV220_;
|
||||
} else {
|
||||
return dmV220Builder_.getMessage();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public Builder setDmV220(dm_v2_20 value) {
|
||||
if (dmV220Builder_ == null) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
dmV220_ = value;
|
||||
} else {
|
||||
dmV220Builder_.setMessage(value);
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public Builder setDmV220(
|
||||
dm_v2_20.Builder builderForValue) {
|
||||
if (dmV220Builder_ == null) {
|
||||
dmV220_ = builderForValue.build();
|
||||
} else {
|
||||
dmV220Builder_.setMessage(builderForValue.build());
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public Builder mergeDmV220(dm_v2_20 value) {
|
||||
if (dmV220Builder_ == null) {
|
||||
if (((bitField0_ & 0x00000001) != 0) &&
|
||||
dmV220_ != null &&
|
||||
dmV220_ != dm_v2_20.getDefaultInstance()) {
|
||||
getDmV220Builder().mergeFrom(value);
|
||||
} else {
|
||||
dmV220_ = value;
|
||||
}
|
||||
} else {
|
||||
dmV220Builder_.mergeFrom(value);
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public Builder clearDmV220() {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
dmV220_ = null;
|
||||
if (dmV220Builder_ != null) {
|
||||
dmV220Builder_.dispose();
|
||||
dmV220Builder_ = null;
|
||||
}
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public dm_v2_20.Builder getDmV220Builder() {
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return getDmV220FieldBuilder().getBuilder();
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
public dm_v2_20OrBuilder getDmV220OrBuilder() {
|
||||
if (dmV220Builder_ != null) {
|
||||
return dmV220Builder_.getMessageOrBuilder();
|
||||
} else {
|
||||
return dmV220_ == null ?
|
||||
dm_v2_20.getDefaultInstance() : dmV220_;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
private com.google.protobuf.SingleFieldBuilderV3<
|
||||
dm_v2_20, dm_v2_20.Builder, dm_v2_20OrBuilder>
|
||||
getDmV220FieldBuilder() {
|
||||
if (dmV220Builder_ == null) {
|
||||
dmV220Builder_ = new com.google.protobuf.SingleFieldBuilderV3<
|
||||
dm_v2_20, dm_v2_20.Builder, dm_v2_20OrBuilder>(
|
||||
getDmV220(),
|
||||
getParentForChildren(),
|
||||
isClean());
|
||||
dmV220_ = null;
|
||||
}
|
||||
return dmV220Builder_;
|
||||
}
|
||||
@Override
|
||||
public final Builder setUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.setUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Builder mergeUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.mergeUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2)
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2)
|
||||
private static final dm_v2 DEFAULT_INSTANCE;
|
||||
static {
|
||||
DEFAULT_INSTANCE = new dm_v2();
|
||||
}
|
||||
|
||||
public static dm_v2 getDefaultInstance() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Parser<dm_v2>
|
||||
PARSER = new com.google.protobuf.AbstractParser<dm_v2>() {
|
||||
@Override
|
||||
public dm_v2 parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
Builder builder = newBuilder();
|
||||
try {
|
||||
builder.mergeFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (com.google.protobuf.UninitializedMessageException e) {
|
||||
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(e)
|
||||
.setUnfinishedMessage(builder.buildPartial());
|
||||
}
|
||||
return builder.buildPartial();
|
||||
}
|
||||
};
|
||||
|
||||
public static com.google.protobuf.Parser<dm_v2> parser() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Parser<dm_v2> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2 getDefaultInstanceForType() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
public interface dm_v2OrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return Whether the dmV220 field is set.
|
||||
*/
|
||||
boolean hasDmV220();
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
* @return The dmV220.
|
||||
*/
|
||||
dm_v2_20 getDmV220();
|
||||
/**
|
||||
* <code>.tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20 dm_v2_20 = 20;</code>
|
||||
*/
|
||||
dm_v2_20OrBuilder getDmV220OrBuilder();
|
||||
}
|
||||
@@ -1,565 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2_20.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
/**
|
||||
* Protobuf type {@code tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20}
|
||||
*/
|
||||
public final class dm_v2_20 extends
|
||||
com.google.protobuf.GeneratedMessageV3 implements
|
||||
// @@protoc_insertion_point(message_implements:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20)
|
||||
dm_v2_20OrBuilder {
|
||||
private static final long serialVersionUID = 0L;
|
||||
// Use dm_v2_20.newBuilder() to construct.
|
||||
private dm_v2_20(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||
super(builder);
|
||||
}
|
||||
private dm_v2_20() {
|
||||
avatar_ = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unused"})
|
||||
protected Object newInstance(
|
||||
UnusedPrivateParameter unused) {
|
||||
return new dm_v2_20();
|
||||
}
|
||||
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return Dm_v2_20Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return Dm_v2_20Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
dm_v2_20.class, Builder.class);
|
||||
}
|
||||
|
||||
public static final int AVATAR_FIELD_NUMBER = 4;
|
||||
@SuppressWarnings("serial")
|
||||
private volatile Object avatar_ = "";
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The avatar.
|
||||
*/
|
||||
@Override
|
||||
public String getAvatar() {
|
||||
Object ref = avatar_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
avatar_ = s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The bytes for avatar.
|
||||
*/
|
||||
@Override
|
||||
public com.google.protobuf.ByteString
|
||||
getAvatarBytes() {
|
||||
Object ref = avatar_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
avatar_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
private byte memoizedIsInitialized = -1;
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized == 1) return true;
|
||||
if (isInitialized == 0) return false;
|
||||
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(avatar_)) {
|
||||
com.google.protobuf.GeneratedMessageV3.writeString(output, 4, avatar_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(avatar_)) {
|
||||
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, avatar_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof dm_v2_20)) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
dm_v2_20 other = (dm_v2_20) obj;
|
||||
|
||||
if (!getAvatar()
|
||||
.equals(other.getAvatar())) return false;
|
||||
if (!getUnknownFields().equals(other.getUnknownFields())) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (memoizedHashCode != 0) {
|
||||
return memoizedHashCode;
|
||||
}
|
||||
int hash = 41;
|
||||
hash = (19 * hash) + getDescriptor().hashCode();
|
||||
hash = (37 * hash) + AVATAR_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getAvatar().hashCode();
|
||||
hash = (29 * hash) + getUnknownFields().hashCode();
|
||||
memoizedHashCode = hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static dm_v2_20 parseFrom(
|
||||
java.nio.ByteBuffer data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
java.nio.ByteBuffer data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
public static dm_v2_20 parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input);
|
||||
}
|
||||
|
||||
public static dm_v2_20 parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static dm_v2_20 parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder() {
|
||||
return DEFAULT_INSTANCE.toBuilder();
|
||||
}
|
||||
public static Builder newBuilder(dm_v2_20 prototype) {
|
||||
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||
}
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return this == DEFAULT_INSTANCE
|
||||
? new Builder() : new Builder().mergeFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder newBuilderForType(
|
||||
BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||
// @@protoc_insertion_point(builder_implements:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20)
|
||||
dm_v2_20OrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return Dm_v2_20Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return Dm_v2_20Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
dm_v2_20.class, Builder.class);
|
||||
}
|
||||
|
||||
// Construct using tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20.newBuilder()
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
private Builder(
|
||||
BuilderParent parent) {
|
||||
super(parent);
|
||||
|
||||
}
|
||||
@Override
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
bitField0_ = 0;
|
||||
avatar_ = "";
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return Dm_v2_20Proto.internal_static_tech_ordinaryroad_live_chat_client_bilibili_protobuf_dm_v2_20_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2_20 getDefaultInstanceForType() {
|
||||
return dm_v2_20.getDefaultInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2_20 build() {
|
||||
dm_v2_20 result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2_20 buildPartial() {
|
||||
dm_v2_20 result = new dm_v2_20(this);
|
||||
if (bitField0_ != 0) { buildPartial0(result); }
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void buildPartial0(dm_v2_20 result) {
|
||||
int from_bitField0_ = bitField0_;
|
||||
if (((from_bitField0_ & 0x00000001) != 0)) {
|
||||
result.avatar_ = avatar_;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clone() {
|
||||
return super.clone();
|
||||
}
|
||||
@Override
|
||||
public Builder setField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.setField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder clearField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||
return super.clearField(field);
|
||||
}
|
||||
@Override
|
||||
public Builder clearOneof(
|
||||
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||
return super.clearOneof(oneof);
|
||||
}
|
||||
@Override
|
||||
public Builder setRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
int index, Object value) {
|
||||
return super.setRepeatedField(field, index, value);
|
||||
}
|
||||
@Override
|
||||
public Builder addRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.addRepeatedField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof dm_v2_20) {
|
||||
return mergeFrom((dm_v2_20)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(dm_v2_20 other) {
|
||||
if (other == dm_v2_20.getDefaultInstance()) return this;
|
||||
if (!other.getAvatar().isEmpty()) {
|
||||
avatar_ = other.avatar_;
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
if (extensionRegistry == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
case 34: {
|
||||
avatar_ = input.readStringRequireUtf8();
|
||||
bitField0_ |= 0x00000001;
|
||||
break;
|
||||
} // case 34
|
||||
default: {
|
||||
if (!super.parseUnknownField(input, extensionRegistry, tag)) {
|
||||
done = true; // was an endgroup tag
|
||||
}
|
||||
break;
|
||||
} // default:
|
||||
} // switch (tag)
|
||||
} // while (!done)
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.unwrapIOException();
|
||||
} finally {
|
||||
onChanged();
|
||||
} // finally
|
||||
return this;
|
||||
}
|
||||
private int bitField0_;
|
||||
|
||||
private Object avatar_ = "";
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The avatar.
|
||||
*/
|
||||
public String getAvatar() {
|
||||
Object ref = avatar_;
|
||||
if (!(ref instanceof String)) {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
avatar_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The bytes for avatar.
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getAvatarBytes() {
|
||||
Object ref = avatar_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
avatar_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @param value The avatar to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setAvatar(
|
||||
String value) {
|
||||
if (value == null) { throw new NullPointerException(); }
|
||||
avatar_ = value;
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder clearAvatar() {
|
||||
avatar_ = getDefaultInstance().getAvatar();
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @param value The bytes for avatar to set.
|
||||
* @return This builder for chaining.
|
||||
*/
|
||||
public Builder setAvatarBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) { throw new NullPointerException(); }
|
||||
checkByteStringIsUtf8(value);
|
||||
avatar_ = value;
|
||||
bitField0_ |= 0x00000001;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public final Builder setUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.setUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Builder mergeUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.mergeUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20)
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20)
|
||||
private static final dm_v2_20 DEFAULT_INSTANCE;
|
||||
static {
|
||||
DEFAULT_INSTANCE = new dm_v2_20();
|
||||
}
|
||||
|
||||
public static dm_v2_20 getDefaultInstance() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Parser<dm_v2_20>
|
||||
PARSER = new com.google.protobuf.AbstractParser<dm_v2_20>() {
|
||||
@Override
|
||||
public dm_v2_20 parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
Builder builder = newBuilder();
|
||||
try {
|
||||
builder.mergeFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (com.google.protobuf.UninitializedMessageException e) {
|
||||
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(e)
|
||||
.setUnfinishedMessage(builder.buildPartial());
|
||||
}
|
||||
return builder.buildPartial();
|
||||
}
|
||||
};
|
||||
|
||||
public static com.google.protobuf.Parser<dm_v2_20> parser() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Parser<dm_v2_20> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public dm_v2_20 getDefaultInstanceForType() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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: dm_v2_20.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
public interface dm_v2_20OrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:tech.ordinaryroad.live.chat.client.bilibili.protobuf.dm_v2_20)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The avatar.
|
||||
*/
|
||||
String getAvatar();
|
||||
/**
|
||||
* <code>string avatar = 4;</code>
|
||||
* @return The bytes for avatar.
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getAvatarBytes();
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aayushatharva.brotli4j.Brotli4jLoader;
|
||||
import com.aayushatharva.brotli4j.decoder.BrotliInputStream;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.OperationEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.ProtoverEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.AuthReplyMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.HeartbeatMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.HeartbeatReplyMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.SendSmsReplyMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.BaseBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.base.IBilibiliMsg;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/1/6
|
||||
*/
|
||||
@Slf4j
|
||||
public class BilibiliCodecUtil {
|
||||
|
||||
public static int sequence = 0;
|
||||
|
||||
public static final short FRAME_HEADER_LENGTH = 16;
|
||||
|
||||
public static ByteBuf encode(BaseBilibiliMsg msg) {
|
||||
ByteBuf out = Unpooled.buffer(FRAME_HEADER_LENGTH);
|
||||
String bodyJsonString = StrUtil.EMPTY;
|
||||
// HeartbeatMsg不需要正文,如果序列化后得到`{}`,则替换为空字符串
|
||||
if (!(msg instanceof HeartbeatMsg)) {
|
||||
bodyJsonString = msg.toString();
|
||||
if (StrUtil.EMPTY_JSON.equals(bodyJsonString)) {
|
||||
bodyJsonString = StrUtil.EMPTY;
|
||||
}
|
||||
}
|
||||
byte[] bodyBytes = bodyJsonString.getBytes(StandardCharsets.UTF_8);
|
||||
int length = bodyBytes.length + FRAME_HEADER_LENGTH;
|
||||
out.writeInt(length);
|
||||
out.writeShort(FRAME_HEADER_LENGTH);
|
||||
out.writeShort(msg.getProtoverEnum().getCode());
|
||||
out.writeInt(msg.getOperationEnum().getCode());
|
||||
out.writeInt(sequence++);
|
||||
out.writeBytes(bodyBytes);
|
||||
return out;
|
||||
}
|
||||
|
||||
public static List<IBilibiliMsg> decode(ByteBuf in) {
|
||||
List<IBilibiliMsg> msgList = new ArrayList<>();
|
||||
Queue<ByteBuf> pendingByteBuf = new LinkedList<>();
|
||||
|
||||
do {
|
||||
Optional<IBilibiliMsg> msg = doDecode(in, pendingByteBuf);
|
||||
msg.ifPresent(msgList::add);
|
||||
in = pendingByteBuf.poll();
|
||||
} while (in != null);
|
||||
|
||||
return msgList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行解码操作,有压缩则先解压,解压后可能得到多条消息
|
||||
*
|
||||
* @param in handler收到的一条消息
|
||||
* @param pendingByteBuf 用于存放未读取完的ByteBuf
|
||||
* @return Optional<IBilibiliMsg> 何时为空值:不支持的{@link OperationEnum},不支持的{@link ProtoverEnum},{@link #parse(OperationEnum, String)}反序列化失败
|
||||
* @see OperationEnum
|
||||
* @see ProtoverEnum
|
||||
*/
|
||||
private static Optional<IBilibiliMsg> doDecode(ByteBuf in, Queue<ByteBuf> pendingByteBuf) {
|
||||
int length = in.readInt();
|
||||
short frameHeaderLength = in.readShort();
|
||||
short protoverCode = in.readShort();
|
||||
int operationCode = in.readInt();
|
||||
int sequence = in.readInt();
|
||||
int contentLength = length - frameHeaderLength;
|
||||
byte[] inputBytes = new byte[contentLength];
|
||||
in.readBytes(inputBytes);
|
||||
if (in.readableBytes() != 0) {
|
||||
// log.error("in.readableBytes() {}", in.readableBytes());
|
||||
pendingByteBuf.offer(in);
|
||||
}
|
||||
|
||||
OperationEnum operationEnum = OperationEnum.getByCode(operationCode);
|
||||
if (operationEnum == null) {
|
||||
throw new BaseException(String.format("未知operation: %d", operationCode));
|
||||
}
|
||||
if (protoverCode == ProtoverEnum.NORMAL_ZLIB.getCode()) {
|
||||
switch (operationEnum) {
|
||||
case SEND_SMS_REPLY: {
|
||||
// Decompress the bytes
|
||||
Inflater inflater = new Inflater();
|
||||
inflater.reset();
|
||||
inflater.setInput(inputBytes);
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(contentLength);
|
||||
try {
|
||||
byte[] bytes = new byte[1024];
|
||||
while (!inflater.finished()) {
|
||||
int count = inflater.inflate(bytes);
|
||||
byteArrayOutputStream.write(bytes, 0, count);
|
||||
}
|
||||
} catch (DataFormatException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
inflater.end();
|
||||
|
||||
return doDecode(Unpooled.wrappedBuffer(byteArrayOutputStream.toByteArray()), pendingByteBuf);
|
||||
}
|
||||
case HEARTBEAT_REPLY: {
|
||||
BigInteger bigInteger = new BigInteger(inputBytes);
|
||||
return parse(operationEnum, String.format("{\"popularity\":%d}", bigInteger));
|
||||
}
|
||||
default: {
|
||||
String s = new String(inputBytes, StandardCharsets.UTF_8);
|
||||
return parse(operationEnum, s);
|
||||
}
|
||||
}
|
||||
} else if (protoverCode == ProtoverEnum.NORMAL_NO_COMPRESSION.getCode()) {
|
||||
switch (operationEnum) {
|
||||
case HEARTBEAT_REPLY: {
|
||||
BigInteger bigInteger = new BigInteger(inputBytes);
|
||||
return parse(operationEnum, String.format("{\"popularity\":%d}", bigInteger));
|
||||
}
|
||||
default: {
|
||||
String s = new String(inputBytes, StandardCharsets.UTF_8);
|
||||
return parse(operationEnum, s);
|
||||
}
|
||||
}
|
||||
} else if (protoverCode == ProtoverEnum.HEARTBEAT_AUTH_NO_COMPRESSION.getCode()) {
|
||||
switch (operationEnum) {
|
||||
case HEARTBEAT_REPLY: {
|
||||
BigInteger bigInteger = new BigInteger(inputBytes);
|
||||
return parse(operationEnum, String.format("{\"popularity\":%d}", bigInteger));
|
||||
}
|
||||
default: {
|
||||
String s = new String(inputBytes, StandardCharsets.UTF_8);
|
||||
return parse(operationEnum, s);
|
||||
}
|
||||
}
|
||||
} else if (protoverCode == ProtoverEnum.NORMAL_BROTLI.getCode()) {
|
||||
switch (operationEnum) {
|
||||
case SEND_SMS_REPLY: {
|
||||
// Load the native library
|
||||
Brotli4jLoader.ensureAvailability();
|
||||
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(inputBytes);
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(contentLength);
|
||||
byte[] bytes = new byte[1024];
|
||||
BrotliInputStream brotliInputStream = null;
|
||||
ByteBuf wrappedBuffer = null;
|
||||
try {
|
||||
brotliInputStream = new BrotliInputStream(byteArrayInputStream);
|
||||
int count;
|
||||
while ((count = brotliInputStream.read(bytes)) > -1) {
|
||||
byteArrayOutputStream.write(bytes, 0, count);
|
||||
}
|
||||
wrappedBuffer = Unpooled.wrappedBuffer(byteArrayOutputStream.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new BaseException(e);
|
||||
} finally {
|
||||
try {
|
||||
// Close the BrotliInputStream. This also closes the InputStream.
|
||||
if (brotliInputStream != null) {
|
||||
brotliInputStream.close();
|
||||
}
|
||||
byteArrayOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error("解压失败", e);
|
||||
}
|
||||
}
|
||||
return doDecode(wrappedBuffer, pendingByteBuf);
|
||||
}
|
||||
case HEARTBEAT_REPLY: {
|
||||
BigInteger bigInteger = new BigInteger(inputBytes);
|
||||
return parse(operationEnum, String.format("{\"popularity\":%d}", bigInteger));
|
||||
}
|
||||
default: {
|
||||
String s = new String(inputBytes, StandardCharsets.UTF_8);
|
||||
return parse(operationEnum, s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("暂不支持的版本:{}", protoverCode);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<IBilibiliMsg> parse(OperationEnum operation, String jsonString) {
|
||||
switch (operation) {
|
||||
case SEND_SMS_REPLY: {
|
||||
try {
|
||||
return Optional.ofNullable(BaseBilibiliMsg.OBJECT_MAPPER.readValue(jsonString, SendSmsReplyMsg.class));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
case AUTH_REPLY: {
|
||||
try {
|
||||
return Optional.ofNullable(BaseBilibiliMsg.OBJECT_MAPPER.readValue(jsonString, AuthReplyMsg.class));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
case HEARTBEAT_REPLY: {
|
||||
try {
|
||||
return Optional.ofNullable(BaseBilibiliMsg.OBJECT_MAPPER.readValue(jsonString, HeartbeatReplyMsg.class));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
default: {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("暂不支持 {}", operation);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
option java_package = "tech.ordinaryroad.live.chat.client.bilibili.protobuf";
|
||||
option java_outer_classname = "Dm_v2Proto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
import "dm_v2_20.proto";
|
||||
|
||||
message dm_v2 {
|
||||
dm_v2_20 dm_v2_20 = 20;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.protobuf;
|
||||
|
||||
option java_package = "tech.ordinaryroad.live.chat.client.bilibili.protobuf";
|
||||
option java_outer_classname = "Dm_v2_20Proto";
|
||||
option java_multiple_files = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
message dm_v2_20 {
|
||||
string avatar = 4;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package tech.ordinaryroad.live.chat.client.bilibili.api;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/9/7
|
||||
*/
|
||||
class BilibiliApisTest {
|
||||
|
||||
@Test
|
||||
void sendMsg() {
|
||||
String cookie = System.getenv("cookie");
|
||||
BilibiliApis.sendMsg("666", 545068, cookie);
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* 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.bilibili.client;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.config.BilibiliLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.constant.BilibiliCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.listener.IBilibiliMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.msg.*;
|
||||
import tech.ordinaryroad.live.chat.client.bilibili.netty.handler.BilibiliBinaryFrameHandler;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2023/8/26
|
||||
*/
|
||||
@Slf4j
|
||||
class BilibiliLiveChatClientTest {
|
||||
|
||||
static Object lock = new Object();
|
||||
BilibiliLiveChatClient client;
|
||||
|
||||
@Test
|
||||
void example() throws InterruptedException {
|
||||
String cookie = System.getenv("cookie");
|
||||
log.error("cookie: {}", cookie);
|
||||
BilibiliLiveChatClientConfig config = BilibiliLiveChatClientConfig.builder()
|
||||
// TODO 浏览器Cookie
|
||||
.cookie(cookie)
|
||||
.roomId(7777)
|
||||
.roomId(697)
|
||||
.build();
|
||||
|
||||
client = new BilibiliLiveChatClient(config, new IBilibiliMsgListener() {
|
||||
@Override
|
||||
public void onDanmuMsg(BilibiliBinaryFrameHandler binaryFrameHandler, DanmuMsgMsg msg) {
|
||||
IBilibiliMsgListener.super.onDanmuMsg(binaryFrameHandler, msg);
|
||||
log.info("{} 收到弹幕 {} {}({}):{}", binaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid(), msg.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGiftMsg(BilibiliBinaryFrameHandler binaryFrameHandler, SendGiftMsg msg) {
|
||||
IBilibiliMsgListener.super.onGiftMsg(binaryFrameHandler, msg);
|
||||
log.info("{} 收到礼物 {} {}({}) {} {}({})x{}({})", binaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid(), msg.getData().getAction(), msg.getGiftName(), msg.getGiftId(), msg.getGiftCount(), msg.getGiftPrice());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuperChatMsg(BilibiliBinaryFrameHandler binaryFrameHandler, SuperChatMessageMsg msg) {
|
||||
IBilibiliMsgListener.super.onSuperChatMsg(binaryFrameHandler, msg);
|
||||
log.info("{} 收到醒目留言 {}({}):{}", binaryFrameHandler.getRoomId(), msg.getUsername(), msg.getUid(), msg.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterRoomMsg(InteractWordMsg msg) {
|
||||
log.info("{} {}({}) 进入直播间", msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLikeMsg(BilibiliBinaryFrameHandler binaryFrameHandler, LikeInfoV3ClickMsg msg) {
|
||||
IBilibiliMsgListener.super.onLikeMsg(binaryFrameHandler, msg);
|
||||
log.info("{} 收到点赞 {} {}({})", binaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntryEffect(SendSmsReplyMsg msg) {
|
||||
JsonNode data = msg.getData();
|
||||
String copyWriting = data.get("copy_writing").asText();
|
||||
log.info("入场效果 {}", copyWriting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWatchedChange(SendSmsReplyMsg msg) {
|
||||
JsonNode data = msg.getData();
|
||||
int num = data.get("num").asInt();
|
||||
String textSmall = data.get("text_small").asText();
|
||||
String textLarge = data.get("text_large").asText();
|
||||
log.debug("观看人数变化 {} {} {}", num, textSmall, textLarge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickLike(SendSmsReplyMsg msg) {
|
||||
JsonNode data = msg.getData();
|
||||
String uname = data.get("uname").asText();
|
||||
String likeText = data.get("like_text").asText();
|
||||
log.debug("为主播点赞 {} {}", uname, likeText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickUpdate(SendSmsReplyMsg msg) {
|
||||
JsonNode data = msg.getData();
|
||||
int clickCount = data.get("click_count").asInt();
|
||||
log.debug("点赞数更新 {}", clickCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsg(IMsg msg) {
|
||||
log.debug("收到{}消息 {}", msg.getClass(), msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCmdMsg(BilibiliCmdEnum cmd, ICmdMsg<BilibiliCmdEnum> cmdMsg) {
|
||||
log.debug("收到CMD消息{} {}", cmd, cmdMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOtherCmdMsg(BilibiliCmdEnum cmd, ICmdMsg<BilibiliCmdEnum> cmdMsg) {
|
||||
// log.debug("收到其他CMD消息 {}", cmd);
|
||||
switch (cmd) {
|
||||
case GUARD_BUY: {
|
||||
// 有人上舰
|
||||
SendSmsReplyMsg sendSmsReplyMsg = (SendSmsReplyMsg) cmdMsg;
|
||||
break;
|
||||
}
|
||||
case SUPER_CHAT_MESSAGE_DELETE: {
|
||||
// 删除醒目留言
|
||||
SendSmsReplyMsg sendSmsReplyMsg = (SendSmsReplyMsg) cmdMsg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnknownCmd(String cmdString, IMsg msg) {
|
||||
log.debug("收到未知CMD消息 {}", cmdString);
|
||||
}
|
||||
});
|
||||
client.connect();
|
||||
|
||||
client.addStatusChangeListener(evt -> {
|
||||
ClientStatusEnums newValue = (ClientStatusEnums) evt.getNewValue();
|
||||
if (newValue == ClientStatusEnums.CONNECTED) {
|
||||
ThreadUtil.execAsync(() -> {
|
||||
ThreadUtil.sleep(5000);
|
||||
client.clickLike(5, () -> {
|
||||
log.warn("为主播点赞成功");
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 防止测试时直接退出
|
||||
while (true) {
|
||||
synchronized (lock) {
|
||||
lock.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-clients</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>live-chat-client-douyin</artifactId>
|
||||
<name>live-chat-client-douyin</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.ruoyi</groupId>
|
||||
<artifactId>live-chat-client-servers-netty-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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.douyin;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.douyin.client.DouyinLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.config.DouyinLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.listener.IDouyinMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.netty.handler.DouyinBinaryFrameHandler;
|
||||
|
||||
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. 创建配置
|
||||
DouyinLiveChatClientConfig config = DouyinLiveChatClientConfig.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("Jiazi-9931")
|
||||
.build();
|
||||
|
||||
// 2. 创建Client并传入配置、添加消息回调
|
||||
DouyinLiveChatClient client = new DouyinLiveChatClient(config, new IDouyinMsgListener() {
|
||||
// @Override
|
||||
// public void onMsg(IMsg msg) {
|
||||
// log.debug("收到{}消息 {}", msg.getClass(), msg);
|
||||
// }
|
||||
// @Override
|
||||
// public void onUnknownCmd(String cmdString, IMsg msg) {
|
||||
// log.debug("收到未知CMD消息 {}", cmdString);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onDanmuMsg(DouyinBinaryFrameHandler douyinBinaryFrameHandler, DouyinDanmuMsg msg) {
|
||||
log.info("{} 收到弹幕 [{}] {}({}):{}", douyinBinaryFrameHandler.getRoomId(), msg.getBadgeLevel() != 0 ? msg.getBadgeLevel() + msg.getBadgeName() : "", msg.getUsername(), msg.getUid(), msg.getContent());
|
||||
}
|
||||
|
||||
});
|
||||
// 3. 开始监听直播间
|
||||
client.connect();
|
||||
|
||||
// 客户端连接状态回调
|
||||
// client.addStatusChangeListener(evt -> {
|
||||
// if (evt.getNewValue().equals(ClientStatusEnums.CONNECTED)) {
|
||||
// // TODO 要发送的弹幕内容,请注意控制发送频率;框架内置支持设置发送弹幕的最少时间间隔,小于时将忽略该次发送
|
||||
// client.sendDanmu("666666" + RandomUtil.randomNumbers(1));
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.api;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.exception.BaseException;
|
||||
import tech.ordinaryroad.live.chat.client.commons.util.OrLiveChatCookieUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/3
|
||||
*/
|
||||
@Slf4j
|
||||
public class DouyinApis {
|
||||
|
||||
public static final String KEY_COOKIE_TTWID = "ttwid";
|
||||
public static final String KEY_COOKIE_MS_TOKEN = "msToken";
|
||||
public static final String KEY_COOKIE_AC_NONCE = "__ac_nonce";
|
||||
public static final String MS_TOKEN_BASE_STRING = RandomUtil.BASE_CHAR_NUMBER_LOWER + "=_";
|
||||
public static final int MS_TOKEN_LENGTH = 107;
|
||||
public static final int AC_NONCE_LENGTH = 21;
|
||||
public static final String PATTERN_USER_UNIQUE_ID = "\\\\\"user_unique_id\\\\\":\\\\\"(\\d+)\\\\\"";
|
||||
public static final String PATTERN_ROOM_ID = "\\\\\"roomId\\\\\":\\\\\"(\\d+)\\\\\"";
|
||||
|
||||
public static RoomInitResult roomInit(Object roomId, String cookie) {
|
||||
Map<String, String> cookieMap = OrLiveChatCookieUtil.parseCookieString(cookie);
|
||||
|
||||
@Cleanup
|
||||
HttpResponse response1 = HttpUtil.createGet("https://live.douyin.com/").cookie(cookie).execute();
|
||||
String ttwid = OrLiveChatCookieUtil.getCookieByName(cookieMap, KEY_COOKIE_TTWID, () -> response1.getCookie(KEY_COOKIE_TTWID).getValue());
|
||||
String msToken = OrLiveChatCookieUtil.getCookieByName(cookieMap, KEY_COOKIE_MS_TOKEN, () -> RandomUtil.randomString(MS_TOKEN_BASE_STRING, MS_TOKEN_LENGTH));
|
||||
String __ac_nonce = OrLiveChatCookieUtil.getCookieByName(cookieMap, KEY_COOKIE_AC_NONCE, () -> RandomUtil.randomString(AC_NONCE_LENGTH));
|
||||
|
||||
@Cleanup
|
||||
HttpResponse response2 = HttpUtil.createGet("https://live.douyin.com/" + roomId)
|
||||
.cookie(StrUtil.emptyToDefault(cookie, KEY_COOKIE_TTWID + "=" + ttwid + "; " + KEY_COOKIE_MS_TOKEN + "=" + msToken + "; " + KEY_COOKIE_AC_NONCE + "=" + __ac_nonce))
|
||||
.execute();
|
||||
if (response2.getStatus() != HttpStatus.HTTP_OK) {
|
||||
throw new BaseException("获取" + roomId + "真实房间ID失败");
|
||||
}
|
||||
String user_unique_id = StrUtil.emptyToDefault(ReUtil.getGroup1(PATTERN_USER_UNIQUE_ID, response2.body()), RandomUtil.randomNumbers(19));
|
||||
long realRoomId;
|
||||
String realRoomIdString = ReUtil.getGroup1(PATTERN_ROOM_ID, response2.body());
|
||||
try {
|
||||
realRoomId = NumberUtil.parseLong(realRoomIdString);
|
||||
} catch (Exception e) {
|
||||
throw new BaseException("获取" + roomId + "真实房间ID失败");
|
||||
}
|
||||
|
||||
|
||||
return RoomInitResult.builder()
|
||||
.ttwid(ttwid)
|
||||
.msToken(msToken)
|
||||
.acNonce(__ac_nonce)
|
||||
.realRoomId(realRoomId)
|
||||
.userUniqueId(user_unique_id)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static RoomInitResult roomInit(Object roomId) {
|
||||
return roomInit(roomId, null);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public static class RoomInitResult {
|
||||
private String ttwid;
|
||||
private String msToken;
|
||||
private String acNonce;
|
||||
private long realRoomId;
|
||||
private String userUniqueId;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.client;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.http.GlobalHeaders;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
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.extern.slf4j.Slf4j;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.api.DouyinApis;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.config.DouyinLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.constant.DouyinCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.listener.IDouyinConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.listener.IDouyinMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.netty.handler.DouyinBinaryFrameHandler;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.netty.handler.DouyinConnectionHandler;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.base.BaseNettyClient;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
@Slf4j
|
||||
public class DouyinLiveChatClient extends BaseNettyClient<
|
||||
DouyinLiveChatClientConfig,
|
||||
DouyinCmdEnum,
|
||||
IDouyinMsg,
|
||||
IDouyinMsgListener,
|
||||
DouyinConnectionHandler,
|
||||
DouyinBinaryFrameHandler> {
|
||||
|
||||
private DouyinApis.RoomInitResult roomInitResult = new DouyinApis.RoomInitResult();
|
||||
|
||||
public DouyinLiveChatClient(DouyinLiveChatClientConfig config, List<IDouyinMsgListener> msgListeners, IDouyinConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListeners(msgListeners);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public DouyinLiveChatClient(DouyinLiveChatClientConfig config, IDouyinMsgListener msgListener, IDouyinConnectionListener connectionListener, EventLoopGroup workerGroup) {
|
||||
super(config, workerGroup, connectionListener);
|
||||
addMsgListener(msgListener);
|
||||
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
public DouyinLiveChatClient(DouyinLiveChatClientConfig config, IDouyinMsgListener msgListener, IDouyinConnectionListener connectionListener) {
|
||||
this(config, msgListener, connectionListener, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public DouyinLiveChatClient(DouyinLiveChatClientConfig config, IDouyinMsgListener msgListener) {
|
||||
this(config, msgListener, null, new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public DouyinLiveChatClient(DouyinLiveChatClientConfig config) {
|
||||
this(config, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
roomInitResult = DouyinApis.roomInit(getConfig().getRoomId(), getConfig().getCookie());
|
||||
super.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DouyinConnectionHandler initConnectionHandler(IBaseConnectionListener<DouyinConnectionHandler> clientConnectionListener) {
|
||||
DefaultHttpHeaders headers = new DefaultHttpHeaders();
|
||||
headers.add(Header.COOKIE.name(), DouyinApis.KEY_COOKIE_TTWID + "=" + roomInitResult.getTtwid());
|
||||
headers.add(Header.USER_AGENT.name(), GlobalHeaders.INSTANCE.header(Header.USER_AGENT));
|
||||
return new DouyinConnectionHandler(
|
||||
WebSocketClientHandshakerFactory.newHandshaker(getWebsocketUri(), WebSocketVersion.V13, null, true, headers, getConfig().getMaxFramePayloadLength()),
|
||||
DouyinLiveChatClient.this, clientConnectionListener
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DouyinBinaryFrameHandler initBinaryFrameHandler() {
|
||||
return new DouyinBinaryFrameHandler(super.msgListeners, DouyinLiveChatClient.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWebSocketUriString() {
|
||||
long realRoomId = roomInitResult.getRealRoomId();
|
||||
String userUniqueId = roomInitResult.getUserUniqueId();
|
||||
|
||||
String webSocketUriString = super.getWebSocketUriString();
|
||||
Map<String, String> queryParams = new HashMap<>();
|
||||
queryParams.put("app_name", "douyin_web");
|
||||
queryParams.put("version_code", getConfig().getVersionCode());
|
||||
queryParams.put("webcast_sdk_version", getConfig().getWebcastSdkVersion());
|
||||
queryParams.put("update_version_code", getConfig().getUpdateVersionCode());
|
||||
queryParams.put("compress", "gzip");
|
||||
queryParams.put("device_platform", "web");
|
||||
queryParams.put("cookie_enabled", "true");
|
||||
queryParams.put("screen_width", "800");
|
||||
queryParams.put("screen_height", "1280");
|
||||
queryParams.put("browser_language", "zh-CN");
|
||||
queryParams.put("browser_platform", "MacIntel");
|
||||
queryParams.put("browser_name", "Mozilla");
|
||||
queryParams.put("browser_version", "5.0%20(Macintosh;%20Intel%20Mac%20OS%20X%2010_15_7)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/116.0.0.0%20Safari/537.36");
|
||||
queryParams.put("browser_online", "true");
|
||||
queryParams.put("tz_name", "Asia/Shanghai");
|
||||
queryParams.put("host", "https://live.douyin.com");
|
||||
queryParams.put("im_path", "/webcast/im/fetch/");
|
||||
queryParams.put("endpoint", "live_pc");
|
||||
queryParams.put("identity", "audience");
|
||||
|
||||
queryParams.put("support_wrds", "1");
|
||||
queryParams.put("heartbeatDuration ", "0");
|
||||
queryParams.put("live_id", "1");
|
||||
queryParams.put("did_rule", "3");
|
||||
queryParams.put("aid", "6383");
|
||||
|
||||
queryParams.put("room_id", Long.toString(realRoomId));
|
||||
queryParams.put("user_unique_id", userUniqueId);
|
||||
// TODO 生成signature
|
||||
queryParams.put("signature", "00000000");
|
||||
queryParams.put("cursor", "t-" + System.currentTimeMillis() + "_r-1_d-1_u-1_h-1");
|
||||
queryParams.put("internal_ext", "internal_src:dim|" +
|
||||
"wss_push_room_id:" + realRoomId + "|" +
|
||||
"wss_push_did:" + userUniqueId + "|" +
|
||||
"dim_log_id:" + DateUtil.format(new Date(), "yyyy-MM-dd") + RandomUtil.randomNumbers(6) + RandomUtil.randomString("0123456789ABCDEF", 20) + "|" +
|
||||
"first_req_ms:" + System.currentTimeMillis() + "|" +
|
||||
"fetch_time:" + System.currentTimeMillis() + "|" +
|
||||
"seq:1|" +
|
||||
"wss_info:0-" + System.currentTimeMillis() + "-0-0|" +
|
||||
"wrds_kvs:WebcastRoomStatsMessage-" + System.nanoTime() + "_WebcastRoomRankMessage-" + System.nanoTime() + "_LotteryInfoSyncData-" + System.nanoTime() + "_WebcastActivityEmojiGroupsMessage-" + System.nanoTime());
|
||||
return webSocketUriString + "?" + HttpUtil.toParams(queryParams);
|
||||
}
|
||||
|
||||
public void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed) {
|
||||
super.sendDanmu(danmu, success, failed);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.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/2
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class DouyinLiveChatClientConfig extends BaseNettyClientConfig {
|
||||
|
||||
@Builder.Default
|
||||
private int aggregatorMaxContentLength = 64 * 1024 * 1024;
|
||||
|
||||
@Builder.Default
|
||||
private int maxFramePayloadLength = 64 * 1024 * 1024;
|
||||
|
||||
private String versionCode = "180800";
|
||||
|
||||
private String webcastSdkVersion = "1.0.12";
|
||||
|
||||
private String updateVersionCode = "1.0.12";
|
||||
|
||||
/**
|
||||
* 示例
|
||||
* wss://webcast5-ws-web-lf.douyin.com/webcast/im/push/v2/
|
||||
* ?app_name=douyin_web
|
||||
* &version_code=180800
|
||||
* &webcast_sdk_version=1.0.12
|
||||
* &update_version_code=1.0.12
|
||||
* &compress=gzip
|
||||
* &device_platform=web
|
||||
* &cookie_enabled=true
|
||||
* &screen_width=1512
|
||||
* &screen_height=982
|
||||
* &browser_language=zh-CN
|
||||
* &browser_platform=MacIntel
|
||||
* &browser_name=Mozilla
|
||||
* &browser_version=5.0%20(Macintosh;%20Intel%20Mac%20OS%20X%2010_15_7)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/118.0.0.0%20Safari/537.36
|
||||
* &browser_online=true
|
||||
* &tz_name=Asia/Shanghai
|
||||
* &cursor=u-1_h-1_t-1704202376885_r-1_d-1
|
||||
* &internal_ext=internal_src:dim|wss_push_room_id:7319486720022301449|wss_push_did:7319492411867170356|dim_log_id:20240102213256AAA5B735ADBE992BEF6A|first_req_ms:1704202376757|fetch_time:1704202376885|seq:1|wss_info:0-1704202376885-0-0|wrds_kvs:WebcastActivityEmojiGroupsMessage-1704200830782138545_WebcastRoomRankMessage-1704202270876589607_WebcastRoomStatsMessage-1704202372842388781
|
||||
* &host=https://live.douyin.com
|
||||
* &aid=6383
|
||||
* &live_id=1
|
||||
* &did_rule=3
|
||||
* &endpoint=live_pc
|
||||
* &support_wrds=1
|
||||
* &user_unique_id=7319492411867170356
|
||||
* &im_path=/webcast/im/fetch/
|
||||
* &identity=audience
|
||||
* &need_persist_msg_count=15
|
||||
* &room_id=7319486720022301449
|
||||
* &heartbeatDuration=0
|
||||
* &signature=Wk407jV1/WbnoIGk
|
||||
*/
|
||||
@Builder.Default
|
||||
private String websocketUri = "wss://webcast5-ws-web-lf.douyin.com:443/webcast/im/push/v2/";
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.constant;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum DouyinCmdEnum {
|
||||
|
||||
/**
|
||||
* 弹幕
|
||||
*/
|
||||
WebcastChatMessage,
|
||||
/**
|
||||
* 礼物
|
||||
*/
|
||||
WebcastGiftMessage,
|
||||
/**
|
||||
* 点赞
|
||||
*/
|
||||
WebcastLikeMessage,
|
||||
/**
|
||||
* 入房
|
||||
*/
|
||||
WebcastMemberMessage,
|
||||
WebcastSocialMessage,
|
||||
WebcastRoomUserSeqMessage,
|
||||
WebcastFansclubMessage,
|
||||
WebcastControlMessage,
|
||||
;
|
||||
|
||||
public static DouyinCmdEnum getByName(String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (DouyinCmdEnum value : values()) {
|
||||
if (value.name().equals(name)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.listener;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.IBaseConnectionListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.netty.handler.DouyinConnectionHandler;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
public interface IDouyinConnectionListener extends IBaseConnectionListener<DouyinConnectionHandler> {
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.listener;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.listener.*;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.constant.DouyinCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinEnterRoomMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinLikeMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.netty.handler.DouyinBinaryFrameHandler;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
public interface IDouyinMsgListener extends IBaseMsgListener<DouyinBinaryFrameHandler, DouyinCmdEnum>,
|
||||
IDanmuMsgListener<DouyinBinaryFrameHandler, DouyinDanmuMsg>,
|
||||
IGiftMsgListener<DouyinBinaryFrameHandler, DouyinGiftMsg>,
|
||||
IEnterRoomMsgListener<DouyinBinaryFrameHandler, DouyinEnterRoomMsg>,
|
||||
ILikeMsgListener<DouyinBinaryFrameHandler, DouyinLikeMsg> {
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
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.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DouyinDanmuMsg implements IDouyinMsg, IDanmuMsg {
|
||||
|
||||
private douyin_webcast_chat_message_msg msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
return msg.getUser().getFansClub().getData().getClubName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return (byte) msg.getUser().getFansClub().getData().getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return Long.toString(msg.getUser().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getNickname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return CollUtil.getFirst(msg.getUser().getAvatarThumb().getUrlListListList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
return msg.getContent();
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IEnterRoomMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_member_message_msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DouyinEnterRoomMsg implements IDouyinMsg, IEnterRoomMsg {
|
||||
|
||||
private douyin_webcast_member_message_msg msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
return msg.getUser().getFansClub().getData().getClubName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return (byte) msg.getUser().getFansClub().getData().getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return Long.toString(msg.getUser().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getNickname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return CollUtil.getFirst(msg.getUser().getAvatarThumb().getUrlListListList());
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
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.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/9
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DouyinGiftMsg implements IDouyinMsg, IGiftMsg {
|
||||
|
||||
private douyin_webcast_gift_message_msg msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
return msg.getUser().getFansClub().getData().getClubName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return (byte) msg.getUser().getFansClub().getData().getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return Long.toString(msg.getUser().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getNickname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return CollUtil.getFirst(msg.getUser().getAvatarThumb().getUrlListListList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftName() {
|
||||
return msg.getGift().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftImg() {
|
||||
return CollUtil.getFirst(msg.getGift().getImage().getUrlListListList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGiftId() {
|
||||
return Long.toString(msg.getLongGiftId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftCount() {
|
||||
return (int) msg.getTotalCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGiftPrice() {
|
||||
return msg.getGift().getDiamondCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUid() {
|
||||
return Long.toString(msg.getToUser().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReceiveUsername() {
|
||||
return msg.getToUser().getNickname();
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
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.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_like_message_msg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/31
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class DouyinLikeMsg implements IDouyinMsg, ILikeMsg {
|
||||
|
||||
private douyin_webcast_like_message_msg msg;
|
||||
|
||||
@Override
|
||||
public String getBadgeName() {
|
||||
return msg.getUser().getFansClub().getData().getClubName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getBadgeLevel() {
|
||||
return (byte) msg.getUser().getFansClub().getData().getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUid() {
|
||||
return Long.toString(msg.getUser().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return msg.getUser().getNickname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserAvatar() {
|
||||
return CollUtil.getFirst(msg.getUser().getAvatarThumb().getUrlListListList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClickCount() {
|
||||
return (int) msg.getCount();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg.base;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.ICmdMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.constant.DouyinCmdEnum;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
public interface IDouyinCmdMsg extends IDouyinMsg, ICmdMsg<DouyinCmdEnum> {
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.msg.base;
|
||||
|
||||
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
public interface IDouyinMsg extends IMsg {
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.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.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||
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.douyin.client.DouyinLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.constant.DouyinCmdEnum;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.listener.IDouyinMsgListener;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinDanmuMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinEnterRoomMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinGiftMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.DouyinLikeMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.msg.base.IDouyinMsg;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.protobuf.*;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientBinaryFrameHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class DouyinBinaryFrameHandler extends BaseNettyClientBinaryFrameHandler<DouyinLiveChatClient, DouyinBinaryFrameHandler, DouyinCmdEnum, IDouyinMsg, IDouyinMsgListener> {
|
||||
|
||||
private ChannelHandlerContext channelHandlerContext;
|
||||
|
||||
public DouyinBinaryFrameHandler(List<IDouyinMsgListener> iDouyinMsgListeners, DouyinLiveChatClient client) {
|
||||
super(iDouyinMsgListeners, client);
|
||||
}
|
||||
|
||||
public DouyinBinaryFrameHandler(List<IDouyinMsgListener> iDouyinMsgListeners, long roomId) {
|
||||
super(iDouyinMsgListeners, roomId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
|
||||
super.handlerAdded(ctx);
|
||||
channelHandlerContext = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
|
||||
super.handlerRemoved(ctx);
|
||||
channelHandlerContext = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCmdMsg(DouyinCmdEnum cmd, ICmdMsg<DouyinCmdEnum> cmdMsg) {
|
||||
if (super.msgListeners.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ByteString payload = ((douyin_cmd_msg) cmdMsg).getPayload();
|
||||
switch (cmd) {
|
||||
case WebcastChatMessage: {
|
||||
try {
|
||||
douyin_webcast_chat_message_msg douyinWebcastChatMessageMsg = douyin_webcast_chat_message_msg.parseFrom(payload);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onDanmuMsg(DouyinBinaryFrameHandler.this, new DouyinDanmuMsg(douyinWebcastChatMessageMsg)));
|
||||
} catch (IOException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WebcastGiftMessage: {
|
||||
try {
|
||||
douyin_webcast_gift_message_msg douyinWebcastGiftMessageMsg = douyin_webcast_gift_message_msg.parseFrom(payload);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onGiftMsg(DouyinBinaryFrameHandler.this, new DouyinGiftMsg(douyinWebcastGiftMessageMsg)));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WebcastMemberMessage: {
|
||||
try {
|
||||
douyin_webcast_member_message_msg douyinWebcastMemberMessageMsg = douyin_webcast_member_message_msg.parseFrom(payload);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onEnterRoomMsg(DouyinBinaryFrameHandler.this, new DouyinEnterRoomMsg(douyinWebcastMemberMessageMsg)));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WebcastLikeMessage: {
|
||||
try {
|
||||
douyin_webcast_like_message_msg douyinWebcastLikeMessageMsg = douyin_webcast_like_message_msg.parseFrom(payload);
|
||||
iteratorMsgListeners(msgListener -> msgListener.onLikeMsg(DouyinBinaryFrameHandler.this, new DouyinLikeMsg(douyinWebcastLikeMessageMsg)));
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
iteratorMsgListeners(msgListener -> msgListener.onOtherCmdMsg(DouyinBinaryFrameHandler.this, cmd, cmdMsg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<IDouyinMsg> decode(ByteBuf byteBuf) {
|
||||
try {
|
||||
douyin_websocket_frame douyinWebsocketFrame = douyin_websocket_frame.parseFrom(byteBuf.nioBuffer());
|
||||
ByteString payload = douyinWebsocketFrame.getPayload();
|
||||
byte[] bytes = ZipUtil.unGzip(payload.newInput());
|
||||
douyin_websocket_frame_msg douyinWebsocketFrameMsg = douyin_websocket_frame_msg.parseFrom(bytes);
|
||||
|
||||
// 抖音不是使用心跳,而是ACK
|
||||
if (douyinWebsocketFrameMsg.getNeedAck()) {
|
||||
douyin_websocket_frame ack = douyin_websocket_frame.newBuilder()
|
||||
.setLogId(douyinWebsocketFrame.getLogId())
|
||||
.setPayloadType("ack")
|
||||
.setPayload(douyinWebsocketFrameMsg.getInternalExtBytes())
|
||||
.build();
|
||||
channelHandlerContext.writeAndFlush(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(ack.toByteArray())));
|
||||
}
|
||||
|
||||
return new ArrayList<>(douyinWebsocketFrameMsg.getMessagesListList());
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw new BaseException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* 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.douyin.netty.handler;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
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.douyin.client.DouyinLiveChatClient;
|
||||
import tech.ordinaryroad.live.chat.client.douyin.config.DouyinLiveChatClientConfig;
|
||||
import tech.ordinaryroad.live.chat.client.servers.netty.client.handler.BaseNettyClientConnectionHandler;
|
||||
|
||||
/**
|
||||
* @author mjz
|
||||
* @date 2024/1/2
|
||||
*/
|
||||
@Slf4j
|
||||
@ChannelHandler.Sharable
|
||||
public class DouyinConnectionHandler extends BaseNettyClientConnectionHandler<DouyinLiveChatClient, DouyinConnectionHandler> {
|
||||
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private final Object roomId;
|
||||
/**
|
||||
* 以ClientConfig为主
|
||||
*/
|
||||
private String cookie;
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, DouyinLiveChatClient client, IBaseConnectionListener<DouyinConnectionHandler> listener) {
|
||||
super(handshaker, client, listener);
|
||||
this.roomId = client.getConfig().getRoomId();
|
||||
this.cookie = client.getConfig().getCookie();
|
||||
}
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, DouyinLiveChatClient client) {
|
||||
this(handshaker, client, null);
|
||||
}
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, IBaseConnectionListener<DouyinConnectionHandler> listener, String cookie) {
|
||||
super(handshaker, listener);
|
||||
this.roomId = roomId;
|
||||
this.cookie = cookie;
|
||||
}
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, IBaseConnectionListener<DouyinConnectionHandler> listener) {
|
||||
this(handshaker, roomId, listener, null);
|
||||
}
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, long roomId, String cookie) {
|
||||
this(handshaker, roomId, null, cookie);
|
||||
}
|
||||
|
||||
public DouyinConnectionHandler(WebSocketClientHandshaker handshaker, long roomId) {
|
||||
this(handshaker, roomId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendHeartbeat(ChannelHandlerContext ctx) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAuthRequest(Channel channel) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatPeriod() {
|
||||
if (client == null) {
|
||||
return DouyinLiveChatClientConfig.DEFAULT_HEARTBEAT_PERIOD;
|
||||
} else {
|
||||
return client.getConfig().getHeartbeatPeriod();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getHeartbeatInitialDelay() {
|
||||
if (client == null) {
|
||||
return DouyinLiveChatClientConfig.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;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* 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: douyin_cmd_msg.proto
|
||||
|
||||
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
|
||||
|
||||
public final class Douyin_cmd_msgProto {
|
||||
private Douyin_cmd_msgProto() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
static final com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor;
|
||||
static final
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||
internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\024douyin_cmd_msg.proto\0222tech.ordinaryroa" +
|
||||
"d.live.chat.client.douyin.protobuf\"\250\001\n\016d" +
|
||||
"ouyin_cmd_msg\022\016\n\006method\030\001 \001(\t\022\017\n\007payload" +
|
||||
"\030\002 \001(\014\022\016\n\006msg_id\030\003 \001(\003\022\020\n\010msg_type\030\004 \001(\005" +
|
||||
"\022\016\n\006offset\030\005 \001(\003\022\027\n\017need_wrds_store\030\006 \001(" +
|
||||
"\010\022\024\n\014wrds_version\030\007 \001(\003\022\024\n\014wrds_sub_key\030" +
|
||||
"\010 \001(\tBQ\n2tech.ordinaryroad.live.chat.cli" +
|
||||
"ent.douyin.protobufB\023Douyin_cmd_msgProto" +
|
||||
"P\001\242\002\003GPBb\006proto3"
|
||||
};
|
||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
});
|
||||
internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor,
|
||||
new java.lang.String[] { "Method", "Payload", "MsgId", "MsgType", "Offset", "NeedWrdsStore", "WrdsVersion", "WrdsSubKey", });
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user