办学质量监测教学评价系统
ageer
2024-02-27 a079ef44e53acd9e8df51dbb31cf5aea4f9be5bd
image/07.png

image/08.png

image/10.png

image/11.png

pom.xml
@@ -10,7 +10,7 @@
    <name>ruoyi-ai</name>
    <url>https://gitee.com/ageerle/ruoyi-ai</url>
    <description>AI助手后台管理系统</description>
    <description>AI助手</description>
    <properties>
        <revision>1.0.0</revision>
@@ -242,16 +242,16 @@
                <version>${tencent.sms.version}</version>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-starter-server</artifactId>
                <version>${spring-boot-admin.version}</version>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-starter-client</artifactId>
                <version>${spring-boot-admin.version}</version>
            </dependency>
<!--            <dependency>-->
<!--                <groupId>de.codecentric</groupId>-->
<!--                <artifactId>spring-boot-admin-starter-server</artifactId>-->
<!--                <version>${spring-boot-admin.version}</version>-->
<!--            </dependency>-->
<!--            <dependency>-->
<!--                <groupId>de.codecentric</groupId>-->
<!--                <artifactId>spring-boot-admin-starter-client</artifactId>-->
<!--                <version>${spring-boot-admin.version}</version>-->
<!--            </dependency>-->
            <!--redisson-->
            <dependency>
@@ -320,6 +320,12 @@
            <dependency>
                <groupId>com.xmzs</groupId>
                <artifactId>ruoyi-midjourney</artifactId>
                <version>${revision}</version>
            </dependency>
            <dependency>
                <groupId>com.xmzs</groupId>
                <artifactId>ruoyi-generator</artifactId>
                <version>${revision}</version>
            </dependency>
ruoyi-admin/pom.xml
@@ -59,6 +59,11 @@
            <artifactId>ruoyi-job</artifactId>
        </dependency>
        <dependency>
            <groupId>com.xmzs</groupId>
            <artifactId>ruoyi-midjourney</artifactId>
        </dependency>
        <!-- ä»£ç ç”Ÿæˆ-->
        <dependency>
            <groupId>com.xmzs</groupId>
@@ -71,10 +76,10 @@
            <artifactId>ruoyi-demo</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>de.codecentric</groupId>-->
<!--            <artifactId>spring-boot-admin-starter-client</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
ruoyi-admin/src/main/java/com/xmzs/controller/CaptchaController.java
@@ -94,7 +94,7 @@
        String code = RandomUtil.randomNumbers(4);
        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
        try {
            MailUtils.sendText(emailRequest.getUsername(), "【GPT助手】登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
            MailUtils.sendText(emailRequest.getUsername(), "【熊猫助手】登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
        } catch (Exception e) {
            log.error("验证码短信发送异常 => {}", e.getMessage());
            return R.fail(e.getMessage());
ruoyi-admin/src/main/java/com/xmzs/controller/ChatController.java
@@ -3,7 +3,10 @@
import com.xmzs.common.chat.domain.request.ChatRequest;
import com.xmzs.common.chat.domain.request.Dall3Request;
import com.xmzs.common.chat.domain.request.MjTaskRequest;
import com.xmzs.common.chat.entity.Tts.TextToSpeech;
import com.xmzs.common.chat.entity.images.Item;
import com.xmzs.common.chat.entity.whisper.WhisperResponse;
import com.xmzs.common.core.domain.R;
import com.xmzs.common.core.domain.model.LoginUser;
import com.xmzs.common.core.exception.base.BaseException;
@@ -13,18 +16,29 @@
import com.xmzs.system.domain.bo.ChatMessageBo;
import com.xmzs.system.domain.vo.ChatMessageVo;
import com.xmzs.system.service.IChatMessageService;
import com.xmzs.system.service.SseService;
import com.xmzs.system.service.ISseService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import retrofit2.Response;
/**
 * æè¿°ï¼š
@@ -37,38 +51,58 @@
@RequiredArgsConstructor
public class ChatController {
    private final SseService sseService;
    private final ISseService ISseService;
    private final  IChatMessageService chatMessageService;
    private final IChatMessageService chatMessageService;
    /**
     * èŠå¤©æŽ¥å£
     */
    @PostMapping("/chat")
    @ResponseBody
    public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest) {
        if("gpt-4-all".equals(chatRequest.getModel())
            || chatRequest.getModel().startsWith("gpt-4-gizmo")
            || chatRequest.getModel().startsWith("net-")
        ){
            return sseService.transitChat(chatRequest);
        }
        if("azure-gpt-3.5".equals(chatRequest.getModel())){
            return sseService.azureChat(chatRequest);
        }
        return sseService.sseChat(chatRequest);
    public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletResponse response) {
        return ISseService.sseChat(chatRequest);
    }
    /**
     * è¯­éŸ³è½¬æ–‡æœ¬
     *
     * @param file
     */
    @PostMapping("/audio")
    @ResponseBody
    public WhisperResponse audio(@RequestParam("file") MultipartFile file) {
        WhisperResponse whisperResponse = ISseService.speechToTextTranscriptionsV2(file);
        return whisperResponse;
    }
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³
     *
     * @param textToSpeech
     */
    @PostMapping("/speech")
    @ResponseBody
    public ResponseEntity<Resource> speech(@RequestBody TextToSpeech textToSpeech) {
        return ISseService.textToSpeed(textToSpeech);
    }
    @PostMapping("/dall3")
    @ResponseBody
    public R<List<Item>> dall3(@RequestBody @Valid Dall3Request request) {
       return R.ok(sseService.dall3(request));
        return R.ok(ISseService.dall3(request));
    }
    /**
     * æ‰£é™¤mj绘图费用
     *
     * @return
     */
    @PostMapping("/mjTask")
    @ResponseBody
    public R<String> mjTask() {
        sseService.mjTask();
    public R<String> mjTask(@RequestBody MjTaskRequest mjTaskRequest) {
        ISseService.mjTask(mjTaskRequest);
        return R.ok();
    }
@@ -77,7 +111,7 @@
     */
    @PostMapping("/chatList")
    @ResponseBody
    public R<TableDataInfo<ChatMessageVo>> list(@RequestBody @Valid ChatMessageBo chatRequest,@RequestBody PageQuery pageQuery) {
    public R<TableDataInfo<ChatMessageVo>> list(@RequestBody @Valid ChatMessageBo chatRequest, @RequestBody PageQuery pageQuery) {
        // é»˜è®¤æŸ¥è¯¢å½“前登录用户消息记录
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
ruoyi-admin/src/main/java/com/xmzs/controller/PayController.java
@@ -73,7 +73,6 @@
        return R.ok(paymentOrdersVo);
    }
    /**
     * è·³è½¬é€šçŸ¥åœ°å€
     *
@@ -138,6 +137,9 @@
        BeanUtil.copyProperties(paymentOrdersVo,paymentOrdersBo);
        paymentOrdersService.updateByBo(paymentOrdersBo);
        SysUserVo sysUserVo = userService.selectUserById(paymentOrdersVo.getUserId());
        if(money>9.9){
            money = money*2;
        }
        sysUserVo.setUserBalance(sysUserVo.getUserBalance()+money);
        SysUserBo sysUserBo = new SysUserBo();
        BeanUtil.copyProperties(sysUserVo,sysUserBo);
ruoyi-admin/src/main/java/com/xmzs/controller/WeChatController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.xmzs.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.xmzs.common.wechat.Wechat;
import com.xmzs.system.cofing.KeywordConfig;
import com.xmzs.system.cofing.QqConfig;
import com.xmzs.system.cofing.WechatConfig;
import com.xmzs.system.handler.WechatMessageHandler;
import com.xmzs.system.service.ISseService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * ä¸ªäººå¾®ä¿¡æ‰©å±•控制器
 *
 * @author WangLe
 */
@SaIgnore
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
public class WeChatController {
    @Getter
    private Wechat wechatBot;
    private final WechatConfig wechatConfig;
    private final ISseService sseService;
    private final  KeywordConfig keywordConfig;
    /**
     * èŽ·å–å¾®ä¿¡ç™»å½•äºŒç»´ç 
     *
     */
    @PostMapping("/getQr")
    public void getQr() {
        //微信
        if (wechatConfig.getEnable()){
            log.info("正在登录微信,请按提示操作:");
            wechatBot = new Wechat(new WechatMessageHandler(sseService, keywordConfig), wechatConfig.getQrPath());
            wechatBot.start();
        }
    }
}
ruoyi-admin/src/main/resources/application-dev.yml
@@ -51,7 +51,7 @@
          # rewriteBatchedStatements=true æ‰¹å¤„理优化 å¤§å¹…提升批量插入更新删除性能(对数据库有性能损耗 ä½¿ç”¨æ‰¹é‡æ“ä½œåº”考虑性能问题)
          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: ry-vue
          password: xxx
        # ä»Žåº“数据源
#        slave:
ruoyi-admin/src/main/resources/application.yml
@@ -220,11 +220,11 @@
  # æ˜¯å¦éœ€è¦ç”¨æˆ·åå¯†ç éªŒè¯
  auth: true
  # å‘送方,遵循RFC-822标准
  from: xxx@163.com
  from: ageerle@163.com
  # ç”¨æˆ·åï¼ˆæ³¨æ„ï¼šå¦‚果使用foxmail邮箱,此处user为qq号)
  user: xxx@163.com
  user: ageerle@163.com
  # å¯†ç ï¼ˆå¡«å†™æŽˆæƒç ï¼‰
  pass: pass
  pass: TOGXBVPYFVPFRQMQ
  # ä½¿ç”¨ STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
  starttlsEnable: true
  # ä½¿ç”¨SSL安全连接
@@ -318,14 +318,10 @@
  path: ''
  # è®¾ç½®è®¿é—®æºåœ°å€
  allowedOrigins: '*'
# AI助手配置信息
# chatgpt配置信息
chat:
  apiKey: ''
  apiHost: ''
# ä¸­è½¬æŽ¥å£
transit:
  apiKey: ''
  apiHost: 'https://api.gptgod.online/'
  apiKey: 'sk-uMCP3lTg1dQ9L7Xs2bF352Fa216a4c9280577b205dE67e12'
  apiHost: 'https://api.pandarobot.chat/'
# å¾®ä¿¡å°ç¨‹åºé…ç½®ä¿¡æ¯
wx:
  miniapp:
@@ -343,3 +339,37 @@
    apiKey: '' # apiKey
    secretKey: '' # secretKey
wechat:
  #  æ˜¯å¦ä½¿ç”¨å¾®ä¿¡ true/false
  enable: true
  #  ç”Ÿæˆçš„登录二维码路径 é»˜è®¤ä¸Žé¡¹ç›®åŒçº§
  qrPath: "./"
keyword:
  #  é‡ç½®ä¼šè¯æŒ‡ä»¤
  reset: "重置会话"
  #  ai画图指令(DALL·E模型 https://platform.openai.com/docs/models/dall-e)
  #  generation æ ¹æ®å…³é”®è¯ç”Ÿæˆå›¾ç‰‡(https://platform.openai.com/docs/guides/images/generations)
  image: "ai画图"
  #  ai语音指令(TTS模型 https://platform.openai.com/docs/api-reference/audio)
  audio: "ai语音"
mj:
  api-secret:
  task-store:
    type: in_memory
    timeout: 30d
  translate-way: gpt
#  proxy:
#    host: 127.0.0.1
#    port: 10809
  ng-discord:
    server: https://discord.pandarobot.chat/
    cdn: https://app.pandarobot.chat/
    wss: https://gateway.pandarobot.chat/
  openai:
    gpt-api-url: 'https://api.pandarobot.chat/'
    gpt-api-key: 'sk-xxx'
  accounts:
    - guild-id: 'xxxxx'
      channel-id: 'xxxxx'
      user-token: 'xx.xx'
ruoyi-common/pom.xml
@@ -34,6 +34,7 @@
        <module>ruoyi-common-tenant</module>
        <module>ruoyi-common-chat</module>
        <module>ruoyi-common-pay</module>
        <module>ruoyi-common-wechat</module>
    </modules>
    <artifactId>ruoyi-common</artifactId>
ruoyi-common/ruoyi-common-bom/pom.xml
@@ -166,6 +166,13 @@
                <version>${revision}</version>
            </dependency>
            <!-- å¾®ä¿¡æ¨¡å— -->
            <dependency>
                <groupId>com.xmzs</groupId>
                <artifactId>ruoyi-common-wechat</artifactId>
                <version>${revision}</version>
            </dependency>
            <!-- æ”¯ä»˜æ¨¡å— -->
            <dependency>
                <groupId>com.xmzs</groupId>
ruoyi-common/ruoyi-common-chat/pom.xml
@@ -70,13 +70,6 @@
            <version>0.5.0</version>
        </dependency>
        <!--   azure-ai    -->
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-ai-openai</artifactId>
            <version>1.0.0-beta.6</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/constant/OpenAIConst.java
@@ -12,15 +12,17 @@
    public final static int SUCCEED_CODE = 200;
    public final static double GPT3_COST = 0.03;
    public final static double GPT3_COST = 0.05;
    public final static double GPT4_COST = 0.3;
    public final static double GPT4_ALL_COST = 0.3;
    /** ç»˜å›¾è´¹ç”¨ */
    public final static double DALL3_COST = 0.3;
    public final static double DALL3_COST = 0.4;
    /** ç»˜å›¾è´¹ç”¨-高清 */
    public final static double DALL3_HD_COST = 0.6;
    public final static double DALL3_HD_COST = 0.8;
    /** mdjourney绘图费用 */
    public final static double MJ_COST = 0.3;
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/domain/request/MjTaskRequest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.xmzs.common.chat.domain.request;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
/**
 * mj任务请求实体类
 *
 * @author WangLe
 */
@Data
public class MjTaskRequest {
    private String prompt;
}
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/entity/Tts/TextToSpeech.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.xmzs.common.chat.entity.Tts;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
public class TextToSpeech {
    @Builder.Default
    private String model = Model.TTS_1.getName();
    /**
     * éŸ³é¢‘声音源
     *
     * @see TtsVoice
     */
    private String voice;
    /**
     * è¾“入内容
     */
    private String input;
    /**
     * è¾“出音频文件格式
     *
     * @see TtsFormat
     */
    @JsonProperty("response_format")
    private String responseFormat;
    /**
     * é€Ÿåº¦è°ƒèŠ‚ï¼Œé»˜è®¤æ˜¯1,取值范围0.25——4.0
     */
    private Double speed;
    @Getter
    @AllArgsConstructor
    public enum Model {
        TTS_1("tts-1"),
        TTS_1_HD("tts-1-hd"),
        ;
        private final String name;
    }
}
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/entity/Tts/TtsFormat.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.xmzs.common.chat.entity.Tts;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TtsFormat {
    MP3("mp3"),
    OPUS("opus"),
    AAC("aac"),
    FLAC("flac"),
    ;
    private final String name;
}
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/entity/Tts/TtsVoice.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.xmzs.common.chat.entity.Tts;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * ç”Ÿæˆä¸åŒå£°éŸ³çš„音频
 * <p>具体语音效果参考:https://platform.openai.com/docs/guides/text-to-speech</p>
 */
@Getter
@AllArgsConstructor
public enum TtsVoice {
    ALLOY("alloy"),
    ECHO("echo"),
    FABLE("fable"),
    ONYX("onyx"),
    NOVA("nova"),
    SHIMMER("shimmer"),
    ;
    private final String name;
}
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/entity/chat/BaseChatCompletion.java
@@ -175,6 +175,10 @@
         */
        GPT_3_5_TURBO_16K_0613("gpt-3.5-turbo-16k-0613"),
        /**
         * gpt-3.5-turbo-0125 è¶…长上下文 æ”¯æŒå‡½æ•°
         */
        GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125"),
        /**
         * GPT4.0
         */
        GPT_4("gpt-4"),
@@ -209,6 +213,10 @@
         * æ”¯æŒå›¾ç‰‡
         */
        GPT_4_VISION_PREVIEW("gpt-4-vision-preview"),
        /**
         * gpt-4-0613,支持函数
         */
        GPT_4_0125_PREVIEW("gpt-4-0125-preview"),
        ;
        private final String name;
    }
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/openai/OpenAiApi.java
@@ -1,5 +1,6 @@
package com.xmzs.common.chat.openai;
import com.xmzs.common.chat.entity.Tts.TextToSpeech;
import com.xmzs.common.chat.entity.chat.ChatCompletionWithPicture;
import io.reactivex.Single;
import okhttp3.MultipartBody;
@@ -33,6 +34,7 @@
import com.xmzs.common.chat.entity.moderations.Moderation;
import com.xmzs.common.chat.entity.moderations.ModerationResponse;
import com.xmzs.common.chat.entity.whisper.WhisperResponse;
import retrofit2.Call;
import retrofit2.http.*;
import java.time.LocalDate;
@@ -340,4 +342,15 @@
     */
    @POST("v1/chat/completions")
    Single<ChatCompletionResponse> chatCompletionWithPicture(@Body ChatCompletionWithPicture chatCompletion);
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³
     *
     * @param textToSpeech å‚æ•°
     * @return ResponseBody body
     * @since 1.1.2
     */
    @POST("v1/audio/speech")
    @Streaming
    Call<ResponseBody> textToSpeech(@Body TextToSpeech textToSpeech);
}
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/openai/OpenAiClient.java
@@ -668,7 +668,6 @@
        return this.chatCompletion(chatCompletion);
    }
    /**
     * è¯­éŸ³ç¿»è¯‘:目前仅支持翻译为英文
     *
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/openai/OpenAiStreamClient.java
@@ -5,6 +5,7 @@
import cn.hutool.http.ContentType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xmzs.common.chat.config.LocalCache;
import com.xmzs.common.chat.entity.Tts.TextToSpeech;
import com.xmzs.common.chat.entity.billing.BillingUsage;
import com.xmzs.common.chat.entity.billing.KeyInfo;
import com.xmzs.common.chat.entity.billing.Subscription;
@@ -37,10 +38,12 @@
import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
@@ -344,6 +347,67 @@
        Transcriptions transcriptions = Transcriptions.builder().build();
        return this.speechToTextTranscriptions(file, transcriptions);
    }
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³ï¼ˆå¼‚步)
     *
     * @param textToSpeech å‚æ•°
     * @param callback     è¿”回值接收
     * @since 1.1.2
     */
    public void textToSpeech(TextToSpeech textToSpeech, retrofit2.Callback callback) {
        retrofit2.Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
        responseBody.enqueue(callback);
    }
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³ï¼ˆåŒæ­¥ï¼‰
     *
     * @param textToSpeech å‚æ•°
     * @since 1.1.3
     */
    public ResponseBody textToSpeech(TextToSpeech textToSpeech){
        Call<ResponseBody> responseBody = this.openAiApi.textToSpeech(textToSpeech);
        try {
            return responseBody.execute().body();
        } catch (IOException e) {
            throw new BaseException("文本转语音(同步)失败: "+e.getMessage());
        }
    }
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³ï¼ˆå…‹éš†ï¼‰
     *
     * @param textToSpeech
     * @return
     */
    public ResponseBody textToSpeechClone(TextToSpeech textToSpeech) {
        String baseUrl = "http://localhost:8081";
        String spk = "三月七";
        String text = textToSpeech.getInput();
        String lang = "zh";
        // åˆ›å»ºOkHttpClient实例
        OkHttpClient client = new OkHttpClient();
        // æž„建请求URL
        HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
        urlBuilder.addQueryParameter("spk", spk);
        urlBuilder.addQueryParameter("text", text);
        urlBuilder.addQueryParameter("lang", lang);
        String url = urlBuilder.build().toString();
        // åˆ›å»ºè¯·æ±‚对象
        Request request = new Request.Builder()
            .url(url)
            .build();
        // å‘送请求并处理响应
        try {
            return client.newCall(request).execute().body();
        } catch (IOException e) {
            throw new BaseException("语音克隆失败!{}",e.getMessage());
        }
    }
    /**
     * æž„造
ruoyi-common/ruoyi-common-chat/src/main/java/com/xmzs/common/chat/utils/TikTokensUtil.java
@@ -6,6 +6,7 @@
import com.knuddels.jtokkit.api.EncodingRegistry;
import com.knuddels.jtokkit.api.EncodingType;
import com.knuddels.jtokkit.api.ModelType;
import com.xmzs.common.chat.entity.chat.BaseChatCompletion;
import lombok.extern.slf4j.Slf4j;
import com.xmzs.common.chat.entity.chat.ChatCompletion;
@@ -39,11 +40,13 @@
        modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
        modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
        modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
        modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0125.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
        modelMap.put(ChatCompletion.Model.GPT_4_32K.getName(), registry.getEncodingForModel(ModelType.GPT_4));
        modelMap.put(ChatCompletion.Model.GPT_4_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
        modelMap.put(ChatCompletion.Model.GPT_4_32K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
        modelMap.put(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
        modelMap.put(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
        modelMap.put(ChatCompletion.Model.GPT_4_0125_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
    }
    /**
ruoyi-common/ruoyi-common-pay/src/main/java/com/xmzs/common/config/PayConfig.java
@@ -10,27 +10,32 @@
    /**
     * å•†æˆ·ID
     */
    public static String pid = "xx";
    public static String pid = "xxx";
    /**
     * æŽ¥å£åœ°å€
     */
    public static String payUrl = "https://pay-cloud.vip/mapi.php";
    /**
     * ç§é’¥
     */
    public static String key = "xxx";
    /**
     * æœåŠ¡å™¨å¼‚æ­¥é€šçŸ¥åœ°å€
     */
    public static String notify_url = "https://www.pandarobot.chat/pay/returnUrl";
    /**
     * é¡µé¢è·³è½¬é€šçŸ¥åœ°å€
     */
    public static String return_url = "https://www.pandarobot.chat/pay/notifyUrl";
    /**
     * æ”¯ä»˜æ–¹å¼
     */
    public static String type = "wxpay";
    /**
     * æŽ¥å£åœ°å€
     */
    public static String payUrl = "https://pay.bluetuo.com/mapi.php";
    /**
     * æœåŠ¡å™¨å¼‚æ­¥é€šçŸ¥åœ°å€
     */
    public static String notify_url = "http://xx/pay/returnUrl";
    /**
     * é¡µé¢è·³è½¬é€šçŸ¥åœ°å€
     */
    public static String return_url = "http://xx/pay/notifyUrl";
    /**
     * è®¾å¤‡ç±»åž‹
@@ -40,12 +45,6 @@
    /**
     * åŠ å¯†æ–¹å¼é»˜è®¤MD5
     */
    public static String sign_type = "MD5";
    /**
     * ç§é’¥
     */
    public static String key = "xx";
}
ruoyi-common/ruoyi-common-pay/src/main/java/com/xmzs/common/service/PayService.java
@@ -19,5 +19,4 @@
     * @return String
     **/
    String getPayUrl(String orderNo, String name, double money, String clientIp);
}
ruoyi-common/ruoyi-common-pay/src/main/java/com/xmzs/common/service/impl/PayServiceImpl.java
@@ -40,5 +40,4 @@
        JSONObject jsonObject = new JSONObject(body);
        return (String) jsonObject.get("qrcode");
    }
}
ruoyi-common/ruoyi-common-security/src/main/java/com/xmzs/common/security/handler/AllUrlHandler.java
@@ -30,8 +30,10 @@
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
        map.keySet().forEach(info -> {
            // èŽ·å–æ³¨è§£ä¸Šè¾¹çš„ path æ›¿ä»£ path variable ä¸º *
            Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
            if(info.getPathPatternsCondition()!=null){
                Objects.requireNonNull(info.getPathPatternsCondition().getPatterns())
                    .forEach(url -> set.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, "*")));
            }
        });
        urls.addAll(set);
    }
ruoyi-common/ruoyi-common-wechat/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
<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">
    <parent>
        <groupId>com.xmzs</groupId>
        <artifactId>ruoyi-common</artifactId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-common-wechat</artifactId>
    <description>
        ruoyi-common-wechat å¾®ä¿¡æœåŠ¡
    </description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- emoji -->
        <dependency>
            <groupId>com.vdurmont</groupId>
            <artifactId>emoji-java</artifactId>
            <version>3.2.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!--        qq          -->
        <dependency>
            <groupId>net.mamoe</groupId>
            <artifactId>mirai-core-jvm</artifactId>
            <version>2.16.0</version>
        </dependency>
        <dependency>
            <groupId>com.xmzs</groupId>
            <artifactId>ruoyi-common-json</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/Wechat.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.xmzs.common.wechat;
import com.xmzs.common.wechat.controller.LoginController;
import com.xmzs.common.wechat.core.MsgCenter;
import com.xmzs.common.wechat.face.IMsgHandlerFace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Wechat {
   private static final Logger LOG = LoggerFactory.getLogger(Wechat.class);
   private IMsgHandlerFace msgHandler;
   public Wechat(IMsgHandlerFace msgHandler, String qrPath) {
      System.setProperty("jsse.enableSNIExtension", "false"); // é˜²æ­¢SSL错误
      this.msgHandler = msgHandler;
      // ç™»é™†
      LoginController login = new LoginController();
      login.login(qrPath);
   }
   public void start() {
      LOG.info("+++++++++++++++++++开始消息处理+++++++++++++++++++++");
      new Thread(new Runnable() {
         @Override
         public void run() {
            MsgCenter.handleMsg(msgHandler);
         }
      }).start();
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/api/AssistTools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.xmzs.common.wechat.api;
import java.io.File;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
 * è¾…助工具类,该类暂时未用,请忽略
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月22日 ä¸‹åˆ10:34:46
 * @version 1.0
 *
 */
public class AssistTools {
   private static OkHttpClient client = new OkHttpClient();
   private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
   public static boolean sendQrPicToServer(String username, String password, String uploadUrl, String localPath)
         throws IOException {
      File file = new File(localPath);
      RequestBody requestBody = new MultipartBody.Builder().addFormDataPart("username", username)
            .addFormDataPart("password", password)
            .addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file)).build();
      Request request = new Request.Builder().url(uploadUrl).post(requestBody).build();
      Call call = client.newCall(request);
      try {
         Response response = call.execute();
         System.out.println(response.body().string());
      } catch (IOException e) {
         e.printStackTrace();
      }
      return true;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/api/MessageTools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,424 @@
package com.xmzs.common.wechat.api;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.activation.MimetypesFileTypeMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xmzs.common.wechat.beans.BaseMsg;
import com.xmzs.common.wechat.beans.RecommendInfo;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.utils.Config;
import com.xmzs.common.wechat.utils.MyHttpClient;
import com.xmzs.common.wechat.utils.enums.StorageLoginInfoEnum;
import com.xmzs.common.wechat.utils.enums.URLEnum;
import com.xmzs.common.wechat.utils.enums.VerifyFriendEnum;
/**
 * æ¶ˆæ¯å¤„理类
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月23日 ä¸‹åˆ2:30:37
 * @version 1.0
 *
 */
public class MessageTools {
   private static Logger LOG = LoggerFactory.getLogger(MessageTools.class);
   private static Core core = Core.getInstance();
   private static MyHttpClient myHttpClient = core.getMyHttpClient();
   /**
    * æ ¹æ®UserName发送文本消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月4日 ä¸‹åˆ11:17:38
    * @param msg
    * @param toUserName
    */
   private static void sendMsg(String text, String toUserName) {
      if (text == null) {
         return;
      }
      LOG.info(String.format("发送消息 %s: %s", toUserName, text));
      webWxSendMsg(1, text, toUserName);
   }
   /**
    * æ ¹æ®ID发送文本消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月6日 ä¸Šåˆ11:45:51
    * @param text
    * @param id
    */
   public static void sendMsgById(String text, String id) {
      if (text == null) {
         return;
      }
      sendMsg(text, id);
   }
   /**
    * æ ¹æ®NickName发送文本消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月4日 ä¸‹åˆ11:17:38
    * @param text
    * @param nickName
    */
   public static boolean sendMsgByNickName(String text, String nickName) {
      if (nickName != null) {
         String toUserName = WechatTools.getUserNameByNickName(nickName);
         if (toUserName != null) {
            webWxSendMsg(1, text, toUserName);
            return true;
         }
      }
      return false;
   }
   /**
    * æ¶ˆæ¯å‘送
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月23日 ä¸‹åˆ2:32:02
    * @param msgType
    * @param content
    * @param toUserName
    */
   public static void webWxSendMsg(int msgType, String content, String toUserName) {
      String url = String.format(URLEnum.WEB_WX_SEND_MSG.getUrl(), core.getLoginInfo().get("url"));
      Map<String, Object> msgMap = new HashMap<String, Object>();
      msgMap.put("Type", msgType);
      msgMap.put("Content", content);
      msgMap.put("FromUserName", core.getUserName());
      msgMap.put("ToUserName", toUserName == null ? core.getUserName() : toUserName);
      msgMap.put("LocalID", new Date().getTime() * 10);
      msgMap.put("ClientMsgId", new Date().getTime() * 10);
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put("Msg", msgMap);
      paramMap.put("Scene", 0);
      try {
         String paramStr = JSON.toJSONString(paramMap);
         HttpEntity entity = myHttpClient.doPost(url, paramStr);
         EntityUtils.toString(entity, Consts.UTF_8);
      } catch (Exception e) {
         LOG.error("webWxSendMsg", e);
      }
   }
   /**
    * ä¸Šä¼ å¤šåª’体文件到 å¾®ä¿¡æœåŠ¡å™¨ï¼Œç›®å‰åº”è¯¥æ”¯æŒ3种类型: 1. pic ç›´æŽ¥æ˜¾ç¤ºï¼ŒåŒ…含图片,表情 2.video 3.doc æ˜¾ç¤ºä¸ºæ–‡ä»¶ï¼ŒåŒ…含PDF等
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸Šåˆ12:41:13
    * @param filePath
    * @return
    */
   private static JSONObject webWxUploadMedia(String filePath) {
      File file = new File(filePath);
      if (!file.exists() && file.isFile()) {
         LOG.info("file is not exist");
         return null;
      }
      String url = String.format(URLEnum.WEB_WX_UPLOAD_MEDIA.getUrl(), core.getLoginInfo().get("fileUrl"));
      String mimeType = new MimetypesFileTypeMap().getContentType(file);
      String mediaType = "";
      if (mimeType == null) {
         mimeType = "text/plain";
      } else {
         mediaType = mimeType.split("/")[0].equals("image") ? "pic" : "doc";
      }
      String lastModifieDate = new SimpleDateFormat("yyyy MM dd HH:mm:ss").format(new Date());
      long fileSize = file.length();
      String passTicket = (String) core.getLoginInfo().get("pass_ticket");
      String clientMediaId = new Date().getTime()
            + String.valueOf(new Random().nextLong()).substring(0, 4);
      String webwxDataTicket = MyHttpClient.getCookie("webwx_data_ticket");
      if (webwxDataTicket == null) {
         LOG.error("get cookie webwx_data_ticket error");
         return null;
      }
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put("ClientMediaId", clientMediaId);
      paramMap.put("TotalLen", fileSize);
      paramMap.put("StartPos", 0);
      paramMap.put("DataLen", fileSize);
      paramMap.put("MediaType", 4);
      MultipartEntityBuilder builder = MultipartEntityBuilder.create();
      builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
      builder.addTextBody("id", "WU_FILE_0", ContentType.TEXT_PLAIN);
      builder.addTextBody("name", filePath, ContentType.TEXT_PLAIN);
      builder.addTextBody("type", mimeType, ContentType.TEXT_PLAIN);
      builder.addTextBody("lastModifieDate", lastModifieDate, ContentType.TEXT_PLAIN);
      builder.addTextBody("size", String.valueOf(fileSize), ContentType.TEXT_PLAIN);
      builder.addTextBody("mediatype", mediaType, ContentType.TEXT_PLAIN);
      builder.addTextBody("uploadmediarequest", JSON.toJSONString(paramMap), ContentType.TEXT_PLAIN);
      builder.addTextBody("webwx_data_ticket", webwxDataTicket, ContentType.TEXT_PLAIN);
      builder.addTextBody("pass_ticket", passTicket, ContentType.TEXT_PLAIN);
      builder.addBinaryBody("filename", file, ContentType.create(mimeType), filePath);
      HttpEntity reqEntity = builder.build();
      HttpEntity entity = myHttpClient.doPostFile(url, reqEntity);
      if (entity != null) {
         try {
            String result = EntityUtils.toString(entity, Consts.UTF_8);
            return JSON.parseObject(result);
         } catch (Exception e) {
            LOG.error("webWxUploadMedia é”™è¯¯ï¼š ", e);
         }
      }
      return null;
   }
   /**
    * æ ¹æ®NickName发送图片消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ10:32:45
    * @param nackName
    * @return
    */
   public static boolean sendPicMsgByNickName(String nickName, String filePath) {
      String toUserName = WechatTools.getUserNameByNickName(nickName);
      if (toUserName != null) {
         return sendPicMsgByUserId(toUserName, filePath);
      }
      return false;
   }
   /**
    * æ ¹æ®ç”¨æˆ·id发送图片消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ10:34:24
    * @param userId
    * @param filePath
    * @return
    */
   public static boolean sendPicMsgByUserId(String userId, String filePath) {
      JSONObject responseObj = webWxUploadMedia(filePath);
      if (responseObj != null) {
         String mediaId = responseObj.getString("MediaId");
         if (mediaId != null) {
            return webWxSendMsgImg(userId, mediaId);
         }
      }
      return false;
   }
   /**
    * å‘送图片消息,内部调用
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ10:38:55
    * @return
    */
   private static boolean webWxSendMsgImg(String userId, String mediaId) {
      String url = String.format("%s/webwxsendmsgimg?fun=async&f=json&pass_ticket=%s", core.getLoginInfo().get("url"),
            core.getLoginInfo().get("pass_ticket"));
      Map<String, Object> msgMap = new HashMap<String, Object>();
      msgMap.put("Type", 3);
      msgMap.put("MediaId", mediaId);
      msgMap.put("FromUserName", core.getUserSelf().getString("UserName"));
      msgMap.put("ToUserName", userId);
      String clientMsgId = String.valueOf(new Date().getTime())
            + String.valueOf(new Random().nextLong()).substring(1, 5);
      msgMap.put("LocalID", clientMsgId);
      msgMap.put("ClientMsgId", clientMsgId);
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put("BaseRequest", core.getParamMap().get("BaseRequest"));
      paramMap.put("Msg", msgMap);
      String paramStr = JSON.toJSONString(paramMap);
      HttpEntity entity = myHttpClient.doPost(url, paramStr);
      if (entity != null) {
         try {
            String result = EntityUtils.toString(entity, Consts.UTF_8);
            return JSON.parseObject(result).getJSONObject("BaseResponse").getInteger("Ret") == 0;
         } catch (Exception e) {
            LOG.error("webWxSendMsgImg é”™è¯¯ï¼š ", e);
         }
      }
      return false;
   }
   /**
    * æ ¹æ®ç”¨æˆ·id发送文件
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ11:57:36
    * @param userId
    * @param filePath
    * @return
    */
   public static boolean sendFileMsgByUserId(String userId, String filePath) {
      String title = new File(filePath).getName();
      Map<String, String> data = new HashMap<String, String>();
      data.put("appid", Config.API_WXAPPID);
      data.put("title", title);
      data.put("totallen", "");
      data.put("attachid", "");
      data.put("type", "6"); // APPMSGTYPE_ATTACH
      data.put("fileext", title.split("\\.")[1]); // æ–‡ä»¶åŽç¼€
      JSONObject responseObj = webWxUploadMedia(filePath);
      if (responseObj != null) {
         data.put("totallen", responseObj.getString("StartPos"));
         data.put("attachid", responseObj.getString("MediaId"));
      } else {
         LOG.error("sednFileMsgByUserId é”™è¯¯: ", data);
      }
      return webWxSendAppMsg(userId, data);
   }
   /**
    * æ ¹æ®ç”¨æˆ·æ˜µç§°å‘送文件消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月10日 ä¸‹åˆ10:59:27
    * @param nickName
    * @param filePath
    * @return
    */
   public static boolean sendFileMsgByNickName(String nickName, String filePath) {
      String toUserName = WechatTools.getUserNameByNickName(nickName);
      if (toUserName != null) {
         return sendFileMsgByUserId(toUserName, filePath);
      }
      return false;
   }
   /**
    * å†…部调用
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月10日 ä¸Šåˆ12:21:28
    * @param userId
    * @param data
    * @return
    */
   private static boolean webWxSendAppMsg(String userId, Map<String, String> data) {
      String url = String.format("%s/webwxsendappmsg?fun=async&f=json&pass_ticket=%s", core.getLoginInfo().get("url"),
            core.getLoginInfo().get("pass_ticket"));
      String clientMsgId = String.valueOf(new Date().getTime())
            + String.valueOf(new Random().nextLong()).substring(1, 5);
      String content = "<appmsg appid='wxeb7ec651dd0aefa9' sdkver=''><title>" + data.get("title")
            + "</title><des></des><action></action><type>6</type><content></content><url></url><lowurl></lowurl>"
            + "<appattach><totallen>" + data.get("totallen") + "</totallen><attachid>" + data.get("attachid")
            + "</attachid><fileext>" + data.get("fileext") + "</fileext></appattach><extinfo></extinfo></appmsg>";
      Map<String, Object> msgMap = new HashMap<String, Object>();
      msgMap.put("Type", data.get("type"));
      msgMap.put("Content", content);
      msgMap.put("FromUserName", core.getUserSelf().getString("UserName"));
      msgMap.put("ToUserName", userId);
      msgMap.put("LocalID", clientMsgId);
      msgMap.put("ClientMsgId", clientMsgId);
      /*
       * Map<String, Object> paramMap = new HashMap<String, Object>();
       *
       * @SuppressWarnings("unchecked") Map<String, Map<String, String>>
       * baseRequestMap = (Map<String, Map<String, String>>)
       * core.getLoginInfo() .get("baseRequest"); paramMap.put("BaseRequest",
       * baseRequestMap.get("BaseRequest"));
       */
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put("Msg", msgMap);
      paramMap.put("Scene", 0);
      String paramStr = JSON.toJSONString(paramMap);
      HttpEntity entity = myHttpClient.doPost(url, paramStr);
      if (entity != null) {
         try {
            String result = EntityUtils.toString(entity, Consts.UTF_8);
            return JSON.parseObject(result).getJSONObject("BaseResponse").getInteger("Ret") == 0;
         } catch (Exception e) {
            LOG.error("错误: ", e);
         }
      }
      return false;
   }
   /**
    * è¢«åŠ¨æ·»åŠ å¥½å‹
    *
    * @date 2017å¹´6月29日 ä¸‹åˆ10:08:43
    * @param msg
    * @param accept
    *            true æŽ¥å— false æ‹’绝
    */
   public static void addFriend(BaseMsg msg, boolean accept) {
      if (!accept) { // ä¸æ·»åŠ 
         return;
      }
      int status = VerifyFriendEnum.ACCEPT.getCode(); // æŽ¥å—好友请求
      RecommendInfo recommendInfo = msg.getRecommendInfo();
      String userName = recommendInfo.getUserName();
      String ticket = recommendInfo.getTicket();
      // æ›´æ–°å¥½å‹åˆ—表
      // TODO æ­¤å¤„需要更新好友列表
      // core.getContactList().add(msg.getJSONObject("RecommendInfo"));
      String url = String.format(URLEnum.WEB_WX_VERIFYUSER.getUrl(), core.getLoginInfo().get("url"),
            String.valueOf(System.currentTimeMillis() / 3158L), core.getLoginInfo().get("pass_ticket"));
      List<Map<String, Object>> verifyUserList = new ArrayList<Map<String, Object>>();
      Map<String, Object> verifyUser = new HashMap<String, Object>();
      verifyUser.put("Value", userName);
      verifyUser.put("VerifyUserTicket", ticket);
      verifyUserList.add(verifyUser);
      List<Integer> sceneList = new ArrayList<Integer>();
      sceneList.add(33);
      JSONObject body = new JSONObject();
      body.put("BaseRequest", core.getParamMap().get("BaseRequest"));
      body.put("Opcode", status);
      body.put("VerifyUserListSize", 1);
      body.put("VerifyUserList", verifyUserList);
      body.put("VerifyContent", "");
      body.put("SceneListCount", 1);
      body.put("SceneList", sceneList);
      body.put("skey", core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey()));
      String result = null;
      try {
         String paramStr = JSON.toJSONString(body);
         HttpEntity entity = myHttpClient.doPost(url, paramStr);
         result = EntityUtils.toString(entity, Consts.UTF_8);
      } catch (Exception e) {
         LOG.error("webWxSendMsg", e);
      }
      if (StringUtils.isBlank(result)) {
         LOG.error("被动添加好友失败");
      }
      LOG.debug(result);
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/api/WechatTools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,215 @@
package com.xmzs.common.wechat.api;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.utils.enums.StorageLoginInfoEnum;
import com.xmzs.common.wechat.utils.enums.URLEnum;
/**
 * å¾®ä¿¡å°å·¥å…·ï¼Œå¦‚获好友列表等
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月4日 ä¸‹åˆ10:49:16
 * @version 1.0
 *
 */
public class WechatTools {
   private static Logger LOG = LoggerFactory.getLogger(WechatTools.class);
   private static Core core = Core.getInstance();
   /**
    * æ ¹æ®ç”¨æˆ·åå‘送文本消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月4日 ä¸‹åˆ10:43:14
    * @param msg
    * @param toUserName
    */
   public static void sendMsgByUserName(String msg, String toUserName) {
      MessageTools.sendMsgById(msg, toUserName);
   }
   /**
    * <p>
    * é€šè¿‡RealName获取本次UserName
    * </p>
    * <p>
    * å¦‚NickName为"yaphone",则获取UserName=
    * "@1212d3356aea8285e5bbe7b91229936bc183780a8ffa469f2d638bf0d2e4fc63",
    * å¯é€šè¿‡UserName发送消息
    * </p>
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月4日 ä¸‹åˆ10:56:31
    * @param name
    * @return
    */
   public static String getUserNameByNickName(String nickName) {
      for (JSONObject o : core.getContactList()) {
         if (o.getString("NickName").equals(nickName)) {
            return o.getString("UserName");
         }
      }
      return null;
   }
   /**
    * è¿”回好友昵称列表
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月4日 ä¸‹åˆ11:37:20
    * @return
    */
   public static List<String> getContactNickNameList() {
      List<String> contactNickNameList = new ArrayList<String>();
      for (JSONObject o : core.getContactList()) {
         contactNickNameList.add(o.getString("NickName"));
      }
      return contactNickNameList;
   }
   /**
    * è¿”回好友完整信息列表
    *
    * @date 2017å¹´6月26日 ä¸‹åˆ9:45:39
    * @return
    */
   public static List<JSONObject> getContactList() {
      return core.getContactList();
   }
   /**
    * è¿”回群列表
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月5日 ä¸‹åˆ9:55:21
    * @return
    */
   public static List<JSONObject> getGroupList() {
      return core.getGroupList();
   }
   /**
    * èŽ·å–ç¾¤ID列表
    *
    * @date 2017å¹´6月21日 ä¸‹åˆ11:42:56
    * @return
    */
   public static List<String> getGroupIdList() {
      return core.getGroupIdList();
   }
   /**
    * èŽ·å–ç¾¤NickName列表
    *
    * @date 2017å¹´6月21日 ä¸‹åˆ11:43:38
    * @return
    */
   public static List<String> getGroupNickNameList() {
      return core.getGroupNickNameList();
   }
   /**
    * æ ¹æ®groupIdList返回群成员列表
    *
    * @date 2017å¹´6月13日 ä¸‹åˆ11:12:31
    * @param groupId
    * @return
    */
   public static JSONArray getMemberListByGroupId(String groupId) {
      return core.getGroupMemeberMap().get(groupId);
   }
   /**
    * é€€å‡ºå¾®ä¿¡
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月18日 ä¸‹åˆ11:56:54
    */
   public static void logout() {
      webWxLogout();
   }
   private static boolean webWxLogout() {
      String url = String.format(URLEnum.WEB_WX_LOGOUT.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()));
      List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
      params.add(new BasicNameValuePair("redirect", "1"));
      params.add(new BasicNameValuePair("type", "1"));
      params.add(
            new BasicNameValuePair("skey", (String) core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey())));
      try {
         HttpEntity entity = core.getMyHttpClient().doGet(url, params, false, null);
         String text = EntityUtils.toString(entity, Consts.UTF_8); // æ— æ¶ˆæ¯
         return true;
      } catch (Exception e) {
         LOG.debug(e.getMessage());
      }
      return false;
   }
   public static void setUserInfo() {
      for (JSONObject o : core.getContactList()) {
         core.getUserInfoMap().put(o.getString("NickName"), o);
         core.getUserInfoMap().put(o.getString("UserName"), o);
      }
   }
   /**
    *
    * æ ¹æ®ç”¨æˆ·æ˜µç§°è®¾ç½®å¤‡æ³¨åç§°
    *
    * @date 2017å¹´5月27日 ä¸Šåˆ12:21:40
    * @param userName
    * @param remName
    */
   public static void remarkNameByNickName(String nickName, String remName) {
      String url = String.format(URLEnum.WEB_WX_REMARKNAME.getUrl(), core.getLoginInfo().get("url"),
            core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
      Map<String, Object> msgMap = new HashMap<String, Object>();
      Map<String, Object> msgMap_BaseRequest = new HashMap<String, Object>();
      msgMap.put("CmdId", 2);
      msgMap.put("RemarkName", remName);
      msgMap.put("UserName", core.getUserInfoMap().get(nickName).get("UserName"));
      msgMap_BaseRequest.put("Uin", core.getLoginInfo().get(StorageLoginInfoEnum.wxuin.getKey()));
      msgMap_BaseRequest.put("Sid", core.getLoginInfo().get(StorageLoginInfoEnum.wxsid.getKey()));
      msgMap_BaseRequest.put("Skey", core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey()));
      msgMap_BaseRequest.put("DeviceID", core.getLoginInfo().get(StorageLoginInfoEnum.deviceid.getKey()));
      msgMap.put("BaseRequest", msgMap_BaseRequest);
      try {
         String paramStr = JSON.toJSONString(msgMap);
         HttpEntity entity = core.getMyHttpClient().doPost(url, paramStr);
         // String result = EntityUtils.toString(entity, Consts.UTF_8);
         LOG.info("修改备注" + remName);
      } catch (Exception e) {
         LOG.error("remarkNameByUserName", e);
      }
   }
   /**
    * èŽ·å–å¾®ä¿¡åœ¨çº¿çŠ¶æ€
    *
    * @date 2017å¹´6月16日 ä¸Šåˆ12:47:46
    * @return
    */
   public static boolean getWechatStatus() {
      return core.isAlive();
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/beans/AppInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.xmzs.common.wechat.beans;
import java.io.Serializable;
/**
 * AppInfo
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´7月3日 ä¸‹åˆ10:38:14
 * @version 1.0
 *
 */
public class AppInfo implements Serializable {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private int type;
   private String appId;
   public int getType() {
      return type;
   }
   public void setType(int type) {
      this.type = type;
   }
   public String getAppId() {
      return appId;
   }
   public void setAppId(String appId) {
      this.appId = appId;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/beans/BaseMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
package com.xmzs.common.wechat.beans;
import java.io.Serializable;
/**
 * æ”¶åˆ°çš„微信消息
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´7月3日 ä¸‹åˆ10:28:06
 * @version 1.0
 *
 */
public class BaseMsg implements Serializable {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private int subMsgType;
   private int voiceLength;
   private String fileName;
   private int imgHeight;
   private String toUserName;
   private int hasProductId;
   private int imgStatus;
   private String url;
   private int imgWidth;
   private int forwardFlag;
   private int status;
   private String Ticket;
   /** æŽ¨èæ¶ˆæ¯æŠ¥æ–‡ **/
   private RecommendInfo recommendInfo;
   private long createTime;
   private String newMsgId;
   /** æ–‡æœ¬æ¶ˆæ¯å†…容 **/
   private String text;
   /** æ¶ˆæ¯ç±»åž‹ **/
   private int msgType;
   /** æ˜¯å¦ä¸ºç¾¤æ¶ˆæ¯ **/
   private boolean groupMsg;
   private String msgId;
   private int statusNotifyCode;
   private AppInfo appInfo;
   private int appMsgType;
   private String Type;
   private int playLength;
   private String mediaId;
   private String content;
   private String statusNotifyUserName;
   /** æ¶ˆæ¯å‘送者ID **/
   private String fromUserName;
   private String oriContent;
   private String fileSize;
   public int getSubMsgType() {
      return subMsgType;
   }
   public void setSubMsgType(int subMsgType) {
      this.subMsgType = subMsgType;
   }
   public int getVoiceLength() {
      return voiceLength;
   }
   public void setVoiceLength(int voiceLength) {
      this.voiceLength = voiceLength;
   }
   public String getFileName() {
      return fileName;
   }
   public void setFileName(String fileName) {
      this.fileName = fileName;
   }
   public int getImgHeight() {
      return imgHeight;
   }
   public void setImgHeight(int imgHeight) {
      this.imgHeight = imgHeight;
   }
   public String getToUserName() {
      return toUserName;
   }
   public void setToUserName(String toUserName) {
      this.toUserName = toUserName;
   }
   public int getHasProductId() {
      return hasProductId;
   }
   public void setHasProductId(int hasProductId) {
      this.hasProductId = hasProductId;
   }
   public int getImgStatus() {
      return imgStatus;
   }
   public void setImgStatus(int imgStatus) {
      this.imgStatus = imgStatus;
   }
   public String getUrl() {
      return url;
   }
   public void setUrl(String url) {
      this.url = url;
   }
   public int getImgWidth() {
      return imgWidth;
   }
   public void setImgWidth(int imgWidth) {
      this.imgWidth = imgWidth;
   }
   public int getForwardFlag() {
      return forwardFlag;
   }
   public void setForwardFlag(int forwardFlag) {
      this.forwardFlag = forwardFlag;
   }
   public int getStatus() {
      return status;
   }
   public void setStatus(int status) {
      this.status = status;
   }
   public String getTicket() {
      return Ticket;
   }
   public void setTicket(String ticket) {
      Ticket = ticket;
   }
   public RecommendInfo getRecommendInfo() {
      return recommendInfo;
   }
   public void setRecommendInfo(RecommendInfo recommendInfo) {
      this.recommendInfo = recommendInfo;
   }
   public long getCreateTime() {
      return createTime;
   }
   public void setCreateTime(long createTime) {
      this.createTime = createTime;
   }
   public String getNewMsgId() {
      return newMsgId;
   }
   public void setNewMsgId(String newMsgId) {
      this.newMsgId = newMsgId;
   }
   public String getText() {
      return text;
   }
   public void setText(String text) {
      this.text = text;
   }
   public int getMsgType() {
      return msgType;
   }
   public void setMsgType(int msgType) {
      this.msgType = msgType;
   }
   public boolean isGroupMsg() {
      return groupMsg;
   }
   public void setGroupMsg(boolean groupMsg) {
      this.groupMsg = groupMsg;
   }
   public String getMsgId() {
      return msgId;
   }
   public void setMsgId(String msgId) {
      this.msgId = msgId;
   }
   public int getStatusNotifyCode() {
      return statusNotifyCode;
   }
   public void setStatusNotifyCode(int statusNotifyCode) {
      this.statusNotifyCode = statusNotifyCode;
   }
   public AppInfo getAppInfo() {
      return appInfo;
   }
   public void setAppInfo(AppInfo appInfo) {
      this.appInfo = appInfo;
   }
   public int getAppMsgType() {
      return appMsgType;
   }
   public void setAppMsgType(int appMsgType) {
      this.appMsgType = appMsgType;
   }
   public String getType() {
      return Type;
   }
   public void setType(String type) {
      Type = type;
   }
   public int getPlayLength() {
      return playLength;
   }
   public void setPlayLength(int playLength) {
      this.playLength = playLength;
   }
   public String getMediaId() {
      return mediaId;
   }
   public void setMediaId(String mediaId) {
      this.mediaId = mediaId;
   }
   public String getContent() {
      return content;
   }
   public void setContent(String content) {
      this.content = content;
   }
   public String getStatusNotifyUserName() {
      return statusNotifyUserName;
   }
   public void setStatusNotifyUserName(String statusNotifyUserName) {
      this.statusNotifyUserName = statusNotifyUserName;
   }
   public String getFromUserName() {
      return fromUserName;
   }
   public void setFromUserName(String fromUserName) {
      this.fromUserName = fromUserName;
   }
   public String getOriContent() {
      return oriContent;
   }
   public void setOriContent(String oriContent) {
      this.oriContent = oriContent;
   }
   public String getFileSize() {
      return fileSize;
   }
   public void setFileSize(String fileSize) {
      this.fileSize = fileSize;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/beans/RecommendInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,146 @@
package com.xmzs.common.wechat.beans;
import java.io.Serializable;
/**
 * RecommendInfo
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´7月3日 ä¸‹åˆ10:35:14
 * @version 1.0
 *
 */
public class RecommendInfo implements Serializable {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private String ticket;
   private String userName;
   private int sex;
   private int attrStatus;
   private String city;
   private String nickName;
   private int scene;
   private String province;
   private String content;
   private String alias;
   private String signature;
   private int opCode;
   private int qQNum;
   private int verifyFlag;
   public String getTicket() {
      return ticket;
   }
   public void setTicket(String ticket) {
      this.ticket = ticket;
   }
   public String getUserName() {
      return userName;
   }
   public void setUserName(String userName) {
      this.userName = userName;
   }
   public int getSex() {
      return sex;
   }
   public void setSex(int sex) {
      this.sex = sex;
   }
   public int getAttrStatus() {
      return attrStatus;
   }
   public void setAttrStatus(int attrStatus) {
      this.attrStatus = attrStatus;
   }
   public String getCity() {
      return city;
   }
   public void setCity(String city) {
      this.city = city;
   }
   public String getNickName() {
      return nickName;
   }
   public void setNickName(String nickName) {
      this.nickName = nickName;
   }
   public int getScene() {
      return scene;
   }
   public void setScene(int scene) {
      this.scene = scene;
   }
   public String getProvince() {
      return province;
   }
   public void setProvince(String province) {
      this.province = province;
   }
   public String getContent() {
      return content;
   }
   public void setContent(String content) {
      this.content = content;
   }
   public String getAlias() {
      return alias;
   }
   public void setAlias(String alias) {
      this.alias = alias;
   }
   public String getSignature() {
      return signature;
   }
   public void setSignature(String signature) {
      this.signature = signature;
   }
   public int getOpCode() {
      return opCode;
   }
   public void setOpCode(int opCode) {
      this.opCode = opCode;
   }
   public int getqQNum() {
      return qQNum;
   }
   public void setqQNum(int qQNum) {
      this.qQNum = qQNum;
   }
   public int getVerifyFlag() {
      return verifyFlag;
   }
   public void setVerifyFlag(int verifyFlag) {
      this.verifyFlag = verifyFlag;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/controller/LoginController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package com.xmzs.common.wechat.controller;
import com.xmzs.common.wechat.utils.SleepUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xmzs.common.wechat.api.WechatTools;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.service.ILoginService;
import com.xmzs.common.wechat.service.impl.LoginServiceImpl;
import com.xmzs.common.wechat.thread.CheckLoginStatusThread;
import com.xmzs.common.wechat.utils.tools.CommonTools;
/**
 * ç™»é™†æŽ§åˆ¶å™¨
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月13日 ä¸‹åˆ12:56:07
 * @version 1.0
 *
 */
public class LoginController {
   private static Logger LOG = LoggerFactory.getLogger(LoginController.class);
   private ILoginService loginService = new LoginServiceImpl();
   private static Core core = Core.getInstance();
   public void login(String qrPath) {
      if (core.isAlive()) { // å·²ç™»é™†
         LOG.info("itchat4j已登陆");
         return;
      }
      while (true) {
         for (int count = 0; count < 10; count++) {
            LOG.info("获取UUID");
            while (loginService.getUuid() == null) {
               LOG.info("1. èŽ·å–å¾®ä¿¡UUID");
               while (loginService.getUuid() == null) {
                  LOG.warn("1.1. èŽ·å–å¾®ä¿¡UUID失败,两秒后重新获取");
                  SleepUtils.sleep(2000);
               }
            }
            LOG.info("2. èŽ·å–ç™»é™†äºŒç»´ç å›¾ç‰‡");
            if (loginService.getQR(qrPath)) {
               break;
            } else if (count == 10) {
               LOG.error("2.2. èŽ·å–ç™»é™†äºŒç»´ç å›¾ç‰‡å¤±è´¥ï¼Œç³»ç»Ÿé€€å‡º");
               System.exit(0);
            }
         }
         LOG.info("3. è¯·æ‰«æäºŒç»´ç å›¾ç‰‡ï¼Œå¹¶åœ¨æ‰‹æœºä¸Šç¡®è®¤");
         if (!core.isAlive()) {
            loginService.login();
            core.setAlive(true);
            LOG.info(("登陆成功"));
            break;
         }
         LOG.info("4. ç™»é™†è¶…时,请重新扫描二维码图片");
      }
      LOG.info("5. ç™»é™†æˆåŠŸï¼Œå¾®ä¿¡åˆå§‹åŒ–");
      if (!loginService.webWxInit()) {
         LOG.info("6. å¾®ä¿¡åˆå§‹åŒ–异常");
         System.exit(0);
      }
      LOG.info("6. å¼€å¯å¾®ä¿¡çŠ¶æ€é€šçŸ¥");
      loginService.wxStatusNotify();
      LOG.info("7. æ¸…除。。。。");
      CommonTools.clearScreen();
      LOG.info(String.format("欢迎回来, %s", core.getNickName()));
      LOG.info("8. å¼€å§‹æŽ¥æ”¶æ¶ˆæ¯");
      loginService.startReceiving();
      LOG.info("9. èŽ·å–è”ç³»äººä¿¡æ¯");
      loginService.webWxGetContact();
      LOG.info("10. èŽ·å–ç¾¤å¥½å‹åŠç¾¤å¥½å‹åˆ—è¡¨");
      loginService.WebWxBatchGetContact();
      LOG.info("11. ç¼“存本次登陆好友相关消息");
      WechatTools.setUserInfo(); // ç™»é™†æˆåŠŸåŽç¼“å­˜æœ¬æ¬¡ç™»é™†å¥½å‹ç›¸å…³æ¶ˆæ¯ï¼ˆNickName, UserName)
      LOG.info("12.开启微信状态检测线程");
      new Thread(new CheckLoginStatusThread()).start();
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/core/Core.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,276 @@
package com.xmzs.common.wechat.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xmzs.common.wechat.beans.BaseMsg;
import com.xmzs.common.wechat.utils.MyHttpClient;
import com.xmzs.common.wechat.utils.enums.parameters.BaseParaEnum;
/**
 * æ ¸å¿ƒå­˜å‚¨ç±»ï¼Œå…¨å±€åªä¿å­˜ä¸€ä»½ï¼Œå•例模式
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月23日 ä¸‹åˆ2:33:56
 * @version 1.0
 *
 */
public class Core {
   private static Core instance;
   private Core() {
   }
   public static Core getInstance() {
      if (instance == null) {
         synchronized (Core.class) {
            instance = new Core();
         }
      }
      return instance;
   }
   boolean alive = false;
   private int memberCount = 0;
   private String indexUrl;
   private String userName;
   private String nickName;
   private List<BaseMsg> msgList = new ArrayList<BaseMsg>();
   private JSONObject userSelf; // ç™»é™†è´¦å·è‡ªèº«ä¿¡æ¯
   private List<JSONObject> memberList = new ArrayList<JSONObject>(); // å¥½å‹+群聊+公众号+特殊账号
   private List<JSONObject> contactList = new ArrayList<JSONObject>();// å¥½å‹
   private List<JSONObject> groupList = new ArrayList<JSONObject>();; // ç¾¤
   private Map<String, JSONArray> groupMemeberMap = new HashMap<String, JSONArray>(); // ç¾¤èŠæˆå‘˜å­—å…¸
   private List<JSONObject> publicUsersList = new ArrayList<JSONObject>();;// å…¬ä¼—号/服务号
   private List<JSONObject> specialUsersList = new ArrayList<JSONObject>();;// ç‰¹æ®Šè´¦å·
   private List<String> groupIdList = new ArrayList<String>(); // ç¾¤ID列表
   private List<String> groupNickNameList = new ArrayList<String>(); // ç¾¤NickName列表
   private Map<String, JSONObject> userInfoMap = new HashMap<String, JSONObject>();
   Map<String, Object> loginInfo = new HashMap<String, Object>();
   // CloseableHttpClient httpClient = HttpClients.createDefault();
   MyHttpClient myHttpClient = MyHttpClient.getInstance();
   String uuid = null;
   boolean useHotReload = false;
   String hotReloadDir = "itchat.pkl";
   int receivingRetryCount = 5;
   private long lastNormalRetcodeTime; // æœ€åŽä¸€æ¬¡æ”¶åˆ°æ­£å¸¸retcode的时间,秒为单位
   /**
    * è¯·æ±‚参数
    */
   public Map<String, Object> getParamMap() {
      return new HashMap<String, Object>(1) {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            Map<String, String> map = new HashMap<String, String>();
            for (BaseParaEnum baseRequest : BaseParaEnum.values()) {
               map.put(baseRequest.para(), getLoginInfo().get(baseRequest.value()).toString());
            }
            put("BaseRequest", map);
         }
      };
   }
   public boolean isAlive() {
      return alive;
   }
   public void setAlive(boolean alive) {
      this.alive = alive;
   }
   public List<JSONObject> getMemberList() {
      return memberList;
   }
   public void setMemberList(List<JSONObject> memberList) {
      this.memberList = memberList;
   }
   public Map<String, Object> getLoginInfo() {
      return loginInfo;
   }
   public void setLoginInfo(Map<String, Object> loginInfo) {
      this.loginInfo = loginInfo;
   }
   public String getUuid() {
      return uuid;
   }
   public void setUuid(String uuid) {
      this.uuid = uuid;
   }
   public int getMemberCount() {
      return memberCount;
   }
   public void setMemberCount(int memberCount) {
      this.memberCount = memberCount;
   }
   public boolean isUseHotReload() {
      return useHotReload;
   }
   public void setUseHotReload(boolean useHotReload) {
      this.useHotReload = useHotReload;
   }
   public String getHotReloadDir() {
      return hotReloadDir;
   }
   public void setHotReloadDir(String hotReloadDir) {
      this.hotReloadDir = hotReloadDir;
   }
   public int getReceivingRetryCount() {
      return receivingRetryCount;
   }
   public void setReceivingRetryCount(int receivingRetryCount) {
      this.receivingRetryCount = receivingRetryCount;
   }
   public MyHttpClient getMyHttpClient() {
      return myHttpClient;
   }
   public List<BaseMsg> getMsgList() {
      return msgList;
   }
   public void setMsgList(List<BaseMsg> msgList) {
      this.msgList = msgList;
   }
   public void setMyHttpClient(MyHttpClient myHttpClient) {
      this.myHttpClient = myHttpClient;
   }
   public List<String> getGroupIdList() {
      return groupIdList;
   }
   public void setGroupIdList(List<String> groupIdList) {
      this.groupIdList = groupIdList;
   }
   public List<JSONObject> getContactList() {
      return contactList;
   }
   public void setContactList(List<JSONObject> contactList) {
      this.contactList = contactList;
   }
   public List<JSONObject> getGroupList() {
      return groupList;
   }
   public void setGroupList(List<JSONObject> groupList) {
      this.groupList = groupList;
   }
   public List<JSONObject> getPublicUsersList() {
      return publicUsersList;
   }
   public void setPublicUsersList(List<JSONObject> publicUsersList) {
      this.publicUsersList = publicUsersList;
   }
   public List<JSONObject> getSpecialUsersList() {
      return specialUsersList;
   }
   public void setSpecialUsersList(List<JSONObject> specialUsersList) {
      this.specialUsersList = specialUsersList;
   }
   public String getUserName() {
      return userName;
   }
   public void setUserName(String userName) {
      this.userName = userName;
   }
   public String getNickName() {
      return nickName;
   }
   public void setNickName(String nickName) {
      this.nickName = nickName;
   }
   public JSONObject getUserSelf() {
      return userSelf;
   }
   public void setUserSelf(JSONObject userSelf) {
      this.userSelf = userSelf;
   }
   public Map<String, JSONObject> getUserInfoMap() {
      return userInfoMap;
   }
   public void setUserInfoMap(Map<String, JSONObject> userInfoMap) {
      this.userInfoMap = userInfoMap;
   }
   public synchronized long getLastNormalRetcodeTime() {
      return lastNormalRetcodeTime;
   }
   public synchronized void setLastNormalRetcodeTime(long lastNormalRetcodeTime) {
      this.lastNormalRetcodeTime = lastNormalRetcodeTime;
   }
   public List<String> getGroupNickNameList() {
      return groupNickNameList;
   }
   public void setGroupNickNameList(List<String> groupNickNameList) {
      this.groupNickNameList = groupNickNameList;
   }
   public Map<String, JSONArray> getGroupMemeberMap() {
      return groupMemeberMap;
   }
   public void setGroupMemeberMap(Map<String, JSONArray> groupMemeberMap) {
      this.groupMemeberMap = groupMemeberMap;
   }
   public String getIndexUrl() {
      return indexUrl;
   }
   public void setIndexUrl(String indexUrl) {
      this.indexUrl = indexUrl;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/core/MsgCenter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
package com.xmzs.common.wechat.core;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import com.xmzs.common.wechat.utils.enums.MsgCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xmzs.common.wechat.api.MessageTools;
import com.xmzs.common.wechat.beans.BaseMsg;
import com.xmzs.common.wechat.face.IMsgHandlerFace;
import com.xmzs.common.wechat.utils.enums.MsgTypeEnum;
import com.xmzs.common.wechat.utils.tools.CommonTools;
/**
 * æ¶ˆæ¯å¤„理中心
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月14日 ä¸‹åˆ12:47:50
 * @version 1.0
 *
 */
public class MsgCenter {
   private static Logger LOG = LoggerFactory.getLogger(MsgCenter.class);
   private static Core core = Core.getInstance();
   /**
    * æŽ¥æ”¶æ¶ˆæ¯ï¼Œæ”¾å…¥é˜Ÿåˆ—
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月23日 ä¸‹åˆ2:30:48
    * @param msgList
    * @return
    */
   public static JSONArray produceMsg(JSONArray msgList) {
      JSONArray result = new JSONArray();
      for (int i = 0; i < msgList.size(); i++) {
         JSONObject msg = new JSONObject();
         JSONObject m = msgList.getJSONObject(i);
         m.put("groupMsg", false);// æ˜¯å¦æ˜¯ç¾¤æ¶ˆæ¯
         if (m.getString("FromUserName").contains("@@") || m.getString("ToUserName").contains("@@")) { // ç¾¤èŠæ¶ˆæ¯
            if (m.getString("FromUserName").contains("@@")
                  && !core.getGroupIdList().contains(m.getString("FromUserName"))) {
               core.getGroupIdList().add((m.getString("FromUserName")));
            } else if (m.getString("ToUserName").contains("@@")
                  && !core.getGroupIdList().contains(m.getString("ToUserName"))) {
               core.getGroupIdList().add((m.getString("ToUserName")));
            }
            // ç¾¤æ¶ˆæ¯ä¸Žæ™®é€šæ¶ˆæ¯ä¸åŒçš„æ˜¯åœ¨å…¶æ¶ˆæ¯ä½“(Content)中会包含发送者id及":<br/>"消息,这里需要处理一下,去掉多余信息,只保留消息内容
            if (m.getString("Content").contains("<br/>")) {
               String content = m.getString("Content").substring(m.getString("Content").indexOf("<br/>") + 5);
               m.put("Content", content);
               m.put("groupMsg", true);
            }
         } else {
            CommonTools.msgFormatter(m, "Content");
         }
         if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_TEXT.getCode())) { // words
                                                                  // æ–‡æœ¬æ¶ˆæ¯
            if (m.getString("Url").length() != 0) {
               String regEx = "(.+?\\(.+?\\))";
               Matcher matcher = CommonTools.getMatcher(regEx, m.getString("Content"));
               String data = "Map";
               if (matcher.find()) {
                  data = matcher.group(1);
               }
               msg.put("Type", "Map");
               msg.put("Text", data);
            } else {
               msg.put("Type", MsgTypeEnum.TEXT.getType());
               msg.put("Text", m.getString("Content"));
            }
            m.put("Type", msg.getString("Type"));
            m.put("Text", msg.getString("Text"));
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_IMAGE.getCode())
               || m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_EMOTICON.getCode())) { // å›¾ç‰‡æ¶ˆæ¯
            m.put("Type", MsgTypeEnum.PIC.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VOICE.getCode())) { // è¯­éŸ³æ¶ˆæ¯
            m.put("Type", MsgTypeEnum.VOICE.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VERIFYMSG.getCode())) {// friends
            // å¥½å‹ç¡®è®¤æ¶ˆæ¯
            // MessageTools.addFriend(core, userName, 3, ticket); // ç¡®è®¤æ·»åŠ å¥½å‹
            m.put("Type", MsgTypeEnum.VERIFYMSG.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_SHARECARD.getCode())) { // å…±äº«åç‰‡
            m.put("Type", MsgTypeEnum.NAMECARD.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VIDEO.getCode())
               || m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MICROVIDEO.getCode())) {// viedo
            m.put("Type", MsgTypeEnum.VIEDO.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MEDIA.getCode())) { // å¤šåª’体消息
            m.put("Type", MsgTypeEnum.MEDIA.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_STATUSNOTIFY.getCode())) {// phone
            // init
            // å¾®ä¿¡åˆå§‹åŒ–消息
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_SYS.getCode())) {// ç³»ç»Ÿæ¶ˆæ¯
            m.put("Type", MsgTypeEnum.SYS.getType());
         } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_RECALLED.getCode())) { // æ’¤å›žæ¶ˆæ¯
         } else {
            LOG.info("Useless msg");
         }
         LOG.info("收到消息一条,来自: " + m.getString("FromUserName"));
         result.add(m);
      }
      return result;
   }
   /**
    * æ¶ˆæ¯å¤„理
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月14日 ä¸Šåˆ10:52:34
    * @param msgHandler
    */
   public static void handleMsg(IMsgHandlerFace msgHandler) {
      while (true) {
         if (core.getMsgList().size() > 0 && core.getMsgList().get(0).getContent() != null) {
            if (core.getMsgList().get(0).getContent().length() > 0) {
               BaseMsg msg = core.getMsgList().get(0);
               if (msg.getType() != null) {
                  try {
                     if (msg.getType().equals(MsgTypeEnum.TEXT.getType())) {
                        String result = msgHandler.textMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.PIC.getType())) {
                        String result = msgHandler.picMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.VOICE.getType())) {
                        String result = msgHandler.voiceMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.VIEDO.getType())) {
                        String result = msgHandler.viedoMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.NAMECARD.getType())) {
                        String result = msgHandler.nameCardMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.SYS.getType())) { // ç³»ç»Ÿæ¶ˆæ¯
                        msgHandler.sysMsgHandle(msg);
                     } else if (msg.getType().equals(MsgTypeEnum.VERIFYMSG.getType())) { // ç¡®è®¤æ·»åŠ å¥½å‹æ¶ˆæ¯
                        String result = msgHandler.verifyAddFriendMsgHandle(msg);
                        MessageTools.sendMsgById(result,
                              core.getMsgList().get(0).getRecommendInfo().getUserName());
                     } else if (msg.getType().equals(MsgTypeEnum.MEDIA.getType())) { // å¤šåª’体消息
                        String result = msgHandler.mediaMsgHandle(msg);
                        MessageTools.sendMsgById(result, core.getMsgList().get(0).getFromUserName());
                     }
                  } catch (Exception e) {
                     e.printStackTrace();
                  }
               }
            }
            core.getMsgList().remove(0);
         }
         try {
            TimeUnit.MILLISECONDS.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/face/IMsgHandlerFace.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.xmzs.common.wechat.face;
import com.xmzs.common.wechat.beans.BaseMsg;
/**
 * æ¶ˆæ¯å¤„理接口
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月20日 ä¸Šåˆ12:13:49
 * @version 1.0
 *
 */
public interface IMsgHandlerFace {
   /**
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月20日 ä¸Šåˆ12:15:00
    * @param msg
    * @return
    */
   public String textMsgHandle(BaseMsg msg);
   /**
    * å¤„理图片消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月21日 ä¸‹åˆ11:07:06
    * @param msg
    * @return
    */
   public String picMsgHandle(BaseMsg msg);
   /**
    * å¤„理声音消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月22日 ä¸Šåˆ12:09:44
    * @param msg
    * @return
    */
   public String voiceMsgHandle(BaseMsg msg);
   /**
    * å¤„理小视频消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月23日 ä¸‹åˆ12:19:50
    * @param msg
    * @return
    */
   public String viedoMsgHandle(BaseMsg msg);
   /**
    * å¤„理名片消息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月1日 ä¸Šåˆ12:50:50
    * @param msg
    * @return
    */
   public String nameCardMsgHandle(BaseMsg msg);
   /**
    * å¤„理系统消息
    *
    * @author Relyn
    * @date 2017å¹´6月21日17:43:51
    * @param msg
    * @return
    */
   public void sysMsgHandle(BaseMsg msg);
   /**
    * å¤„理确认添加好友消息
    *
    * @date 2017å¹´6月28日 ä¸‹åˆ10:15:30
    * @param msg
    * @return
    */
   public String verifyAddFriendMsgHandle(BaseMsg msg);
   /**
    * å¤„理收到的文件消息
    *
    * @date 2017å¹´7月21日 ä¸‹åˆ11:59:14
    * @param msg
    * @return
    */
   public String mediaMsgHandle(BaseMsg msg);
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/service/ILoginService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package com.xmzs.common.wechat.service;
/**
 * ç™»é™†æœåŠ¡æŽ¥å£
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月13日 ä¸Šåˆ12:07:21
 * @version 1.0
 *
 */
public interface ILoginService {
   /**
    * ç™»é™†
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:14:07
    * @return
    */
   boolean login();
   /**
    * èŽ·å–UUID
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:21:40
    * @param qrPath
    * @return
    */
   String getUuid();
   /**
    * èŽ·å–äºŒç»´ç å›¾ç‰‡
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:13:51
    * @param qrPath
    * @return
    */
   boolean getQR(String qrPath);
   /**
    * web初始化
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:14:13
    * @return
    */
   boolean webWxInit();
   /**
    * å¾®ä¿¡çŠ¶æ€é€šçŸ¥
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:14:24
    */
   void wxStatusNotify();
   /**
    * æŽ¥æ”¶æ¶ˆæ¯
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸Šåˆ12:14:37
    */
   void startReceiving();
   /**
    * èŽ·å–å¾®ä¿¡è”ç³»äºº
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月13日 ä¸‹åˆ2:26:18
    */
   void webWxGetContact();
   /**
    * æ‰¹é‡èŽ·å–è”ç³»äººä¿¡æ¯
    *
    * @date 2017å¹´6月22日 ä¸‹åˆ11:24:35
    */
   void WebWxBatchGetContact();
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/service/impl/LoginServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,687 @@
package com.xmzs.common.wechat.service.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.regex.Matcher;
import com.xmzs.common.wechat.utils.SleepUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xmzs.common.wechat.beans.BaseMsg;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.core.MsgCenter;
import com.xmzs.common.wechat.service.ILoginService;
import com.xmzs.common.wechat.utils.Config;
import com.xmzs.common.wechat.utils.MyHttpClient;
import com.xmzs.common.wechat.utils.enums.ResultEnum;
import com.xmzs.common.wechat.utils.enums.RetCodeEnum;
import com.xmzs.common.wechat.utils.enums.StorageLoginInfoEnum;
import com.xmzs.common.wechat.utils.enums.URLEnum;
import com.xmzs.common.wechat.utils.enums.parameters.BaseParaEnum;
import com.xmzs.common.wechat.utils.enums.parameters.LoginParaEnum;
import com.xmzs.common.wechat.utils.enums.parameters.StatusNotifyParaEnum;
import com.xmzs.common.wechat.utils.enums.parameters.UUIDParaEnum;
import com.xmzs.common.wechat.utils.tools.CommonTools;
/**
 * ç™»é™†æœåŠ¡å®žçŽ°ç±»
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月13日 ä¸Šåˆ12:09:35
 * @version 1.0
 *
 */
public class LoginServiceImpl implements ILoginService {
   private static Logger LOG = LoggerFactory.getLogger(LoginServiceImpl.class);
   private Core core = Core.getInstance();
   private MyHttpClient httpClient = core.getMyHttpClient();
   private MyHttpClient myHttpClient = core.getMyHttpClient();
   public LoginServiceImpl() {
   }
   @Override
   public boolean login() {
      boolean isLogin = false;
      // ç»„装参数和URL
      List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
      params.add(new BasicNameValuePair(LoginParaEnum.LOGIN_ICON.para(), LoginParaEnum.LOGIN_ICON.value()));
      params.add(new BasicNameValuePair(LoginParaEnum.UUID.para(), core.getUuid()));
      params.add(new BasicNameValuePair(LoginParaEnum.TIP.para(), LoginParaEnum.TIP.value()));
      // long time = 4000;
      while (!isLogin) {
         // SleepUtils.sleep(time += 1000);
         long millis = System.currentTimeMillis();
         params.add(new BasicNameValuePair(LoginParaEnum.R.para(), String.valueOf(millis / 1579L)));
         params.add(new BasicNameValuePair(LoginParaEnum._1.para(), String.valueOf(millis)));
         HttpEntity entity = httpClient.doGet(URLEnum.LOGIN_URL.getUrl(), params, true, null);
         try {
            String result = EntityUtils.toString(entity);
            String status = checklogin(result);
            if (ResultEnum.SUCCESS.getCode().equals(status)) {
               processLoginInfo(result); // å¤„理结果
               isLogin = true;
               core.setAlive(isLogin);
               break;
            }
            if (ResultEnum.WAIT_CONFIRM.getCode().equals(status)) {
               LOG.info("请点击微信确认按钮,进行登陆");
            }
         } catch (Exception e) {
            LOG.error("微信登陆异常!", e);
         }
      }
      return isLogin;
   }
   @Override
   public String getUuid() {
      // ç»„装参数和URL
      List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
      params.add(new BasicNameValuePair(UUIDParaEnum.APP_ID.para(), UUIDParaEnum.APP_ID.value()));
      params.add(new BasicNameValuePair(UUIDParaEnum.REDIRECT_URL.para(),
            UUIDParaEnum.REDIRECT_URL.value()));
      params.add(new BasicNameValuePair(UUIDParaEnum.FUN.para(), UUIDParaEnum.FUN.value()));
      params.add(new BasicNameValuePair(UUIDParaEnum.LANG.para(), UUIDParaEnum.LANG.value()));
      params.add(new BasicNameValuePair(UUIDParaEnum._1.para(), String.valueOf(System.currentTimeMillis())));
      HttpEntity entity = httpClient.doGet(URLEnum.UUID_URL.getUrl(), params, true, null);
      try {
         String result = EntityUtils.toString(entity);
         String regEx = "window.QRLogin.code = (\\d+); window.QRLogin.uuid = \"(\\S+?)\";";
         Matcher matcher = CommonTools.getMatcher(regEx, result);
         if (matcher.find()) {
            if ((ResultEnum.SUCCESS.getCode().equals(matcher.group(1)))) {
               core.setUuid(matcher.group(2));
            }
         }
      } catch (Exception e) {
         LOG.error(e.getMessage(), e);
      }
      return core.getUuid();
   }
   @Override
   public boolean getQR(String qrPath) {
      qrPath = qrPath + File.separator + "QR.jpg";
      String qrUrl = URLEnum.QRCODE_URL.getUrl() + core.getUuid();
      HttpEntity entity = myHttpClient.doGet(qrUrl, null, true, null);
      try {
         OutputStream out = new FileOutputStream(qrPath);
         byte[] bytes = EntityUtils.toByteArray(entity);
         out.write(bytes);
         out.flush();
         out.close();
         try {
            CommonTools.printQr(qrPath); // æ‰“开登陆二维码图片
         } catch (Exception e) {
            LOG.info(e.getMessage());
         }
      } catch (Exception e) {
         LOG.info(e.getMessage());
         return false;
      }
      return true;
   }
   @Override
   public boolean webWxInit() {
      core.setAlive(true);
      core.setLastNormalRetcodeTime(System.currentTimeMillis());
      // ç»„装请求URL和参数
      String url = String.format(URLEnum.INIT_URL.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()),
            String.valueOf(System.currentTimeMillis() / 3158L),
            core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
      Map<String, Object> paramMap = core.getParamMap();
      // è¯·æ±‚初始化接口
      HttpEntity entity = httpClient.doPost(url, JSON.toJSONString(paramMap));
      try {
         String result = EntityUtils.toString(entity, Consts.UTF_8);
         JSONObject obj = JSON.parseObject(result);
         JSONObject user = obj.getJSONObject(StorageLoginInfoEnum.User.getKey());
         JSONObject syncKey = obj.getJSONObject(StorageLoginInfoEnum.SyncKey.getKey());
         core.getLoginInfo().put(StorageLoginInfoEnum.InviteStartCount.getKey(),
               obj.getInteger(StorageLoginInfoEnum.InviteStartCount.getKey()));
         core.getLoginInfo().put(StorageLoginInfoEnum.SyncKey.getKey(), syncKey);
         JSONArray syncArray = syncKey.getJSONArray("List");
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < syncArray.size(); i++) {
            sb.append(syncArray.getJSONObject(i).getString("Key") + "_"
                  + syncArray.getJSONObject(i).getString("Val") + "|");
         }
         // 1_661706053|2_661706420|3_661706415|1000_1494151022|
         String synckey = sb.toString();
         // 1_661706053|2_661706420|3_661706415|1000_1494151022
         core.getLoginInfo().put(StorageLoginInfoEnum.synckey.getKey(), synckey.substring(0, synckey.length() - 1));// 1_656161336|2_656161626|3_656161313|11_656159955|13_656120033|201_1492273724|1000_1492265953|1001_1492250432|1004_1491805192
         core.setUserName(user.getString("UserName"));
         core.setNickName(user.getString("NickName"));
         core.setUserSelf(obj.getJSONObject("User"));
         String chatSet = obj.getString("ChatSet");
         String[] chatSetArray = chatSet.split(",");
         for (int i = 0; i < chatSetArray.length; i++) {
            if (chatSetArray[i].indexOf("@@") != -1) {
               // æ›´æ–°GroupIdList
               core.getGroupIdList().add(chatSetArray[i]); //
            }
         }
         // JSONArray contactListArray = obj.getJSONArray("ContactList");
         // for (int i = 0; i < contactListArray.size(); i++) {
         // JSONObject o = contactListArray.getJSONObject(i);
         // if (o.getString("UserName").indexOf("@@") != -1) {
         // core.getGroupIdList().add(o.getString("UserName")); //
         // // æ›´æ–°GroupIdList
         // core.getGroupList().add(o); // æ›´æ–°GroupList
         // core.getGroupNickNameList().add(o.getString("NickName"));
         // }
         // }
      } catch (Exception e) {
         e.printStackTrace();
         return false;
      }
      return true;
   }
   @Override
   public void wxStatusNotify() {
      // ç»„装请求URL和参数
      String url = String.format(URLEnum.STATUS_NOTIFY_URL.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put(StatusNotifyParaEnum.CODE.para(), StatusNotifyParaEnum.CODE.value());
      paramMap.put(StatusNotifyParaEnum.FROM_USERNAME.para(), core.getUserName());
      paramMap.put(StatusNotifyParaEnum.TO_USERNAME.para(), core.getUserName());
      paramMap.put(StatusNotifyParaEnum.CLIENT_MSG_ID.para(), System.currentTimeMillis());
      String paramStr = JSON.toJSONString(paramMap);
      try {
         HttpEntity entity = httpClient.doPost(url, paramStr);
         EntityUtils.toString(entity, Consts.UTF_8);
      } catch (Exception e) {
         LOG.error("微信状态通知接口失败!", e);
      }
   }
   @Override
   public void startReceiving() {
      core.setAlive(true);
      new Thread(new Runnable() {
         int retryCount = 0;
         @Override
         public void run() {
            while (core.isAlive()) {
               try {
                  Map<String, String> resultMap = syncCheck();
                  LOG.info(JSONObject.toJSONString(resultMap));
                  String retcode = resultMap.get("retcode");
                  String selector = resultMap.get("selector");
                  if (retcode.equals(RetCodeEnum.UNKOWN.getCode())) {
                     LOG.info(RetCodeEnum.UNKOWN.getType());
                     continue;
                  } else if (retcode.equals(RetCodeEnum.LOGIN_OUT.getCode())) { // é€€å‡º
                     LOG.info(RetCodeEnum.LOGIN_OUT.getType());
                     break;
                  } else if (retcode.equals(RetCodeEnum.LOGIN_OTHERWHERE.getCode())) { // å…¶å®ƒåœ°æ–¹ç™»é™†
                     LOG.info(RetCodeEnum.LOGIN_OTHERWHERE.getType());
                     break;
                  } else if (retcode.equals(RetCodeEnum.MOBILE_LOGIN_OUT.getCode())) { // ç§»åŠ¨ç«¯é€€å‡º
                     LOG.info(RetCodeEnum.MOBILE_LOGIN_OUT.getType());
                     break;
                  } else if (retcode.equals(RetCodeEnum.NORMAL.getCode())) {
                     core.setLastNormalRetcodeTime(System.currentTimeMillis()); // æœ€åŽæ”¶åˆ°æ­£å¸¸æŠ¥æ–‡æ—¶é—´
                     JSONObject msgObj = webWxSync();
                     if (selector.equals("2")) {
                        if (msgObj != null) {
                           try {
                              JSONArray msgList = new JSONArray();
                              msgList = msgObj.getJSONArray("AddMsgList");
                              msgList = MsgCenter.produceMsg(msgList);
                              for (int j = 0; j < msgList.size(); j++) {
                                 BaseMsg baseMsg = JSON.toJavaObject(msgList.getJSONObject(j),
                                       BaseMsg.class);
                                 core.getMsgList().add(baseMsg);
                              }
                           } catch (Exception e) {
                              LOG.info(e.getMessage());
                           }
                        }
                     } else if (selector.equals("7")) {
                        webWxSync();
                     } else if (selector.equals("4")) {
                        continue;
                     } else if (selector.equals("3")) {
                        continue;
                     } else if (selector.equals("6")) {
                        if (msgObj != null) {
                           try {
                              JSONArray msgList = new JSONArray();
                              msgList = msgObj.getJSONArray("AddMsgList");
                              JSONArray modContactList = msgObj.getJSONArray("ModContactList"); // å­˜åœ¨åˆ é™¤æˆ–者新增的好友信息
                              msgList = MsgCenter.produceMsg(msgList);
                              for (int j = 0; j < msgList.size(); j++) {
                                 JSONObject userInfo = modContactList.getJSONObject(j);
                                 // å­˜åœ¨ä¸»åŠ¨åŠ å¥½å‹ä¹‹åŽçš„åŒæ­¥è”ç³»äººåˆ°æœ¬åœ°
                                 core.getContactList().add(userInfo);
                              }
                           } catch (Exception e) {
                              LOG.info(e.getMessage());
                           }
                        }
                     }
                  } else {
                     JSONObject obj = webWxSync();
                  }
               } catch (Exception e) {
                  LOG.info(e.getMessage());
                  retryCount += 1;
                  if (core.getReceivingRetryCount() < retryCount) {
                     core.setAlive(false);
                  } else {
                     try {
                        Thread.sleep(1000);
                     } catch (InterruptedException e1) {
                        LOG.info(e.getMessage());
                     }
                  }
               }
            }
         }
      }).start();
   }
   @Override
   public void webWxGetContact() {
      String url = String.format(URLEnum.WEB_WX_GET_CONTACT.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()));
      Map<String, Object> paramMap = core.getParamMap();
      HttpEntity entity = httpClient.doPost(url, JSON.toJSONString(paramMap));
      try {
         String result = EntityUtils.toString(entity, Consts.UTF_8);
         JSONObject fullFriendsJsonList = JSON.parseObject(result);
         // æŸ¥çœ‹seq是否为0,0表示好友列表已全部获取完毕,若大于0,则表示好友列表未获取完毕,当前的字节数(断点续传)
         long seq = 0;
         long currentTime = 0L;
         List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
         if (fullFriendsJsonList.get("Seq") != null) {
            seq = fullFriendsJsonList.getLong("Seq");
            currentTime = new Date().getTime();
         }
         core.setMemberCount(fullFriendsJsonList.getInteger(StorageLoginInfoEnum.MemberCount.getKey()));
         JSONArray member = fullFriendsJsonList.getJSONArray(StorageLoginInfoEnum.MemberList.getKey());
         // å¾ªçŽ¯èŽ·å–seq直到为0,即获取全部好友列表 ==0:好友获取完毕 >0:好友未获取完毕,此时seq为已获取的字节数
         while (seq > 0) {
            // è®¾ç½®seq传参
            params.add(new BasicNameValuePair("r", String.valueOf(currentTime)));
            params.add(new BasicNameValuePair("seq", String.valueOf(seq)));
            entity = httpClient.doGet(url, params, false, null);
            params.remove(new BasicNameValuePair("r", String.valueOf(currentTime)));
            params.remove(new BasicNameValuePair("seq", String.valueOf(seq)));
            result = EntityUtils.toString(entity, Consts.UTF_8);
            fullFriendsJsonList = JSON.parseObject(result);
            if (fullFriendsJsonList.get("Seq") != null) {
               seq = fullFriendsJsonList.getLong("Seq");
               currentTime = new Date().getTime();
            }
            // ç´¯åŠ å¥½å‹åˆ—è¡¨
            member.addAll(fullFriendsJsonList.getJSONArray(StorageLoginInfoEnum.MemberList.getKey()));
         }
         core.setMemberCount(member.size());
         for (Iterator<?> iterator = member.iterator(); iterator.hasNext();) {
            JSONObject o = (JSONObject) iterator.next();
            if ((o.getInteger("VerifyFlag") & 8) != 0) { // å…¬ä¼—号/服务号
               core.getPublicUsersList().add(o);
            } else if (Config.API_SPECIAL_USER.contains(o.getString("UserName"))) { // ç‰¹æ®Šè´¦å·
               core.getSpecialUsersList().add(o);
            } else if (o.getString("UserName").indexOf("@@") != -1) { // ç¾¤èŠ
               if (!core.getGroupIdList().contains(o.getString("UserName"))) {
                  core.getGroupNickNameList().add(o.getString("NickName"));
                  core.getGroupIdList().add(o.getString("UserName"));
                  core.getGroupList().add(o);
               }
            } else if (o.getString("UserName").equals(core.getUserSelf().getString("UserName"))) { // è‡ªå·±
               core.getContactList().remove(o);
            } else { // æ™®é€šè”系人
               core.getContactList().add(o);
            }
         }
         return;
      } catch (Exception e) {
         LOG.error(e.getMessage(), e);
      }
      return;
   }
   @Override
   public void WebWxBatchGetContact() {
      String url = String.format(URLEnum.WEB_WX_BATCH_GET_CONTACT.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()), new Date().getTime(),
            core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put("Count", core.getGroupIdList().size());
      List<Map<String, String>> list = new ArrayList<Map<String, String>>();
      for (int i = 0; i < core.getGroupIdList().size(); i++) {
         HashMap<String, String> map = new HashMap<String, String>();
         map.put("UserName", core.getGroupIdList().get(i));
         map.put("EncryChatRoomId", "");
         list.add(map);
      }
      paramMap.put("List", list);
      HttpEntity entity = httpClient.doPost(url, JSON.toJSONString(paramMap));
      try {
         String text = EntityUtils.toString(entity, Consts.UTF_8);
         JSONObject obj = JSON.parseObject(text);
         JSONArray contactList = obj.getJSONArray("ContactList");
         for (int i = 0; i < contactList.size(); i++) { // ç¾¤å¥½å‹
            if (contactList.getJSONObject(i).getString("UserName").indexOf("@@") > -1) { // ç¾¤
               core.getGroupNickNameList().add(contactList.getJSONObject(i).getString("NickName")); // æ›´æ–°ç¾¤æ˜µç§°åˆ—表
               core.getGroupList().add(contactList.getJSONObject(i)); // æ›´æ–°ç¾¤ä¿¡æ¯ï¼ˆæ‰€æœ‰ï¼‰åˆ—表
               core.getGroupMemeberMap().put(contactList.getJSONObject(i).getString("UserName"),
                     contactList.getJSONObject(i).getJSONArray("MemberList")); // æ›´æ–°ç¾¤æˆå‘˜Map
            }
         }
      } catch (Exception e) {
         LOG.info(e.getMessage());
      }
   }
   /**
    * æ£€æŸ¥ç™»é™†çŠ¶æ€
    *
    * @param result
    * @return
    */
   public String checklogin(String result) {
      String regEx = "window.code=(\\d+)";
      Matcher matcher = CommonTools.getMatcher(regEx, result);
      if (matcher.find()) {
         return matcher.group(1);
      }
      return null;
   }
   /**
    * å¤„理登陆信息
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月9日 ä¸‹åˆ12:16:26
    * @param loginContent
    */
   private void processLoginInfo(String loginContent) {
      String regEx = "window.redirect_uri=\"(\\S+)\";";
      Matcher matcher = CommonTools.getMatcher(regEx, loginContent);
      if (matcher.find()) {
         String originalUrl = matcher.group(1);
         String url = originalUrl.substring(0, originalUrl.lastIndexOf('/')); // https://wx2.qq.com/cgi-bin/mmwebwx-bin
         core.getLoginInfo().put("url", url);
         Map<String, List<String>> possibleUrlMap = this.getPossibleUrlMap();
         Iterator<Entry<String, List<String>>> iterator = possibleUrlMap.entrySet().iterator();
         Map.Entry<String, List<String>> entry;
         String fileUrl;
         String syncUrl;
         while (iterator.hasNext()) {
            entry = iterator.next();
            String indexUrl = entry.getKey();
            fileUrl = "https://" + entry.getValue().get(0) + "/cgi-bin/mmwebwx-bin";
            syncUrl = "https://" + entry.getValue().get(1) + "/cgi-bin/mmwebwx-bin";
            if (core.getLoginInfo().get("url").toString().contains(indexUrl)) {
               core.setIndexUrl(indexUrl);
               core.getLoginInfo().put("fileUrl", fileUrl);
               core.getLoginInfo().put("syncUrl", syncUrl);
               break;
            }
         }
         if (core.getLoginInfo().get("fileUrl") == null && core.getLoginInfo().get("syncUrl") == null) {
            core.getLoginInfo().put("fileUrl", url);
            core.getLoginInfo().put("syncUrl", url);
         }
         core.getLoginInfo().put("deviceid", "e" + String.valueOf(new Random().nextLong()).substring(1, 16)); // ç”Ÿæˆ15位随机数
         core.getLoginInfo().put("BaseRequest", new ArrayList<String>());
         String text = "";
         try {
            HttpEntity entity = myHttpClient.doGet(originalUrl, null, false, null);
            text = EntityUtils.toString(entity);
         } catch (Exception e) {
            LOG.info(e.getMessage());
            return;
         }
         //add by é»˜éžé»˜ 2017-08-01 22:28:09
         //如果登录被禁止时,则登录返回的message内容不为空,下面代码则判断登录内容是否为空,不为空则退出程序
         String msg = getLoginMessage(text);
         if (!"".equals(msg)){
            LOG.info(msg);
            System.exit(0);
         }
         Document doc = CommonTools.xmlParser(text);
         if (doc != null) {
            core.getLoginInfo().put(StorageLoginInfoEnum.skey.getKey(),
                  doc.getElementsByTagName(StorageLoginInfoEnum.skey.getKey()).item(0).getFirstChild()
                        .getNodeValue());
            core.getLoginInfo().put(StorageLoginInfoEnum.wxsid.getKey(),
                  doc.getElementsByTagName(StorageLoginInfoEnum.wxsid.getKey()).item(0).getFirstChild()
                        .getNodeValue());
            core.getLoginInfo().put(StorageLoginInfoEnum.wxuin.getKey(),
                  doc.getElementsByTagName(StorageLoginInfoEnum.wxuin.getKey()).item(0).getFirstChild()
                        .getNodeValue());
            core.getLoginInfo().put(StorageLoginInfoEnum.pass_ticket.getKey(),
                  doc.getElementsByTagName(StorageLoginInfoEnum.pass_ticket.getKey()).item(0).getFirstChild()
                        .getNodeValue());
         }
      }
   }
   private Map<String, List<String>> getPossibleUrlMap() {
      Map<String, List<String>> possibleUrlMap = new HashMap<String, List<String>>();
      possibleUrlMap.put("wx.qq.com", new ArrayList<String>() {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            add("file.wx.qq.com");
            add("webpush.wx.qq.com");
         }
      });
      possibleUrlMap.put("wx2.qq.com", new ArrayList<String>() {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            add("file.wx2.qq.com");
            add("webpush.wx2.qq.com");
         }
      });
      possibleUrlMap.put("wx8.qq.com", new ArrayList<String>() {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            add("file.wx8.qq.com");
            add("webpush.wx8.qq.com");
         }
      });
      possibleUrlMap.put("web2.wechat.com", new ArrayList<String>() {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            add("file.web2.wechat.com");
            add("webpush.web2.wechat.com");
         }
      });
      possibleUrlMap.put("wechat.com", new ArrayList<String>() {
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         {
            add("file.web.wechat.com");
            add("webpush.web.wechat.com");
         }
      });
      return possibleUrlMap;
   }
   /**
    * åŒæ­¥æ¶ˆæ¯ sync the messages
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月12日 ä¸Šåˆ12:24:55
    * @return
    */
   private JSONObject webWxSync() {
      JSONObject result = null;
      String url = String.format(URLEnum.WEB_WX_SYNC_URL.getUrl(),
            core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()),
            core.getLoginInfo().get(StorageLoginInfoEnum.wxsid.getKey()),
            core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey()),
            core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
      Map<String, Object> paramMap = core.getParamMap();
      paramMap.put(StorageLoginInfoEnum.SyncKey.getKey(),
            core.getLoginInfo().get(StorageLoginInfoEnum.SyncKey.getKey()));
      paramMap.put("rr", -new Date().getTime() / 1000);
      String paramStr = JSON.toJSONString(paramMap);
      try {
         HttpEntity entity = myHttpClient.doPost(url, paramStr);
         String text = EntityUtils.toString(entity, Consts.UTF_8);
         JSONObject obj = JSON.parseObject(text);
         if (obj.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
            result = null;
         } else {
            result = obj;
            core.getLoginInfo().put(StorageLoginInfoEnum.SyncKey.getKey(), obj.getJSONObject("SyncCheckKey"));
            JSONArray syncArray = obj.getJSONObject(StorageLoginInfoEnum.SyncKey.getKey()).getJSONArray("List");
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < syncArray.size(); i++) {
               sb.append(syncArray.getJSONObject(i).getString("Key") + "_"
                     + syncArray.getJSONObject(i).getString("Val") + "|");
            }
            String synckey = sb.toString();
            core.getLoginInfo().put(StorageLoginInfoEnum.synckey.getKey(),
                  synckey.substring(0, synckey.length() - 1));// 1_656161336|2_656161626|3_656161313|11_656159955|13_656120033|201_1492273724|1000_1492265953|1001_1492250432|1004_1491805192
         }
      } catch (Exception e) {
         LOG.info(e.getMessage());
      }
      return result;
   }
   /**
    * æ£€æŸ¥æ˜¯å¦æœ‰æ–°æ¶ˆæ¯ check whether there's a message
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月16日 ä¸Šåˆ11:11:34
    * @return
    *
    */
   private Map<String, String> syncCheck() {
      Map<String, String> resultMap = new HashMap<String, String>();
      // ç»„装请求URL和参数
      String url = core.getLoginInfo().get(StorageLoginInfoEnum.syncUrl.getKey()) + URLEnum.SYNC_CHECK_URL.getUrl();
      List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
      for (BaseParaEnum baseRequest : BaseParaEnum.values()) {
         params.add(new BasicNameValuePair(baseRequest.para().toLowerCase(),
               core.getLoginInfo().get(baseRequest.value()).toString()));
      }
      params.add(new BasicNameValuePair("r", String.valueOf(new Date().getTime())));
      params.add(new BasicNameValuePair("synckey", (String) core.getLoginInfo().get("synckey")));
      params.add(new BasicNameValuePair("_", String.valueOf(new Date().getTime())));
      SleepUtils.sleep(7);
      try {
         HttpEntity entity = myHttpClient.doGet(url, params, true, null);
         if (entity == null) {
            resultMap.put("retcode", "9999");
            resultMap.put("selector", "9999");
            return resultMap;
         }
         String text = EntityUtils.toString(entity);
         String regEx = "window.synccheck=\\{retcode:\"(\\d+)\",selector:\"(\\d+)\"\\}";
         Matcher matcher = CommonTools.getMatcher(regEx, text);
         if (!matcher.find() || matcher.group(1).equals("2")) {
            LOG.info(String.format("Unexpected sync check result: %s", text));
         } else {
            resultMap.put("retcode", matcher.group(1));
            resultMap.put("selector", matcher.group(2));
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
      return resultMap;
   }
   /**
    * è§£æžç™»å½•返回的消息,如果成功登录,则message为空
    * @param result
    * @return
    */
   public String getLoginMessage(String result){
      String[] strArr = result.split("<message>");
      String[] rs = strArr[1].split("</message>");
      if (rs!=null && rs.length>1) {
         return rs[0];
      }
      return "";
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/thread/CheckLoginStatusThread.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.xmzs.common.wechat.thread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.utils.SleepUtils;
/**
 * æ£€æŸ¥å¾®ä¿¡åœ¨çº¿çŠ¶æ€
 * <p>
 * å¦‚何来感知微信状态?
 * å¾®ä¿¡ä¼šæœ‰å¿ƒè·³åŒ…,LoginServiceImpl.syncCheck()正常在线情况下返回的消息中retcode报文应该为"0",心跳间隔一般在25秒,
 * é‚£ä¹ˆå¯ä»¥é€šè¿‡æœ€åŽæ”¶åˆ°æ­£å¸¸æŠ¥æ–‡çš„æ—¶é—´æ¥ä½œä¸ºåˆ¤æ–­æ˜¯å¦åœ¨çº¿çš„依据。若报文间隔大于60秒,则认为已掉线。
 * </p>
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月17日 ä¸‹åˆ10:53:15
 * @version 1.0
 *
 */
public class CheckLoginStatusThread implements Runnable {
   private static Logger LOG = LoggerFactory.getLogger(CheckLoginStatusThread.class);
   private Core core = Core.getInstance();
   @Override
   public void run() {
      while (core.isAlive()) {
         long t1 = System.currentTimeMillis(); // ç§’为单位
         if (t1 - core.getLastNormalRetcodeTime() > 60 * 1000) { // è¶…过60秒,判为离线
            core.setAlive(false);
            LOG.info("微信已离线");
         }
         SleepUtils.sleep(10 * 1000); // ä¼‘眠10秒
      }
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/Config.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.xmzs.common.wechat.utils;
import com.xmzs.common.wechat.utils.enums.OsNameEnum;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
/**
 * é…ç½®ä¿¡æ¯
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月23日 ä¸‹åˆ2:26:21
 * @version 1.0
 *
 */
public class Config {
   public static final String API_WXAPPID = "API_WXAPPID";
   public static final String picDir = "D://itchat4j";
   public static final String VERSION = "1.4.1";
   public static final String BASE_URL = "https://login.weixin.qq.com";
   public static final String REFERER = "https://wx.qq.com/?&lang=zh_CN&target=t";
   public static final String OS = "";
   public static final String DIR = "";
   public static final String DEFAULT_QR = "QR.jpg";
   public static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
   public static final String UOS_PATCH_CLIENT_VERSION = "2.0.0";
   public static final String UOS_PATCH_EXTSPAM =
         "Go8FCIkFEokFCggwMDAwMDAwMRAGGvAESySibk50w5Wb3uTl2c2h64jVVrV7gNs06GFlWplHQbY/5FfiO++1yH4ykCyNPWKXmco+wfQzK5R98D3so7rJ5LmGFvBLjGceleySrc3SOf2Pc1gVehzJgODeS0lDL3/I/0S2SSE98YgKleq6Uqx6ndTy9yaL9qFxJL7eiA/R3SEfTaW1SBoSITIu+EEkXff+Pv8NHOk7N57rcGk1w0ZzRrQDkXTOXFN2iHYIzAAZPIOY45Lsh+A4slpgnDiaOvRtlQYCt97nmPLuTipOJ8Qc5pM7ZsOsAPPrCQL7nK0I7aPrFDF0q4ziUUKettzW8MrAaiVfmbD1/VkmLNVqqZVvBCtRblXb5FHmtS8FxnqCzYP4WFvz3T0TcrOqwLX1M/DQvcHaGGw0B0y4bZMs7lVScGBFxMj3vbFi2SRKbKhaitxHfYHAOAa0X7/MSS0RNAjdwoyGHeOepXOKY+h3iHeqCvgOH6LOifdHf/1aaZNwSkGotYnYScW8Yx63LnSwba7+hESrtPa/huRmB9KWvMCKbDThL/nne14hnL277EDCSocPu3rOSYjuB9gKSOdVmWsj9Dxb/iZIe+S6AiG29Esm+/eUacSba0k8wn5HhHg9d4tIcixrxveflc8vi2/wNQGVFNsGO6tB5WF0xf/plngOvQ1/ivGV/C1Qpdhzznh0ExAVJ6dwzNg7qIEBaw+BzTJTUuRcPk92Sn6QDn2Pu3mpONaEumacjW4w6ipPnPw+g2TfywJjeEcpSZaP4Q3YV5HG8D6UjWA4GSkBKculWpdCMadx0usMomsSS/74QgpYqcPkmamB4nVv1JxczYITIqItIKjD35IGKAUwAA==";
   public static final ArrayList<String> API_SPECIAL_USER = new ArrayList<String>(Arrays.asList("filehelper", "weibo",
         "qqmail", "fmessage", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote",
         "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp", "meishiapp", "feedsapp", "voip",
         "blogappweixin", "brandsessionholder", "weixin", "weixinreminder", "officialaccounts", "wxitil",
         "notification_messages", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "userexperience_alarm"));
   /**
    * èŽ·å–æ–‡ä»¶ç›®å½•
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月8日 ä¸‹åˆ10:27:42
    * @return
    */
   public static String getLocalPath() {
      String localPath = null;
      try {
         localPath = new File("").getCanonicalPath();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      return localPath;
   }
   /**
    * èŽ·å–ç³»ç»Ÿå¹³å°
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月8日 ä¸‹åˆ10:27:53
    */
   public static OsNameEnum getOsNameEnum() {
      String os = System.getProperty("os.name").toUpperCase();
      if (os.indexOf(OsNameEnum.DARWIN.toString()) >= 0) {
         return OsNameEnum.DARWIN;
      } else if (os.indexOf(OsNameEnum.WINDOWS.toString()) >= 0) {
         return OsNameEnum.WINDOWS;
      } else if (os.indexOf(OsNameEnum.LINUX.toString()) >= 0) {
         return OsNameEnum.LINUX;
      } else if (os.indexOf(OsNameEnum.MAC.toString()) >= 0) {
         return OsNameEnum.MAC;
      }
      return OsNameEnum.OTHER;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/ConstantConfigEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.xmzs.common.wechat.utils;
/**
 * å¸¸é‡
 *
 * @author https=//github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月5日 ä¸‹åˆ11=29=04
 * @version 1.0
 *
 */
public class ConstantConfigEnum {
   public static final int APPMSGTYPE_TEXT = 1;
   public static final int APPMSGTYPE_IMG = 2;
   public static final int APPMSGTYPE_AUDIO = 3;
   public static final int APPMSGTYPE_VIDEO = 4;
   public static final int APPMSGTYPE_URL = 5;
   public static final int APPMSGTYPE_ATTACH = 6;
   public static final int APPMSGTYPE_OPEN = 7;
   public static final int APPMSGTYPE_EMOJI = 8;
   public static final int APPMSGTYPE_VOICE_REMIND = 9;
   public static final int APPMSGTYPE_SCAN_GOOD = 10;
   public static final int APPMSGTYPE_GOOD = 13;
   public static final int APPMSGTYPE_EMOTION = 15;
   public static final int APPMSGTYPE_CARD_TICKET = 16;
   public static final int APPMSGTYPE_REALTIME_SHARE_LOCATION = 17;
   // public static final int APPMSGTYPE_TRANSFERS = 2e3;
   public static final int APPMSGTYPE_RED_ENVELOPES = 2001;
   public static final int APPMSGTYPE_READER_TYPE = 100001;
   public static final int UPLOAD_MEDIA_TYPE_IMAGE = 1;
   public static final int UPLOAD_MEDIA_TYPE_VIDEO = 2;
   public static final int UPLOAD_MEDIA_TYPE_AUDIO = 3;
   public static final int UPLOAD_MEDIA_TYPE_ATTACHMENT = 4;
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/MsgKeywords.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
package com.xmzs.common.wechat.utils;
public class MsgKeywords {
   public static String newFriendStr = "我通过了你的朋友验证请求";
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/MyHttpClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,194 @@
package com.xmzs.common.wechat.utils;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
 * HTTP访问类,对Apache HttpClient进行简单封装,适配器模式
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月9日 ä¸‹åˆ7:05:04
 * @version 1.0
 *
 */
public class MyHttpClient {
   private Logger logger = Logger.getLogger("MyHttpClient");
   private static CloseableHttpClient httpClient = HttpClients.createDefault();
   private static MyHttpClient instance = null;
   private static CookieStore cookieStore;
   static {
      cookieStore = new BasicCookieStore();
      // å°†CookieStore设置到httpClient中
      httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
   }
   public static String getCookie(String name) {
      List<Cookie> cookies = cookieStore.getCookies();
      for (Cookie cookie : cookies) {
         if (cookie.getName().equalsIgnoreCase(name)) {
            return cookie.getValue();
         }
      }
      return null;
   }
   private MyHttpClient() {
   }
   /**
    * èŽ·å–cookies
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ8:37:17
    * @return
    */
   public static MyHttpClient getInstance() {
      if (instance == null) {
         synchronized (MyHttpClient.class) {
            if (instance == null) {
               instance = new MyHttpClient();
            }
         }
      }
      return instance;
   }
   /**
    * å¤„理GET请求
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月9日 ä¸‹åˆ7:06:19
    * @param url
    * @param params
    * @return
    */
   public HttpEntity doGet(String url, List<BasicNameValuePair> params, boolean redirect,
         Map<String, String> headerMap) {
      HttpEntity entity = null;
      HttpGet httpGet = new HttpGet();
      try {
         if (params != null) {
            String paramStr = EntityUtils.toString(new UrlEncodedFormEntity(params, Consts.UTF_8));
            httpGet = new HttpGet(url + "?" + paramStr);
         } else {
            httpGet = new HttpGet(url);
         }
         if (!redirect) {
            httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build()); // ç¦æ­¢é‡å®šå‘
         }
         httpGet.setHeader("User-Agent", Config.USER_AGENT);
         httpGet.setHeader("client-version", Config.UOS_PATCH_CLIENT_VERSION);
         httpGet.setHeader("extspam", Config.UOS_PATCH_EXTSPAM);
         httpGet.setHeader("referer", Config.REFERER);
         if (headerMap != null) {
            Set<Entry<String, String>> entries = headerMap.entrySet();
            for (Entry<String, String> entry : entries) {
               httpGet.setHeader(entry.getKey(), entry.getValue());
            }
         }
         CloseableHttpResponse response = httpClient.execute(httpGet);
         entity = response.getEntity();
      } catch (ClientProtocolException e) {
         logger.info(e.getMessage());
      } catch (IOException e) {
         logger.info(e.getMessage());
      }
      return entity;
   }
   /**
    * å¤„理POST请求
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月9日 ä¸‹åˆ7:06:35
    * @param url
    * @param params
    * @return
    */
   public HttpEntity doPost(String url, String paramsStr) {
      HttpEntity entity = null;
      HttpPost httpPost = new HttpPost();
      try {
         StringEntity params = new StringEntity(paramsStr, Consts.UTF_8);
         httpPost = new HttpPost(url);
         httpPost.setEntity(params);
         httpPost.setHeader("Content-type", "application/json; charset=utf-8");
         httpPost.setHeader("User-Agent", Config.USER_AGENT);
         httpPost.setHeader("client-version", Config.UOS_PATCH_CLIENT_VERSION);
         httpPost.setHeader("extspam", Config.UOS_PATCH_EXTSPAM);
         httpPost.setHeader("referer", Config.REFERER);
         CloseableHttpResponse response = httpClient.execute(httpPost);
         entity = response.getEntity();
      } catch (ClientProtocolException e) {
         logger.info(e.getMessage());
      } catch (IOException e) {
         logger.info(e.getMessage());
      }
      return entity;
   }
   /**
    * ä¸Šä¼ æ–‡ä»¶åˆ°æœåС噍
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´5月7日 ä¸‹åˆ9:19:23
    * @param url
    * @param reqEntity
    * @return
    */
   public HttpEntity doPostFile(String url, HttpEntity reqEntity) {
      HttpEntity entity = null;
      HttpPost httpPost = new HttpPost(url);
      httpPost.setHeader("User-Agent", Config.USER_AGENT);
      httpPost.setHeader("client-version", Config.UOS_PATCH_CLIENT_VERSION);
      httpPost.setHeader("extspam", Config.UOS_PATCH_EXTSPAM);
      httpPost.setHeader("referer", Config.REFERER);
      httpPost.setEntity(reqEntity);
      try {
         CloseableHttpResponse response = httpClient.execute(httpPost);
         entity = response.getEntity();
      } catch (Exception e) {
         logger.info(e.getMessage());
      }
      return entity;
   }
   public static CloseableHttpClient getHttpClient() {
      return httpClient;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/SleepUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.xmzs.common.wechat.utils;
/**
 * Created by xiaoxiaomo on 2017/5/6.
 */
public class SleepUtils {
    /**
     * æ¯«ç§’为单位
     * @param time
     */
    public static void sleep( long time ){
        try {
            Thread.sleep( time );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/MsgCodeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * æ¶ˆæ¯ç±»åž‹
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月23日 ä¸‹åˆ12:15:00
 * @version 1.0
 *
 */
public enum MsgCodeEnum {
   // public static final int MSGTYPE_TEXT = 1; // æ–‡æœ¬æ¶ˆæ¯ç±»åž‹
   // public static final int MSGTYPE_IMAGE = 3; // å›¾ç‰‡æ¶ˆæ¯
   // public static final int MSGTYPE_VOICE = 34; // è¯­éŸ³æ¶ˆæ¯
   // public static final int MSGTYPE_VIDEO = 43; // å°è§†é¢‘消息
   // public static final int MSGTYPE_MICROVIDEO = 62; // çŸ­è§†é¢‘消息
   // public static final int MSGTYPE_EMOTICON = 47; // è¡¨æƒ…消息
   // public static final int MSGTYPE_APP = 49;
   // public static final int MSGTYPE_VOIPMSG = 50;
   // public static final int MSGTYPE_VOIPNOTIFY = 52;
   // public static final int MSGTYPE_VOIPINVITE = 53;
   // public static final int MSGTYPE_LOCATION = 48;
   // public static final int MSGTYPE_STATUSNOTIFY = 51;
   // public static final int MSGTYPE_SYSNOTICE = 9999;
   // public static final int MSGTYPE_POSSIBLEFRIEND_MSG = 40;
   // public static final int MSGTYPE_VERIFYMSG = 37;
   // public static final int MSGTYPE_SHARECARD = 42;
   // public static final int MSGTYPE_SYS = 10000;
   // public static final int MSGTYPE_RECALLED = 10002;
   MSGTYPE_TEXT(1, "文本消息类型"),
   MSGTYPE_IMAGE(3, "图片消息"),
   MSGTYPE_VOICE(34, "语音消息"),
   MSGTYPE_VIDEO(43, "小视频消息"),
   MSGTYPE_MICROVIDEO(62, "短视频消息"),
   MSGTYPE_EMOTICON(47, "表情消息"),
   MSGTYPE_MEDIA(49, "多媒体消息"),
   MSGTYPE_VOIPMSG(50, ""),
   MSGTYPE_VOIPNOTIFY(52, ""),
   MSGTYPE_VOIPINVITE(53, ""),
   MSGTYPE_LOCATION(48, ""),
   MSGTYPE_STATUSNOTIFY(51, ""),
   MSGTYPE_SYSNOTICE(9999, ""),
   MSGTYPE_POSSIBLEFRIEND_MSG(40, ""),
   MSGTYPE_VERIFYMSG(37, "好友请求"),
   MSGTYPE_SHARECARD(42, ""),
   MSGTYPE_SYS(10000, "系统消息"),
   MSGTYPE_RECALLED(10002, "")
   ;
   private int code;
   private String type;
   MsgCodeEnum(int code, String type) {
      this.code = code;
      this.type = type;
   }
   public int getCode() {
      return code;
   }
   public String getType() {
      return type;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/MsgTypeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * æ¶ˆæ¯ç±»åž‹æžšä¸¾ç±»
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´5月13日 ä¸‹åˆ11:53:00
 * @version 1.0
 *
 */
public enum MsgTypeEnum {
   TEXT("Text", "文本消息"),
   PIC("Pic", "图片消息"),
   VOICE("Voice", "语音消息"),
   VIEDO("Viedo", "小视频消息"),
   NAMECARD("NameCard", "名片消息"),
   SYS("Sys", "系统消息"),
   VERIFYMSG("VerifyMsg", "添加好友"),
   MEDIA("app", "文件消息");
   private String type;
   private String code;
   MsgTypeEnum(String type, String code) {
      this.type = type;
      this.code = code;
   }
   public String getType() {
      return type;
   }
   public String getCode() {
      return code;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/OsNameEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * ç³»ç»Ÿå¹³å°
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月8日 ä¸‹åˆ10:36:28
 * @version 1.0
 *
 */
public enum OsNameEnum {
   WINDOWS, LINUX, DARWIN, MAC, OTHER
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/ResultEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * è¿”回结构枚举类
 * <p>
 * Created by xiaoxiaomo on 2017/5/6.
 */
public enum ResultEnum {
    SUCCESS("200", "成功"),
    WAIT_CONFIRM("201", "请在手机上点击确认"),
    WAIT_SCAN("400", "请扫描二维码");
    private String code;
    private String msg;
    ResultEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public String getCode() {
        return code;
    }
//    public static MsgInfoEnum getCode(String code) {
//        switch (code) {
//            case "Text":
//                return MsgInfoEnum.TEXT;
//            default:
//                return MsgInfoEnum.VIDEO;
//        }
//    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/RetCodeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.xmzs.common.wechat.utils.enums;
public enum RetCodeEnum {
   NORMAL("0", "普通"),
   LOGIN_OUT("1102", "退出"),
   LOGIN_OTHERWHERE("1101", "其它地方登陆"),
   MOBILE_LOGIN_OUT("1102", "移动端退出"),
   UNKOWN("9999", "未知")
   ;
   private String code;
   private String type;
   RetCodeEnum(String code, String type) {
      this.code = code;
      this.type = type;
   }
   public String getCode() {
      return code;
   }
   public String getType() {
      return type;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/StorageLoginInfoEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.xmzs.common.wechat.utils.enums;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by xiaoxiaomo on 2017/5/7.
 */
public enum StorageLoginInfoEnum {
    //URL
    url("url",new String()),
    fileUrl("fileUrl",new String()),
    syncUrl("syncUrl",new String()),
    deviceid("deviceid",new String()), //生成15位随机数
    //baseRequest
    skey("skey",new String()),
    wxsid("wxsid",new String()),
    wxuin("wxuin",new String()),
    pass_ticket("pass_ticket",new String()),
    InviteStartCount("InviteStartCount",0),
    User("User",new JSONObject()),
    SyncKey("SyncKey",new JSONObject()),
    synckey("synckey",new String()),
    MemberCount("MemberCount",new String()),
    MemberList("MemberList",new JSONArray()),
    ;
    private String key;
    private Object type;
    StorageLoginInfoEnum(String key, Object type) {
        this.key = key;
        this.type = type;
    }
    public String getKey() {
        return key;
    }
    public Object getType() {
        return type;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/URLEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * URL
 * Created by xiaoxiaomo on 2017/5/6.
 */
public enum URLEnum {
    BASE_URL("https://login.weixin.qq.com","基本的URL"),
    UUID_URL(BASE_URL.url+"/jslogin","UUIDLURL"),
    QRCODE_URL(BASE_URL.url+"/qrcode/","初始化URL"),
    STATUS_NOTIFY_URL(BASE_URL.url+"/webwxstatusnotify?lang=zh_CN&pass_ticket=%s","微信状态通知"),
    LOGIN_URL(BASE_URL.url+"/cgi-bin/mmwebwx-bin/login","登陆URL"),
    INIT_URL("%s/webwxinit?r=%s&pass_ticket=%s","初始化URL"),
    SYNC_CHECK_URL("/synccheck","检查心跳URL"),
    WEB_WX_SYNC_URL("%s/webwxsync?sid=%s&skey=%s&pass_ticket=%s","web微信消息同步URL"),
    WEB_WX_GET_CONTACT("%s/webwxgetcontact","web微信获取联系人信息URL"),
    WEB_WX_SEND_MSG("%s/webwxsendmsg","发送消息URL"),
    WEB_WX_UPLOAD_MEDIA("%s/webwxuploadmedia?f=json", "上传文件到服务器"),
    WEB_WX_GET_MSG_IMG("%s/webwxgetmsgimg", "下载图片消息"),
    WEB_WX_GET_VOICE("%s/webwxgetvoice", "下载语音消息"),
    WEB_WX_GET_VIEDO("%s/webwxgetvideo", "下载语音消息"),
    WEB_WX_PUSH_LOGIN("%s/webwxpushloginurl", "不扫码登陆"),
    WEB_WX_LOGOUT("%s/webwxlogout", "退出微信"),
    WEB_WX_BATCH_GET_CONTACT("%s/webwxbatchgetcontact?type=ex&r=%s&lang=zh_CN&pass_ticket=%s", "查询群信息"),
   WEB_WX_REMARKNAME("%s/webwxoplog?lang=zh_CN&pass_ticket=%s", "修改好友备注"),
    WEB_WX_VERIFYUSER("%s/webwxverifyuser?r=%s&lang=zh_CN&pass_ticket=%s", "被动添加好友"),
    WEB_WX_GET_MEDIA("%s/webwxgetmedia", "下载文件")
    ;
    private String url;
    private String msg;
    URLEnum(String url, String msg) {
        this.url = url;
        this.msg = msg;
    }
    public String getUrl() {
        return url;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/VerifyFriendEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.xmzs.common.wechat.utils.enums;
/**
 * ç¡®è®¤æ·»åŠ å¥½å‹Enum
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´6月29日 ä¸‹åˆ9:47:14
 * @version 1.0
 *
 */
public enum VerifyFriendEnum {
   ADD(2, "添加"),
   ACCEPT(3, "接受");
   private int code;
   private String desc;
   private VerifyFriendEnum(int code, String desc) {
      this.code = code;
      this.desc = desc;
   }
   public int getCode() {
      return code;
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/parameters/BaseParaEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.xmzs.common.wechat.utils.enums.parameters;
/**
 *
 * åŸºæœ¬è¯·æ±‚参数
 * 1. webWxInit      åˆå§‹åŒ–
 * 2. wxStatusNotify å¾®ä¿¡çŠ¶æ€é€šçŸ¥
 *
 * <p>
 * Created by xiaoxiaomo on 2017/5/7.
 */
public enum BaseParaEnum {
    Uin("Uin", "wxuin"),
    Sid("Sid", "wxsid"),
    Skey("Skey", "skey"),
    DeviceID("DeviceID", "pass_ticket");
    private String para;
    private String value;
    BaseParaEnum(String para, String value) {
        this.para = para;
        this.value = value;
    }
    public String para() {
        return para;
    }
    public Object value() {
        return value;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/parameters/LoginParaEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.xmzs.common.wechat.utils.enums.parameters;
/**
 * ç™»é™†
 * <p>
 * Created by xiaoxiaomo on 2017/5/7.
 */
public enum LoginParaEnum {
    LOGIN_ICON("loginicon", "true"),
    UUID("uuid", ""),
    TIP("tip", "0"),
    R("r", ""),
    _1("_", "");
    private String para;
    private String value;
    LoginParaEnum(String para, String value) {
        this.para = para;
        this.value = value;
    }
    public String para() {
        return para;
    }
    public String value() {
        return value;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/parameters/StatusNotifyParaEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.xmzs.common.wechat.utils.enums.parameters;
/**
 * çŠ¶æ€é€šçŸ¥
 * <p>
 * Created by xiaoxiaomo on 2017/5/7.
 */
public enum StatusNotifyParaEnum {
    CODE("Code", "3"),
    FROM_USERNAME("FromUserName", ""),
    TO_USERNAME("ToUserName", ""),
    CLIENT_MSG_ID("ClientMsgId", ""); //时间戳
    private String para;
    private String value;
    StatusNotifyParaEnum(String para, String value) {
        this.para = para;
        this.value = value;
    }
    public String para() {
        return para;
    }
    public String value() {
        return value;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/enums/parameters/UUIDParaEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.xmzs.common.wechat.utils.enums.parameters;
/**
 * UUID
 * <p>
 * Created by xiaoxiaomo on 2017/5/7.
 */
public enum UUIDParaEnum {
    APP_ID("appid", "wx782c26e4c19acffb"),
    FUN("fun", "new"),
    LANG("lang", "zh_CN"),
    REDIRECT_URL("redirect_uri",
            "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop"),
    _1("_", "时间戳");
    private String para;
    private String value;
    UUIDParaEnum(String para, String value) {
        this.para = para;
        this.value = value;
    }
    public String para() {
        return para;
    }
    public String value() {
        return value;
    }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/tools/CommonTools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,243 @@
package com.xmzs.common.wechat.utils.tools;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vdurmont.emoji.EmojiParser;
import com.xmzs.common.wechat.utils.Config;
import com.xmzs.common.wechat.utils.enums.OsNameEnum;
/**
 * å¸¸ç”¨å·¥å…·ç±»
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月8日 ä¸‹åˆ10:59:55
 * @version 1.0
 *
 */
public class CommonTools {
   public static boolean printQr(String qrPath) {
      switch (Config.getOsNameEnum()) {
      case WINDOWS:
         if (Config.getOsNameEnum().equals(OsNameEnum.WINDOWS)) {
            Runtime runtime = Runtime.getRuntime();
            try {
               runtime.exec("cmd /c start " + qrPath);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
         break;
      case MAC:
         if (Config.getOsNameEnum().equals(OsNameEnum.MAC)) {
            Runtime runtime = Runtime.getRuntime();
            try {
               runtime.exec("open " + qrPath);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
         break;
      default:
         break;
      }
      return true;
   }
   public static boolean clearScreen() {
      switch (Config.getOsNameEnum()) {
      case WINDOWS:
         if (Config.getOsNameEnum().equals(OsNameEnum.WINDOWS)) {
            Runtime runtime = Runtime.getRuntime();
            try {
               runtime.exec("cmd /c " + "cls");
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
         break;
      default:
         break;
      }
      return true;
   }
   /**
    * æ­£åˆ™è¡¨è¾¾å¼å¤„理工具
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月9日 ä¸Šåˆ12:27:10
    * @return
    */
   public static Matcher getMatcher(String regEx, String text) {
      Pattern pattern = Pattern.compile(regEx);
      Matcher matcher = pattern.matcher(text);
      return matcher;
   }
   /**
    * xml解析器
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月9日 ä¸‹åˆ6:24:25
    * @param text
    * @return
    */
   public static Document xmlParser(String text) {
      Document doc = null;
      StringReader sr = new StringReader(text);
      InputSource is = new InputSource(sr);
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      try {
         DocumentBuilder builder = factory.newDocumentBuilder();
         doc = builder.parse(is);
      } catch (Exception e) {
         e.printStackTrace();
      }
      return doc;
   }
   public static JSONObject structFriendInfo(JSONObject userObj) {
      Map<String, Object> friendInfoTemplate = new HashMap<String, Object>();
      friendInfoTemplate.put("UserName", "");
      friendInfoTemplate.put("City", "");
      friendInfoTemplate.put("DisplayName", "");
      friendInfoTemplate.put("PYQuanPin", "");
      friendInfoTemplate.put("RemarkPYInitial", "");
      friendInfoTemplate.put("Province", "");
      friendInfoTemplate.put("KeyWord", "");
      friendInfoTemplate.put("RemarkName", "");
      friendInfoTemplate.put("PYInitial", "");
      friendInfoTemplate.put("EncryChatRoomId", "");
      friendInfoTemplate.put("Alias", "");
      friendInfoTemplate.put("Signature", "");
      friendInfoTemplate.put("NickName", "");
      friendInfoTemplate.put("RemarkPYQuanPin", "");
      friendInfoTemplate.put("HeadImgUrl", "");
      friendInfoTemplate.put("UniFriend", 0);
      friendInfoTemplate.put("Sex", 0);
      friendInfoTemplate.put("AppAccountFlag", 0);
      friendInfoTemplate.put("VerifyFlag", 0);
      friendInfoTemplate.put("ChatRoomId", 0);
      friendInfoTemplate.put("HideInputBarFlag", 0);
      friendInfoTemplate.put("AttrStatus", 0);
      friendInfoTemplate.put("SnsFlag", 0);
      friendInfoTemplate.put("MemberCount", 0);
      friendInfoTemplate.put("OwnerUin", 0);
      friendInfoTemplate.put("ContactFlag", 0);
      friendInfoTemplate.put("Uin", 0);
      friendInfoTemplate.put("StarFriend", 0);
      friendInfoTemplate.put("Statues", 0);
      friendInfoTemplate.put("MemberList", new ArrayList<Object>());
      JSONObject r = new JSONObject();
      Set<String> keySet = friendInfoTemplate.keySet();
      for (String key : keySet) {
         if (userObj.containsKey(key)) {
            r.put(key, userObj.get(key));
         } else {
            r.put(key, friendInfoTemplate.get(key));
         }
      }
      return r;
   }
   public static String getSynckey(JSONObject obj) {
      JSONArray obj2 = obj.getJSONArray("List");
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < obj2.size(); i++) {
         JSONObject obj3 = (JSONObject) JSON.toJSON(obj2.get(i));
         sb.append(obj3.get("Val") + "|");
      }
      return sb.substring(0, sb.length() - 1); // 656159784|656159911|656159873|1491905341
   }
   public static JSONObject searchDictList(List<JSONObject> list, String key, String value) {
      JSONObject r = null;
      for (JSONObject i : list) {
         if (i.getString(key).equals(value)) {
            r = i;
            break;
         }
      }
      return r;
   }
   /**
    * å¤„理emoji表情
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月23日 ä¸‹åˆ2:39:04
    * @param d
    * @param k
    */
   public static void emojiFormatter(JSONObject d, String k) {
      Matcher matcher = getMatcher("<span class=\"emoji emoji(.{1,10})\"></span>", d.getString(k));
      StringBuilder sb = new StringBuilder();
      String content = d.getString(k);
      int lastStart = 0;
      while (matcher.find()) {
         String str = matcher.group(1);
         if (str.length() == 6) {
         } else if (str.length() == 10) {
         } else {
            str = "&#x" + str + ";";
            String tmp = content.substring(lastStart, matcher.start());
            sb.append(tmp + str);
            lastStart = matcher.end();
         }
      }
      if (lastStart < content.length()) {
         sb.append(content.substring(lastStart));
      }
      if (sb.length() != 0) {
         d.put(k, EmojiParser.parseToUnicode(sb.toString()));
      } else {
         d.put(k, content);
      }
   }
   /**
    * æ¶ˆæ¯æ ¼å¼åŒ–
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月23日 ä¸‹åˆ4:19:08
    * @param d
    * @param k
    */
   public static void msgFormatter(JSONObject d, String k) {
      d.put(k, d.getString(k).replace("<br/>", "\n"));
      emojiFormatter(d, k);
      // TODO ä¸Žemoji表情有部分兼容问题,目前暂未处理解码处理 d.put(k,
      // StringEscapeUtils.unescapeHtml4(d.getString(k)));
   }
}
ruoyi-common/ruoyi-common-wechat/src/main/java/com/xmzs/common/wechat/utils/tools/DownloadTools.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package com.xmzs.common.wechat.utils.tools;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.xmzs.common.wechat.beans.BaseMsg;
import com.xmzs.common.wechat.core.Core;
import com.xmzs.common.wechat.utils.MyHttpClient;
import com.xmzs.common.wechat.utils.enums.MsgTypeEnum;
import com.xmzs.common.wechat.utils.enums.URLEnum;
/**
 * ä¸‹è½½å·¥å…·ç±»
 *
 * @author https://github.com/yaphone
 * @date åˆ›å»ºæ—¶é—´ï¼š2017å¹´4月21日 ä¸‹åˆ11:18:46
 * @version 1.0
 *
 */
public class DownloadTools {
   private static Logger logger = Logger.getLogger("DownloadTools");
   private static Core core = Core.getInstance();
   private static MyHttpClient myHttpClient = core.getMyHttpClient();
   /**
    * å¤„理下载任务
    *
    * @author https://github.com/yaphone
    * @date 2017å¹´4月21日 ä¸‹åˆ11:00:25
    * @param url
    * @param msgId
    * @param path
    * @return
    */
   public static Object getDownloadFn(BaseMsg msg, String type, String path) {
      Map<String, String> headerMap = new HashMap<String, String>();
      List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
      String url = "";
      if (type.equals(MsgTypeEnum.PIC.getType())) {
         url = String.format(URLEnum.WEB_WX_GET_MSG_IMG.getUrl(), (String) core.getLoginInfo().get("url"));
      } else if (type.equals(MsgTypeEnum.VOICE.getType())) {
         url = String.format(URLEnum.WEB_WX_GET_VOICE.getUrl(), (String) core.getLoginInfo().get("url"));
      } else if (type.equals(MsgTypeEnum.VIEDO.getType())) {
         headerMap.put("Range", "bytes=0-");
         url = String.format(URLEnum.WEB_WX_GET_VIEDO.getUrl(), (String) core.getLoginInfo().get("url"));
      } else if (type.equals(MsgTypeEnum.MEDIA.getType())) {
         headerMap.put("Range", "bytes=0-");
         url = String.format(URLEnum.WEB_WX_GET_MEDIA.getUrl(), (String) core.getLoginInfo().get("fileUrl"));
         params.add(new BasicNameValuePair("sender", msg.getFromUserName()));
         params.add(new BasicNameValuePair("mediaid", msg.getMediaId()));
         params.add(new BasicNameValuePair("filename", msg.getFileName()));
      }
      params.add(new BasicNameValuePair("msgid", msg.getNewMsgId()));
      params.add(new BasicNameValuePair("skey", (String) core.getLoginInfo().get("skey")));
      HttpEntity entity = myHttpClient.doGet(url, params, true, headerMap);
      try {
         OutputStream out = new FileOutputStream(path);
         byte[] bytes = EntityUtils.toByteArray(entity);
         out.write(bytes);
         out.flush();
         out.close();
         // Tools.printQr(path);
      } catch (Exception e) {
         logger.info(e.getMessage());
         return false;
      }
      return null;
   };
}
ruoyi-modules/pom.xml
@@ -14,7 +14,9 @@
        <module>ruoyi-demo</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-job</module>
        <module>ruoyi-midjourney</module>
        <module>ruoyi-system</module>
        <module>ruoyi-live</module>
    </modules>
    <artifactId>ruoyi-modules</artifactId>
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>live-chat-client-commons</artifactId>
        <version>1.0.0</version>
    </parent>
    <packaging>jar</packaging>
    <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>
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/constant/Constants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
/*
 * 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 {
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/exception/BaseException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/IBaseConnectionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
/*
 * 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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/IBaseMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,149 @@
/*
 * 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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/IDanmuMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
/*
 * 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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/IEnterRoomMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/IGiftMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/ILikeMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
/*
 * 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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/listener/ISuperChatMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/BaseCmdMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
/*
 * 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> {
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/BaseMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
/*
 * 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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/ICmdMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
/*
 * 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();
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/IDanmuMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
/*
 * 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();
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/IEnterRoomMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/IGiftMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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();
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/ILikeMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/IMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.commons.base.msg;
import java.io.Serializable;
/**
 * @author mjz
 * @date 2023/8/26
 */
public interface IMsg extends Serializable {
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-base/src/main/java/tech/ordinaryroad/live/chat/client/commons/base/msg/ISuperChatMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-client/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>live-chat-client-commons</artifactId>
        <version>1.0.0</version>
    </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>com.xmzs</groupId>
            <artifactId>live-chat-client-commons-base</artifactId>
        </dependency>
        <dependency>
            <groupId>com.xmzs</groupId>
            <artifactId>live-chat-client-commons-util</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-client/src/main/java/tech/ordinaryroad/live/chat/client/commons/client/BaseLiveChatClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,200 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-client/src/main/java/tech/ordinaryroad/live/chat/client/commons/client/IBaseLiveChatClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
/*
 * 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);
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-client/src/main/java/tech/ordinaryroad/live/chat/client/commons/client/config/BaseLiveChatClientConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,139 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-client/src/main/java/tech/ordinaryroad/live/chat/client/commons/client/enums/ClientStatusEnums.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
/*
 * 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;
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-util/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<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>com.xmzs</groupId>
        <artifactId>live-chat-client-commons</artifactId>
        <version>1.0.0</version>
    </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>
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-util/src/main/java/tech/ordinaryroad/live/chat/client/commons/util/OrLiveChatCookieUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-util/src/main/java/tech/ordinaryroad/live/chat/client/commons/util/OrLiveChatNumberUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
/*
 * 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));
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-util/src/main/java/tech/ordinaryroad/live/chat/client/commons/util/OrLiveChatReflectUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/live-chat-client-commons-util/src/main/java/tech/ordinaryroad/live/chat/client/commons/util/OrLocalDateTimeUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-commons/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>ruoyi-live</artifactId>
        <version>1.0.0</version>
    </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>
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty-client/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>live-chat-client-servers</artifactId>
        <version>1.0.0</version>
    </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>com.xmzs</groupId>
            <artifactId>live-chat-client-commons-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.xmzs</groupId>
            <artifactId>live-chat-client-servers-netty</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty-client/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/client/base/BaseNettyClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,349 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty-client/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/client/config/BaseNettyClientConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
/*
 * 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;
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty-client/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/client/handler/BaseNettyClientBinaryFrameHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty-client/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/client/handler/BaseNettyClientConnectionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>live-chat-client-servers</artifactId>
        <version>1.0.0</version>
    </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>com.xmzs</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>
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/frame/base/BaseBinaryWebSocketFrame.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/handler/base/BaseBinaryFrameHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/live-chat-client-servers-netty/src/main/java/tech/ordinaryroad/live/chat/client/servers/netty/handler/base/BaseConnectionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,168 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-client-servers/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>ruoyi-live</artifactId>
        <version>1.0.0</version>
    </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>
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
<!--
  ~ 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>com.xmzs</groupId>
        <artifactId>live-chat-clients</artifactId>
        <version>1.0.0</version>
    </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>com.xmzs</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>
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/api/BilibiliApis.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,247 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/api/request/BilibiliLikeReportV3Request.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/api/request/BilibiliSendMsgRequest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/client/BilibiliLiveChatClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
/*
 * 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();
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/config/BilibiliLiveChatClientConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/constant/BilibiliCmdEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,143 @@
/*
 * 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;
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/constant/OperationEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/constant/ProtoverEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/listener/IBilibiliConnectionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
/*
 * 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> {
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/listener/IBilibiliMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
/*
 * 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
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/AuthMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/AuthReplyMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/DanmuMsgMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/HeartbeatMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/HeartbeatReplyMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/InteractWordMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,396 @@
/*
 * 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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/LikeInfoV3ClickMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,158 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/SendGiftMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,351 @@
/*
 * 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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/SendSmsReplyMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/SuperChatMessageMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,202 @@
/*
 * 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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/base/BaseBilibiliCmdMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/base/BaseBilibiliMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/base/IBilibiliMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
/*
 * 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();
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/msg/dto/MedalInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/frame/AuthWebSocketFrame.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/frame/HeartbeatWebSocketFrame.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/frame/base/BaseBilibiliWebSocketFrame.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/frame/factory/BilibiliWebSocketFrameFactory.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/handler/BilibiliBinaryFrameHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,153 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/netty/handler/BilibiliConnectionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
/*
 * 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();
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/Dm_v2Proto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
/*
 * 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)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/Dm_v2_20Proto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
/*
 * 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)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/dm_v2.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,610 @@
/*
 * 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;
  }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/dm_v2OrBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
/*
 * 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();
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/dm_v2_20.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,565 @@
/*
 * 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;
  }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/protobuf/dm_v2_20OrBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
// 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();
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/util/BilibiliCodecUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,259 @@
/*
 * 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();
            }
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/resources/proto/dm_v2.proto
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
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;
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/resources/proto/dm_v2_20.proto
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
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;
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/test/java/tech/ordinaryroad/live/chat/client/bilibili/api/BilibiliApisTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/test/java/tech/ordinaryroad/live/chat/client/bilibili/client/BilibiliLiveChatClientTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
/*
 * 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();
            }
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
<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>com.xmzs</groupId>
        <artifactId>live-chat-clients</artifactId>
        <version>1.0.0</version>
    </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>com.xmzs</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>
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/ClientModeExample.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
/*
 * 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));
//            }
//        });
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/api/DouyinApis.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/client/DouyinLiveChatClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,174 @@
/*
 * 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);
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/config/DouyinLiveChatClientConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
/*
 * 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/";
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/constant/DouyinCmdEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/listener/IDouyinConnectionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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> {
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/listener/IDouyinMsgListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
/*
 * 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> {
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinDanmuMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinEnterRoomMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
/*
 * 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());
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinGiftMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinLikeMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
/*
 * 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();
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/base/IDouyinCmdMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.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> {
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/base/IDouyinMsg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
/*
 * MIT License
 *
 * Copyright (c) 2023 OrdinaryRoad
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package tech.ordinaryroad.live.chat.client.douyin.msg.base;
import tech.ordinaryroad.live.chat.client.commons.base.msg.IMsg;
/**
 * @author mjz
 * @date 2024/1/2
 */
public interface IDouyinMsg extends IMsg {
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/netty/handler/DouyinBinaryFrameHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
/*
 * 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);
        }
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/netty/handler/DouyinConnectionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
/*
 * 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;
    }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/Douyin_cmd_msgProto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
/*
 * 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)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/Douyin_webcast_chat_message_msgProto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
/*
 * 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_webcast_chat_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
public final class Douyin_webcast_chat_message_msgProto {
  private Douyin_webcast_chat_message_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_webcast_chat_message_msg_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_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%douyin_webcast_chat_message_msg.proto\022" +
      "2tech.ordinaryroad.live.chat.client.douy" +
      "in.protobuf\032\014Common.proto\032\nUser.proto\032\013I" +
      "mage.proto\"\300\003\n\037douyin_webcast_chat_messa" +
      "ge_msg\022\027\n\006common\030\001 \001(\0132\007.Common\022\023\n\004user\030" +
      "\002 \001(\0132\005.User\022\017\n\007content\030\003 \001(\t\022\031\n\021visible" +
      "_to_sender\030\004 \001(\010\022 \n\020background_image\030\005 \001" +
      "(\0132\006.Image\022\036\n\026full_screen_text_color\030\006 \001" +
      "(\t\022#\n\023background_image_v2\030\007 \001(\0132\006.Image\022" +
      "\032\n\ngift_image\030\n \001(\0132\006.Image\022\024\n\014agree_msg" +
      "_id\030\013 \001(\004\022\026\n\016priority_level\030\014 \001(\r\022\022\n\neve" +
      "nt_time\030\017 \001(\004\022\023\n\013send_review\030\020 \001(\010\022\025\n\rfr" +
      "om_intercom\030\021 \001(\010\022\037\n\027intercom_hide_user_" +
      "card\030\022 \001(\010\022\017\n\007chat_by\030\024 \001(\t\022 \n\030individua" +
      "l_chat_priority\030\025 \001(\rBb\n2tech.ordinaryro" +
      "ad.live.chat.client.douyin.protobufB$Dou" +
      "yin_webcast_chat_message_msgProtoP\001\242\002\003GP" +
      "Bb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.getDescriptor(),
        });
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_descriptor,
        new java.lang.String[] { "Common", "User", "Content", "VisibleToSender", "BackgroundImage", "FullScreenTextColor", "BackgroundImageV2", "GiftImage", "AgreeMsgId", "PriorityLevel", "EventTime", "SendReview", "FromIntercom", "IntercomHideUserCard", "ChatBy", "IndividualChatPriority", });
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.getDescriptor();
  }
  // @@protoc_insertion_point(outer_class_scope)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/Douyin_webcast_gift_message_msgProto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
/*
 * 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_webcast_gift_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
public final class Douyin_webcast_gift_message_msgProto {
  private Douyin_webcast_gift_message_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_webcast_gift_message_msg_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_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%douyin_webcast_gift_message_msg.proto\022" +
      "2tech.ordinaryroad.live.chat.client.douy" +
      "in.protobuf\032\014Common.proto\032\nUser.proto\032\020T" +
      "extEffect.proto\032\nText.proto\032\024GiftIMPrior" +
      "ity.proto\032\020GiftStruct.proto\032\026PublicAreaC" +
      "ommon.proto\"\277\006\n\037douyin_webcast_gift_mess" +
      "age_msg\022\027\n\006common\030\001 \001(\0132\007.Common\022\024\n\014long" +
      "_gift_id\030\002 \001(\004\022\030\n\020fan_ticket_count\030\003 \001(\004" +
      "\022\023\n\013group_count\030\004 \001(\004\022\024\n\014repeat_count\030\005 " +
      "\001(\004\022\023\n\013combo_count\030\006 \001(\004\022\023\n\004user\030\007 \001(\0132\005" +
      ".User\022\026\n\007to_user\030\010 \001(\0132\005.User\022\022\n\nrepeat_" +
      "end\030\t \001(\r\022 \n\013text_effect\030\n \001(\0132\013.TextEff" +
      "ect\022\020\n\010group_id\030\013 \001(\004\022\030\n\020income_taskgift" +
      "s\030\014 \001(\004\022\035\n\025room_fan_ticket_count\030\r \001(\004\022!" +
      "\n\010priority\030\016 \001(\0132\017.GiftIMPriority\022\031\n\004gif" +
      "t\030\017 \001(\0132\013.GiftStruct\022\016\n\006log_id\030\020 \001(\t\022\021\n\t" +
      "send_type\030\021 \001(\004\022-\n\022public_area_common\030\022 " +
      "\001(\0132\021.PublicAreaCommon\022 \n\021tray_display_t" +
      "ext\030\023 \001(\0132\005.Text\022\036\n\026banned_display_effec" +
      "ts\030\024 \001(\004\022\030\n\020display_for_self\030\031 \001(\010\022\032\n\022in" +
      "teract_gift_info\030\032 \001(\t\022\025\n\rdiy_item_info\030" +
      "\033 \001(\t\022\032\n\022min_asset_set_list\030\034 \003(\004\022\023\n\013tot" +
      "al_count\030\035 \001(\004\022\032\n\022client_gift_source\030\036 \001" +
      "(\r\022\030\n\020to_user_ids_list\030  \003(\004\022\022\n\nsend_tim" +
      "et\030! \001(\004\022\036\n\026force_display_effectst\030\" \001(\004" +
      "\022\020\n\010trace_id\030# \001(\t\022\031\n\021effect_display_ts\030" +
      "$ \001(\004Bb\n2tech.ordinaryroad.live.chat.cli" +
      "ent.douyin.protobufB$Douyin_webcast_gift" +
      "_message_msgProtoP\001\242\002\003GPBb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.getDescriptor(),
        });
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_descriptor,
        new java.lang.String[] { "Common", "LongGiftId", "FanTicketCount", "GroupCount", "RepeatCount", "ComboCount", "User", "ToUser", "RepeatEnd", "TextEffect", "GroupId", "IncomeTaskgifts", "RoomFanTicketCount", "Priority", "Gift", "LogId", "SendType", "PublicAreaCommon", "TrayDisplayText", "BannedDisplayEffects", "DisplayForSelf", "InteractGiftInfo", "DiyItemInfo", "MinAssetSetList", "TotalCount", "ClientGiftSource", "ToUserIdsList", "SendTimet", "ForceDisplayEffectst", "TraceId", "EffectDisplayTs", });
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.getDescriptor();
  }
  // @@protoc_insertion_point(outer_class_scope)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/Douyin_webcast_member_message_msgProto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
/*
 * 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_webcast_member_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
public final class Douyin_webcast_member_message_msgProto {
  private Douyin_webcast_member_message_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_webcast_member_message_msg_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_fieldAccessorTable;
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_BuriedPointMapEntry_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_BuriedPointMapEntry_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\'douyin_webcast_member_message_msg.prot" +
      "o\0222tech.ordinaryroad.live.chat.client.do" +
      "uyin.protobuf\032\014Common.proto\032\nUser.proto\032" +
      "\013Image.proto\032\nText.proto\"\203\005\n!douyin_webc" +
      "ast_member_message_msg\022\027\n\006common\030\001 \001(\0132\007" +
      ".Common\022\023\n\004user\030\002 \001(\0132\005.User\022\023\n\013memberCo" +
      "unt\030\003 \001(\004\022\027\n\010operator\030\004 \001(\0132\005.User\022\024\n\014is" +
      "SetToAdmin\030\005 \001(\010\022\021\n\tisTopUser\030\006 \001(\010\022\021\n\tr" +
      "ankScore\030\007 \001(\003\022\021\n\ttopUserNo\030\010 \001(\003\022\021\n\tent" +
      "erType\030\t \001(\003\022\016\n\006action\030\n \001(\003\022\031\n\021actionDe" +
      "scription\030\013 \001(\t\022\016\n\006userId\030\014 \001(\003\022\016\n\006popSt" +
      "r\030\016 \001(\t\022\037\n\017backgroundImage\030\020 \001(\0132\006.Image" +
      "\022!\n\021backgroundImageV2\030\021 \001(\0132\006.Image\022 \n\021a" +
      "nchorDisplayText\030\022 \001(\0132\005.Text\022\030\n\020userEnt" +
      "erTipType\030\024 \001(\003\022\032\n\022anchorEnterTipType\030\025 " +
      "\001(\003\022\201\001\n\016buriedPointMap\030\026 \003(\0132i.tech.ordi" +
      "naryroad.live.chat.client.douyin.protobu" +
      "f.douyin_webcast_member_message_msg.Buri" +
      "edPointMapEntry\0325\n\023BuriedPointMapEntry\022\013" +
      "\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001Bd\n2tech.o" +
      "rdinaryroad.live.chat.client.douyin.prot" +
      "obufB&Douyin_webcast_member_message_msgP" +
      "rotoP\001\242\002\003GPBb\006proto3"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.getDescriptor(),
          tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.getDescriptor(),
        });
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_descriptor,
        new java.lang.String[] { "Common", "User", "MemberCount", "Operator", "IsSetToAdmin", "IsTopUser", "RankScore", "TopUserNo", "EnterType", "Action", "ActionDescription", "UserId", "PopStr", "BackgroundImage", "BackgroundImageV2", "AnchorDisplayText", "UserEnterTipType", "AnchorEnterTipType", "BuriedPointMap", });
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_BuriedPointMapEntry_descriptor =
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_descriptor.getNestedTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_BuriedPointMapEntry_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_member_message_msg_BuriedPointMapEntry_descriptor,
        new java.lang.String[] { "Key", "Value", });
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.getDescriptor();
    tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.getDescriptor();
  }
  // @@protoc_insertion_point(outer_class_scope)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/Douyin_websocket_frameProto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
/*
 * 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_websocket_frame.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
public final class Douyin_websocket_frameProto {
  private Douyin_websocket_frameProto() {}
  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_websocket_frame_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_fieldAccessorTable;
  static final com.google.protobuf.Descriptors.Descriptor
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_HeadersListEntry_descriptor;
  static final
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_HeadersListEntry_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\034douyin_websocket_frame.proto\0222tech.ord" +
      "inaryroad.live.chat.client.douyin.protob" +
      "uf\"\301\002\n\026douyin_websocket_frame\022\016\n\006seq_id\030" +
      "\001 \001(\004\022\016\n\006log_id\030\002 \001(\004\022\017\n\007service\030\003 \001(\004\022\016" +
      "\n\006method\030\004 \001(\004\022q\n\014headers_list\030\005 \003(\0132[.t" +
      "ech.ordinaryroad.live.chat.client.douyin" +
      ".protobuf.douyin_websocket_frame.Headers" +
      "ListEntry\022\030\n\020payload_encoding\030\006 \001(\t\022\024\n\014p" +
      "ayload_type\030\007 \001(\t\022\017\n\007payload\030\010 \001(\014\0322\n\020He" +
      "adersListEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001" +
      "(\t:\0028\001BY\n2tech.ordinaryroad.live.chat.cl" +
      "ient.douyin.protobufB\033Douyin_websocket_f" +
      "rameProtoP\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_websocket_frame_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_descriptor,
        new java.lang.String[] { "SeqId", "LogId", "Service", "Method", "HeadersList", "PayloadEncoding", "PayloadType", "Payload", });
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_HeadersListEntry_descriptor =
      internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_descriptor.getNestedTypes().get(0);
    internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_HeadersListEntry_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_websocket_frame_HeadersListEntry_descriptor,
        new java.lang.String[] { "Key", "Value", });
  }
  // @@protoc_insertion_point(outer_class_scope)
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_cmd_msg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1122 @@
/*
 * 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;
import tech.ordinaryroad.live.chat.client.douyin.constant.DouyinCmdEnum;
import tech.ordinaryroad.live.chat.client.douyin.msg.base.IDouyinCmdMsg;
/**
 * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg}
 */
public final class douyin_cmd_msg extends
    com.google.protobuf.GeneratedMessageV3 implements
    // @@protoc_insertion_point(message_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)
    douyin_cmd_msgOrBuilder, IDouyinCmdMsg {
  @Override
  public String getCmd() {
    return getMethod();
  }
  @Override
  public void setCmd(String cmd) {
    // ignore
    // method_ = cmd;
  }
  @Override
  public DouyinCmdEnum getCmdEnum() {
    return DouyinCmdEnum.getByName(getMethod());
  }
private static final long serialVersionUID = 0L;
  // Use douyin_cmd_msg.newBuilder() to construct.
  private douyin_cmd_msg(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
    super(builder);
  }
  private douyin_cmd_msg() {
    method_ = "";
    payload_ = com.google.protobuf.ByteString.EMPTY;
    wrdsSubKey_ = "";
  }
  @java.lang.Override
  @SuppressWarnings({"unused"})
  protected java.lang.Object newInstance(
      UnusedPrivateParameter unused) {
    return new douyin_cmd_msg();
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_cmd_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor;
  }
  @java.lang.Override
  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internalGetFieldAccessorTable() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_cmd_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.Builder.class);
  }
  public static final int METHOD_FIELD_NUMBER = 1;
  @SuppressWarnings("serial")
  private volatile java.lang.Object method_ = "";
  /**
   * <code>string method = 1;</code>
   * @return The method.
   */
  @java.lang.Override
  public java.lang.String getMethod() {
    java.lang.Object ref = method_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      method_ = s;
      return s;
    }
  }
  /**
   * <code>string method = 1;</code>
   * @return The bytes for method.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getMethodBytes() {
    java.lang.Object ref = method_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      method_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int PAYLOAD_FIELD_NUMBER = 2;
  private com.google.protobuf.ByteString payload_ = com.google.protobuf.ByteString.EMPTY;
  /**
   * <code>bytes payload = 2;</code>
   * @return The payload.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString getPayload() {
    return payload_;
  }
  public static final int MSG_ID_FIELD_NUMBER = 3;
  private long msgId_ = 0L;
  /**
   * <code>int64 msg_id = 3;</code>
   * @return The msgId.
   */
  @java.lang.Override
  public long getMsgId() {
    return msgId_;
  }
  public static final int MSG_TYPE_FIELD_NUMBER = 4;
  private int msgType_ = 0;
  /**
   * <code>int32 msg_type = 4;</code>
   * @return The msgType.
   */
  @java.lang.Override
  public int getMsgType() {
    return msgType_;
  }
  public static final int OFFSET_FIELD_NUMBER = 5;
  private long offset_ = 0L;
  /**
   * <code>int64 offset = 5;</code>
   * @return The offset.
   */
  @java.lang.Override
  public long getOffset() {
    return offset_;
  }
  public static final int NEED_WRDS_STORE_FIELD_NUMBER = 6;
  private boolean needWrdsStore_ = false;
  /**
   * <code>bool need_wrds_store = 6;</code>
   * @return The needWrdsStore.
   */
  @java.lang.Override
  public boolean getNeedWrdsStore() {
    return needWrdsStore_;
  }
  public static final int WRDS_VERSION_FIELD_NUMBER = 7;
  private long wrdsVersion_ = 0L;
  /**
   * <code>int64 wrds_version = 7;</code>
   * @return The wrdsVersion.
   */
  @java.lang.Override
  public long getWrdsVersion() {
    return wrdsVersion_;
  }
  public static final int WRDS_SUB_KEY_FIELD_NUMBER = 8;
  @SuppressWarnings("serial")
  private volatile java.lang.Object wrdsSubKey_ = "";
  /**
   * <code>string wrds_sub_key = 8;</code>
   * @return The wrdsSubKey.
   */
  @java.lang.Override
  public java.lang.String getWrdsSubKey() {
    java.lang.Object ref = wrdsSubKey_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      wrdsSubKey_ = s;
      return s;
    }
  }
  /**
   * <code>string wrds_sub_key = 8;</code>
   * @return The bytes for wrdsSubKey.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getWrdsSubKeyBytes() {
    java.lang.Object ref = wrdsSubKey_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      wrdsSubKey_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  private byte memoizedIsInitialized = -1;
  @java.lang.Override
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized == 1) return true;
    if (isInitialized == 0) return false;
    memoizedIsInitialized = 1;
    return true;
  }
  @java.lang.Override
  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(method_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, method_);
    }
    if (!payload_.isEmpty()) {
      output.writeBytes(2, payload_);
    }
    if (msgId_ != 0L) {
      output.writeInt64(3, msgId_);
    }
    if (msgType_ != 0) {
      output.writeInt32(4, msgType_);
    }
    if (offset_ != 0L) {
      output.writeInt64(5, offset_);
    }
    if (needWrdsStore_ != false) {
      output.writeBool(6, needWrdsStore_);
    }
    if (wrdsVersion_ != 0L) {
      output.writeInt64(7, wrdsVersion_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(wrdsSubKey_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 8, wrdsSubKey_);
    }
    getUnknownFields().writeTo(output);
  }
  @java.lang.Override
  public int getSerializedSize() {
    int size = memoizedSize;
    if (size != -1) return size;
    size = 0;
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(method_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, method_);
    }
    if (!payload_.isEmpty()) {
      size += com.google.protobuf.CodedOutputStream
        .computeBytesSize(2, payload_);
    }
    if (msgId_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt64Size(3, msgId_);
    }
    if (msgType_ != 0) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt32Size(4, msgType_);
    }
    if (offset_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt64Size(5, offset_);
    }
    if (needWrdsStore_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(6, needWrdsStore_);
    }
    if (wrdsVersion_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeInt64Size(7, wrdsVersion_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(wrdsSubKey_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, wrdsSubKey_);
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSize = size;
    return size;
  }
  @java.lang.Override
  public boolean equals(final java.lang.Object obj) {
    if (obj == this) {
     return true;
    }
    if (!(obj instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)) {
      return super.equals(obj);
    }
    tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg other = (tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg) obj;
    if (!getMethod()
        .equals(other.getMethod())) return false;
    if (!getPayload()
        .equals(other.getPayload())) return false;
    if (getMsgId()
        != other.getMsgId()) return false;
    if (getMsgType()
        != other.getMsgType()) return false;
    if (getOffset()
        != other.getOffset()) return false;
    if (getNeedWrdsStore()
        != other.getNeedWrdsStore()) return false;
    if (getWrdsVersion()
        != other.getWrdsVersion()) return false;
    if (!getWrdsSubKey()
        .equals(other.getWrdsSubKey())) return false;
    if (!getUnknownFields().equals(other.getUnknownFields())) return false;
    return true;
  }
  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    hash = (37 * hash) + METHOD_FIELD_NUMBER;
    hash = (53 * hash) + getMethod().hashCode();
    hash = (37 * hash) + PAYLOAD_FIELD_NUMBER;
    hash = (53 * hash) + getPayload().hashCode();
    hash = (37 * hash) + MSG_ID_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getMsgId());
    hash = (37 * hash) + MSG_TYPE_FIELD_NUMBER;
    hash = (53 * hash) + getMsgType();
    hash = (37 * hash) + OFFSET_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getOffset());
    hash = (37 * hash) + NEED_WRDS_STORE_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getNeedWrdsStore());
    hash = (37 * hash) + WRDS_VERSION_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getWrdsVersion());
    hash = (37 * hash) + WRDS_SUB_KEY_FIELD_NUMBER;
    hash = (53 * hash) + getWrdsSubKey().hashCode();
    hash = (29 * hash) + getUnknownFields().hashCode();
    memoizedHashCode = hash;
    return hash;
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      java.nio.ByteBuffer data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      java.nio.ByteBuffer data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseDelimitedWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input, extensionRegistry);
  }
  @java.lang.Override
  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder() {
    return DEFAULT_INSTANCE.toBuilder();
  }
  public static Builder newBuilder(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg prototype) {
    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
  }
  @java.lang.Override
  public Builder toBuilder() {
    return this == DEFAULT_INSTANCE
        ? new Builder() : new Builder().mergeFrom(this);
  }
  @java.lang.Override
  protected Builder newBuilderForType(
      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
      // @@protoc_insertion_point(builder_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msgOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_cmd_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor;
    }
    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_cmd_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.Builder.class);
    }
    // Construct using tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.newBuilder()
    private Builder() {
    }
    private Builder(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      super(parent);
    }
    @java.lang.Override
    public Builder clear() {
      super.clear();
      bitField0_ = 0;
      method_ = "";
      payload_ = com.google.protobuf.ByteString.EMPTY;
      msgId_ = 0L;
      msgType_ = 0;
      offset_ = 0L;
      needWrdsStore_ = false;
      wrdsVersion_ = 0L;
      wrdsSubKey_ = "";
      return this;
    }
    @java.lang.Override
    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_cmd_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_cmd_msg_descriptor;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg getDefaultInstanceForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.getDefaultInstance();
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg build() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg buildPartial() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg result = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg(this);
      if (bitField0_ != 0) { buildPartial0(result); }
      onBuilt();
      return result;
    }
    private void buildPartial0(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg result) {
      int from_bitField0_ = bitField0_;
      if (((from_bitField0_ & 0x00000001) != 0)) {
        result.method_ = method_;
      }
      if (((from_bitField0_ & 0x00000002) != 0)) {
        result.payload_ = payload_;
      }
      if (((from_bitField0_ & 0x00000004) != 0)) {
        result.msgId_ = msgId_;
      }
      if (((from_bitField0_ & 0x00000008) != 0)) {
        result.msgType_ = msgType_;
      }
      if (((from_bitField0_ & 0x00000010) != 0)) {
        result.offset_ = offset_;
      }
      if (((from_bitField0_ & 0x00000020) != 0)) {
        result.needWrdsStore_ = needWrdsStore_;
      }
      if (((from_bitField0_ & 0x00000040) != 0)) {
        result.wrdsVersion_ = wrdsVersion_;
      }
      if (((from_bitField0_ & 0x00000080) != 0)) {
        result.wrdsSubKey_ = wrdsSubKey_;
      }
    }
    @java.lang.Override
    public Builder clone() {
      return super.clone();
    }
    @java.lang.Override
    public Builder setField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.setField(field, value);
    }
    @java.lang.Override
    public Builder clearField(
        com.google.protobuf.Descriptors.FieldDescriptor field) {
      return super.clearField(field);
    }
    @java.lang.Override
    public Builder clearOneof(
        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
      return super.clearOneof(oneof);
    }
    @java.lang.Override
    public Builder setRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        int index, java.lang.Object value) {
      return super.setRepeatedField(field, index, value);
    }
    @java.lang.Override
    public Builder addRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.addRepeatedField(field, value);
    }
    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg) {
        return mergeFrom((tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }
    public Builder mergeFrom(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg other) {
      if (other == tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg.getDefaultInstance()) return this;
      if (!other.getMethod().isEmpty()) {
        method_ = other.method_;
        bitField0_ |= 0x00000001;
        onChanged();
      }
      if (other.getPayload() != com.google.protobuf.ByteString.EMPTY) {
        setPayload(other.getPayload());
      }
      if (other.getMsgId() != 0L) {
        setMsgId(other.getMsgId());
      }
      if (other.getMsgType() != 0) {
        setMsgType(other.getMsgType());
      }
      if (other.getOffset() != 0L) {
        setOffset(other.getOffset());
      }
      if (other.getNeedWrdsStore() != false) {
        setNeedWrdsStore(other.getNeedWrdsStore());
      }
      if (other.getWrdsVersion() != 0L) {
        setWrdsVersion(other.getWrdsVersion());
      }
      if (!other.getWrdsSubKey().isEmpty()) {
        wrdsSubKey_ = other.wrdsSubKey_;
        bitField0_ |= 0x00000080;
        onChanged();
      }
      this.mergeUnknownFields(other.getUnknownFields());
      onChanged();
      return this;
    }
    @java.lang.Override
    public final boolean isInitialized() {
      return true;
    }
    @java.lang.Override
    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              method_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00000001;
              break;
            } // case 10
            case 18: {
              payload_ = input.readBytes();
              bitField0_ |= 0x00000002;
              break;
            } // case 18
            case 24: {
              msgId_ = input.readInt64();
              bitField0_ |= 0x00000004;
              break;
            } // case 24
            case 32: {
              msgType_ = input.readInt32();
              bitField0_ |= 0x00000008;
              break;
            } // case 32
            case 40: {
              offset_ = input.readInt64();
              bitField0_ |= 0x00000010;
              break;
            } // case 40
            case 48: {
              needWrdsStore_ = input.readBool();
              bitField0_ |= 0x00000020;
              break;
            } // case 48
            case 56: {
              wrdsVersion_ = input.readInt64();
              bitField0_ |= 0x00000040;
              break;
            } // case 56
            case 66: {
              wrdsSubKey_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00000080;
              break;
            } // case 66
            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 java.lang.Object method_ = "";
    /**
     * <code>string method = 1;</code>
     * @return The method.
     */
    public java.lang.String getMethod() {
      java.lang.Object ref = method_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        method_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string method = 1;</code>
     * @return The bytes for method.
     */
    public com.google.protobuf.ByteString
        getMethodBytes() {
      java.lang.Object ref = method_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        method_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string method = 1;</code>
     * @param value The method to set.
     * @return This builder for chaining.
     */
    public Builder setMethod(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      method_ = value;
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>string method = 1;</code>
     * @return This builder for chaining.
     */
    public Builder clearMethod() {
      method_ = getDefaultInstance().getMethod();
      bitField0_ = (bitField0_ & ~0x00000001);
      onChanged();
      return this;
    }
    /**
     * <code>string method = 1;</code>
     * @param value The bytes for method to set.
     * @return This builder for chaining.
     */
    public Builder setMethodBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      method_ = value;
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    private com.google.protobuf.ByteString payload_ = com.google.protobuf.ByteString.EMPTY;
    /**
     * <code>bytes payload = 2;</code>
     * @return The payload.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString getPayload() {
      return payload_;
    }
    /**
     * <code>bytes payload = 2;</code>
     * @param value The payload to set.
     * @return This builder for chaining.
     */
    public Builder setPayload(com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      payload_ = value;
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }
    /**
     * <code>bytes payload = 2;</code>
     * @return This builder for chaining.
     */
    public Builder clearPayload() {
      bitField0_ = (bitField0_ & ~0x00000002);
      payload_ = getDefaultInstance().getPayload();
      onChanged();
      return this;
    }
    private long msgId_ ;
    /**
     * <code>int64 msg_id = 3;</code>
     * @return The msgId.
     */
    @java.lang.Override
    public long getMsgId() {
      return msgId_;
    }
    /**
     * <code>int64 msg_id = 3;</code>
     * @param value The msgId to set.
     * @return This builder for chaining.
     */
    public Builder setMsgId(long value) {
      msgId_ = value;
      bitField0_ |= 0x00000004;
      onChanged();
      return this;
    }
    /**
     * <code>int64 msg_id = 3;</code>
     * @return This builder for chaining.
     */
    public Builder clearMsgId() {
      bitField0_ = (bitField0_ & ~0x00000004);
      msgId_ = 0L;
      onChanged();
      return this;
    }
    private int msgType_ ;
    /**
     * <code>int32 msg_type = 4;</code>
     * @return The msgType.
     */
    @java.lang.Override
    public int getMsgType() {
      return msgType_;
    }
    /**
     * <code>int32 msg_type = 4;</code>
     * @param value The msgType to set.
     * @return This builder for chaining.
     */
    public Builder setMsgType(int value) {
      msgType_ = value;
      bitField0_ |= 0x00000008;
      onChanged();
      return this;
    }
    /**
     * <code>int32 msg_type = 4;</code>
     * @return This builder for chaining.
     */
    public Builder clearMsgType() {
      bitField0_ = (bitField0_ & ~0x00000008);
      msgType_ = 0;
      onChanged();
      return this;
    }
    private long offset_ ;
    /**
     * <code>int64 offset = 5;</code>
     * @return The offset.
     */
    @java.lang.Override
    public long getOffset() {
      return offset_;
    }
    /**
     * <code>int64 offset = 5;</code>
     * @param value The offset to set.
     * @return This builder for chaining.
     */
    public Builder setOffset(long value) {
      offset_ = value;
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }
    /**
     * <code>int64 offset = 5;</code>
     * @return This builder for chaining.
     */
    public Builder clearOffset() {
      bitField0_ = (bitField0_ & ~0x00000010);
      offset_ = 0L;
      onChanged();
      return this;
    }
    private boolean needWrdsStore_ ;
    /**
     * <code>bool need_wrds_store = 6;</code>
     * @return The needWrdsStore.
     */
    @java.lang.Override
    public boolean getNeedWrdsStore() {
      return needWrdsStore_;
    }
    /**
     * <code>bool need_wrds_store = 6;</code>
     * @param value The needWrdsStore to set.
     * @return This builder for chaining.
     */
    public Builder setNeedWrdsStore(boolean value) {
      needWrdsStore_ = value;
      bitField0_ |= 0x00000020;
      onChanged();
      return this;
    }
    /**
     * <code>bool need_wrds_store = 6;</code>
     * @return This builder for chaining.
     */
    public Builder clearNeedWrdsStore() {
      bitField0_ = (bitField0_ & ~0x00000020);
      needWrdsStore_ = false;
      onChanged();
      return this;
    }
    private long wrdsVersion_ ;
    /**
     * <code>int64 wrds_version = 7;</code>
     * @return The wrdsVersion.
     */
    @java.lang.Override
    public long getWrdsVersion() {
      return wrdsVersion_;
    }
    /**
     * <code>int64 wrds_version = 7;</code>
     * @param value The wrdsVersion to set.
     * @return This builder for chaining.
     */
    public Builder setWrdsVersion(long value) {
      wrdsVersion_ = value;
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>int64 wrds_version = 7;</code>
     * @return This builder for chaining.
     */
    public Builder clearWrdsVersion() {
      bitField0_ = (bitField0_ & ~0x00000040);
      wrdsVersion_ = 0L;
      onChanged();
      return this;
    }
    private java.lang.Object wrdsSubKey_ = "";
    /**
     * <code>string wrds_sub_key = 8;</code>
     * @return The wrdsSubKey.
     */
    public java.lang.String getWrdsSubKey() {
      java.lang.Object ref = wrdsSubKey_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        wrdsSubKey_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string wrds_sub_key = 8;</code>
     * @return The bytes for wrdsSubKey.
     */
    public com.google.protobuf.ByteString
        getWrdsSubKeyBytes() {
      java.lang.Object ref = wrdsSubKey_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        wrdsSubKey_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string wrds_sub_key = 8;</code>
     * @param value The wrdsSubKey to set.
     * @return This builder for chaining.
     */
    public Builder setWrdsSubKey(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      wrdsSubKey_ = value;
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <code>string wrds_sub_key = 8;</code>
     * @return This builder for chaining.
     */
    public Builder clearWrdsSubKey() {
      wrdsSubKey_ = getDefaultInstance().getWrdsSubKey();
      bitField0_ = (bitField0_ & ~0x00000080);
      onChanged();
      return this;
    }
    /**
     * <code>string wrds_sub_key = 8;</code>
     * @param value The bytes for wrdsSubKey to set.
     * @return This builder for chaining.
     */
    public Builder setWrdsSubKeyBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      wrdsSubKey_ = value;
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    @java.lang.Override
    public final Builder setUnknownFields(
        final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.setUnknownFields(unknownFields);
    }
    @java.lang.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.douyin.protobuf.douyin_cmd_msg)
  }
  // @@protoc_insertion_point(class_scope:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)
  private static final tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg DEFAULT_INSTANCE;
  static {
    DEFAULT_INSTANCE = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg();
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }
  private static final com.google.protobuf.Parser<douyin_cmd_msg>
      PARSER = new com.google.protobuf.AbstractParser<douyin_cmd_msg>() {
    @java.lang.Override
    public douyin_cmd_msg 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<douyin_cmd_msg> parser() {
    return PARSER;
  }
  @java.lang.Override
  public com.google.protobuf.Parser<douyin_cmd_msg> getParserForType() {
    return PARSER;
  }
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_cmd_msgOrBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
/*
 * 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 interface douyin_cmd_msgOrBuilder extends
    // @@protoc_insertion_point(interface_extends:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_cmd_msg)
    com.google.protobuf.MessageOrBuilder {
  /**
   * <code>string method = 1;</code>
   * @return The method.
   */
  java.lang.String getMethod();
  /**
   * <code>string method = 1;</code>
   * @return The bytes for method.
   */
  com.google.protobuf.ByteString
      getMethodBytes();
  /**
   * <code>bytes payload = 2;</code>
   * @return The payload.
   */
  com.google.protobuf.ByteString getPayload();
  /**
   * <code>int64 msg_id = 3;</code>
   * @return The msgId.
   */
  long getMsgId();
  /**
   * <code>int32 msg_type = 4;</code>
   * @return The msgType.
   */
  int getMsgType();
  /**
   * <code>int64 offset = 5;</code>
   * @return The offset.
   */
  long getOffset();
  /**
   * <code>bool need_wrds_store = 6;</code>
   * @return The needWrdsStore.
   */
  boolean getNeedWrdsStore();
  /**
   * <code>int64 wrds_version = 7;</code>
   * @return The wrdsVersion.
   */
  long getWrdsVersion();
  /**
   * <code>string wrds_sub_key = 8;</code>
   * @return The wrdsSubKey.
   */
  java.lang.String getWrdsSubKey();
  /**
   * <code>string wrds_sub_key = 8;</code>
   * @return The bytes for wrdsSubKey.
   */
  com.google.protobuf.ByteString
      getWrdsSubKeyBytes();
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_chat_message_msg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2384 @@
/*
 * 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_webcast_chat_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
/**
 * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg}
 */
public final class douyin_webcast_chat_message_msg extends
    com.google.protobuf.GeneratedMessageV3 implements
    // @@protoc_insertion_point(message_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)
    douyin_webcast_chat_message_msgOrBuilder {
  private static final long serialVersionUID = 0L;
  // Use douyin_webcast_chat_message_msg.newBuilder() to construct.
  private douyin_webcast_chat_message_msg(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
    super(builder);
  }
  private douyin_webcast_chat_message_msg() {
    content_ = "";
    fullScreenTextColor_ = "";
    chatBy_ = "";
  }
  @java.lang.Override
  @SuppressWarnings({"unused"})
  protected java.lang.Object newInstance(
      UnusedPrivateParameter unused) {
    return new douyin_webcast_chat_message_msg();
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_chat_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_descriptor;
  }
  @java.lang.Override
  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internalGetFieldAccessorTable() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_chat_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.Builder.class);
  }
  public static final int COMMON_FIELD_NUMBER = 1;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common common_;
  /**
   * <code>.Common common = 1;</code>
   * @return Whether the common field is set.
   */
  @java.lang.Override
  public boolean hasCommon() {
    return common_ != null;
  }
  /**
   * <code>.Common common = 1;</code>
   * @return The common.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common getCommon() {
    return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
  }
  /**
   * <code>.Common common = 1;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder getCommonOrBuilder() {
    return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
  }
  public static final int USER_FIELD_NUMBER = 2;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User user_;
  /**
   * <code>.User user = 2;</code>
   * @return Whether the user field is set.
   */
  @java.lang.Override
  public boolean hasUser() {
    return user_ != null;
  }
  /**
   * <code>.User user = 2;</code>
   * @return The user.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getUser() {
    return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
  }
  /**
   * <code>.User user = 2;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getUserOrBuilder() {
    return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
  }
  public static final int CONTENT_FIELD_NUMBER = 3;
  @SuppressWarnings("serial")
  private volatile java.lang.Object content_ = "";
  /**
   * <code>string content = 3;</code>
   * @return The content.
   */
  @java.lang.Override
  public java.lang.String getContent() {
    java.lang.Object ref = content_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      content_ = s;
      return s;
    }
  }
  /**
   * <code>string content = 3;</code>
   * @return The bytes for content.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getContentBytes() {
    java.lang.Object ref = content_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      content_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int VISIBLE_TO_SENDER_FIELD_NUMBER = 4;
  private boolean visibleToSender_ = false;
  /**
   * <code>bool visible_to_sender = 4;</code>
   * @return The visibleToSender.
   */
  @java.lang.Override
  public boolean getVisibleToSender() {
    return visibleToSender_;
  }
  public static final int BACKGROUND_IMAGE_FIELD_NUMBER = 5;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image backgroundImage_;
  /**
   * <code>.Image background_image = 5;</code>
   * @return Whether the backgroundImage field is set.
   */
  @java.lang.Override
  public boolean hasBackgroundImage() {
    return backgroundImage_ != null;
  }
  /**
   * <code>.Image background_image = 5;</code>
   * @return The backgroundImage.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImage() {
    return backgroundImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImage_;
  }
  /**
   * <code>.Image background_image = 5;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageOrBuilder() {
    return backgroundImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImage_;
  }
  public static final int FULL_SCREEN_TEXT_COLOR_FIELD_NUMBER = 6;
  @SuppressWarnings("serial")
  private volatile java.lang.Object fullScreenTextColor_ = "";
  /**
   * <code>string full_screen_text_color = 6;</code>
   * @return The fullScreenTextColor.
   */
  @java.lang.Override
  public java.lang.String getFullScreenTextColor() {
    java.lang.Object ref = fullScreenTextColor_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      fullScreenTextColor_ = s;
      return s;
    }
  }
  /**
   * <code>string full_screen_text_color = 6;</code>
   * @return The bytes for fullScreenTextColor.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getFullScreenTextColorBytes() {
    java.lang.Object ref = fullScreenTextColor_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      fullScreenTextColor_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int BACKGROUND_IMAGE_V2_FIELD_NUMBER = 7;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image backgroundImageV2_;
  /**
   * <code>.Image background_image_v2 = 7;</code>
   * @return Whether the backgroundImageV2 field is set.
   */
  @java.lang.Override
  public boolean hasBackgroundImageV2() {
    return backgroundImageV2_ != null;
  }
  /**
   * <code>.Image background_image_v2 = 7;</code>
   * @return The backgroundImageV2.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImageV2() {
    return backgroundImageV2_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImageV2_;
  }
  /**
   * <code>.Image background_image_v2 = 7;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageV2OrBuilder() {
    return backgroundImageV2_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImageV2_;
  }
  public static final int GIFT_IMAGE_FIELD_NUMBER = 10;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image giftImage_;
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   * @return Whether the giftImage field is set.
   */
  @java.lang.Override
  public boolean hasGiftImage() {
    return giftImage_ != null;
  }
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   * @return The giftImage.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getGiftImage() {
    return giftImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : giftImage_;
  }
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getGiftImageOrBuilder() {
    return giftImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : giftImage_;
  }
  public static final int AGREE_MSG_ID_FIELD_NUMBER = 11;
  private long agreeMsgId_ = 0L;
  /**
   * <code>uint64 agree_msg_id = 11;</code>
   * @return The agreeMsgId.
   */
  @java.lang.Override
  public long getAgreeMsgId() {
    return agreeMsgId_;
  }
  public static final int PRIORITY_LEVEL_FIELD_NUMBER = 12;
  private int priorityLevel_ = 0;
  /**
   * <code>uint32 priority_level = 12;</code>
   * @return The priorityLevel.
   */
  @java.lang.Override
  public int getPriorityLevel() {
    return priorityLevel_;
  }
  public static final int EVENT_TIME_FIELD_NUMBER = 15;
  private long eventTime_ = 0L;
  /**
   * <pre>
   * LandscapeAreaCommon landscape_area_common = 13;
   * </pre>
   *
   * <code>uint64 event_time = 15;</code>
   * @return The eventTime.
   */
  @java.lang.Override
  public long getEventTime() {
    return eventTime_;
  }
  public static final int SEND_REVIEW_FIELD_NUMBER = 16;
  private boolean sendReview_ = false;
  /**
   * <code>bool send_review = 16;</code>
   * @return The sendReview.
   */
  @java.lang.Override
  public boolean getSendReview() {
    return sendReview_;
  }
  public static final int FROM_INTERCOM_FIELD_NUMBER = 17;
  private boolean fromIntercom_ = false;
  /**
   * <code>bool from_intercom = 17;</code>
   * @return The fromIntercom.
   */
  @java.lang.Override
  public boolean getFromIntercom() {
    return fromIntercom_;
  }
  public static final int INTERCOM_HIDE_USER_CARD_FIELD_NUMBER = 18;
  private boolean intercomHideUserCard_ = false;
  /**
   * <code>bool intercom_hide_user_card = 18;</code>
   * @return The intercomHideUserCard.
   */
  @java.lang.Override
  public boolean getIntercomHideUserCard() {
    return intercomHideUserCard_;
  }
  public static final int CHAT_BY_FIELD_NUMBER = 20;
  @SuppressWarnings("serial")
  private volatile java.lang.Object chatBy_ = "";
  /**
   * <pre>
   * repeated string chatTagsList = 19;
   * </pre>
   *
   * <code>string chat_by = 20;</code>
   * @return The chatBy.
   */
  @java.lang.Override
  public java.lang.String getChatBy() {
    java.lang.Object ref = chatBy_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      chatBy_ = s;
      return s;
    }
  }
  /**
   * <pre>
   * repeated string chatTagsList = 19;
   * </pre>
   *
   * <code>string chat_by = 20;</code>
   * @return The bytes for chatBy.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getChatByBytes() {
    java.lang.Object ref = chatBy_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      chatBy_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int INDIVIDUAL_CHAT_PRIORITY_FIELD_NUMBER = 21;
  private int individualChatPriority_ = 0;
  /**
   * <pre>
   * Text rtf_content = 22 ;
   * </pre>
   *
   * <code>uint32 individual_chat_priority = 21;</code>
   * @return The individualChatPriority.
   */
  @java.lang.Override
  public int getIndividualChatPriority() {
    return individualChatPriority_;
  }
  private byte memoizedIsInitialized = -1;
  @java.lang.Override
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized == 1) return true;
    if (isInitialized == 0) return false;
    memoizedIsInitialized = 1;
    return true;
  }
  @java.lang.Override
  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    if (common_ != null) {
      output.writeMessage(1, getCommon());
    }
    if (user_ != null) {
      output.writeMessage(2, getUser());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(content_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, content_);
    }
    if (visibleToSender_ != false) {
      output.writeBool(4, visibleToSender_);
    }
    if (backgroundImage_ != null) {
      output.writeMessage(5, getBackgroundImage());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(fullScreenTextColor_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, fullScreenTextColor_);
    }
    if (backgroundImageV2_ != null) {
      output.writeMessage(7, getBackgroundImageV2());
    }
    if (giftImage_ != null) {
      output.writeMessage(10, getGiftImage());
    }
    if (agreeMsgId_ != 0L) {
      output.writeUInt64(11, agreeMsgId_);
    }
    if (priorityLevel_ != 0) {
      output.writeUInt32(12, priorityLevel_);
    }
    if (eventTime_ != 0L) {
      output.writeUInt64(15, eventTime_);
    }
    if (sendReview_ != false) {
      output.writeBool(16, sendReview_);
    }
    if (fromIntercom_ != false) {
      output.writeBool(17, fromIntercom_);
    }
    if (intercomHideUserCard_ != false) {
      output.writeBool(18, intercomHideUserCard_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chatBy_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 20, chatBy_);
    }
    if (individualChatPriority_ != 0) {
      output.writeUInt32(21, individualChatPriority_);
    }
    getUnknownFields().writeTo(output);
  }
  @java.lang.Override
  public int getSerializedSize() {
    int size = memoizedSize;
    if (size != -1) return size;
    size = 0;
    if (common_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(1, getCommon());
    }
    if (user_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(2, getUser());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(content_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, content_);
    }
    if (visibleToSender_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(4, visibleToSender_);
    }
    if (backgroundImage_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(5, getBackgroundImage());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(fullScreenTextColor_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, fullScreenTextColor_);
    }
    if (backgroundImageV2_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(7, getBackgroundImageV2());
    }
    if (giftImage_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(10, getGiftImage());
    }
    if (agreeMsgId_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(11, agreeMsgId_);
    }
    if (priorityLevel_ != 0) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt32Size(12, priorityLevel_);
    }
    if (eventTime_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(15, eventTime_);
    }
    if (sendReview_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(16, sendReview_);
    }
    if (fromIntercom_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(17, fromIntercom_);
    }
    if (intercomHideUserCard_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(18, intercomHideUserCard_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chatBy_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(20, chatBy_);
    }
    if (individualChatPriority_ != 0) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt32Size(21, individualChatPriority_);
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSize = size;
    return size;
  }
  @java.lang.Override
  public boolean equals(final java.lang.Object obj) {
    if (obj == this) {
     return true;
    }
    if (!(obj instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)) {
      return super.equals(obj);
    }
    tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg other = (tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg) obj;
    if (hasCommon() != other.hasCommon()) return false;
    if (hasCommon()) {
      if (!getCommon()
          .equals(other.getCommon())) return false;
    }
    if (hasUser() != other.hasUser()) return false;
    if (hasUser()) {
      if (!getUser()
          .equals(other.getUser())) return false;
    }
    if (!getContent()
        .equals(other.getContent())) return false;
    if (getVisibleToSender()
        != other.getVisibleToSender()) return false;
    if (hasBackgroundImage() != other.hasBackgroundImage()) return false;
    if (hasBackgroundImage()) {
      if (!getBackgroundImage()
          .equals(other.getBackgroundImage())) return false;
    }
    if (!getFullScreenTextColor()
        .equals(other.getFullScreenTextColor())) return false;
    if (hasBackgroundImageV2() != other.hasBackgroundImageV2()) return false;
    if (hasBackgroundImageV2()) {
      if (!getBackgroundImageV2()
          .equals(other.getBackgroundImageV2())) return false;
    }
    if (hasGiftImage() != other.hasGiftImage()) return false;
    if (hasGiftImage()) {
      if (!getGiftImage()
          .equals(other.getGiftImage())) return false;
    }
    if (getAgreeMsgId()
        != other.getAgreeMsgId()) return false;
    if (getPriorityLevel()
        != other.getPriorityLevel()) return false;
    if (getEventTime()
        != other.getEventTime()) return false;
    if (getSendReview()
        != other.getSendReview()) return false;
    if (getFromIntercom()
        != other.getFromIntercom()) return false;
    if (getIntercomHideUserCard()
        != other.getIntercomHideUserCard()) return false;
    if (!getChatBy()
        .equals(other.getChatBy())) return false;
    if (getIndividualChatPriority()
        != other.getIndividualChatPriority()) return false;
    if (!getUnknownFields().equals(other.getUnknownFields())) return false;
    return true;
  }
  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    if (hasCommon()) {
      hash = (37 * hash) + COMMON_FIELD_NUMBER;
      hash = (53 * hash) + getCommon().hashCode();
    }
    if (hasUser()) {
      hash = (37 * hash) + USER_FIELD_NUMBER;
      hash = (53 * hash) + getUser().hashCode();
    }
    hash = (37 * hash) + CONTENT_FIELD_NUMBER;
    hash = (53 * hash) + getContent().hashCode();
    hash = (37 * hash) + VISIBLE_TO_SENDER_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getVisibleToSender());
    if (hasBackgroundImage()) {
      hash = (37 * hash) + BACKGROUND_IMAGE_FIELD_NUMBER;
      hash = (53 * hash) + getBackgroundImage().hashCode();
    }
    hash = (37 * hash) + FULL_SCREEN_TEXT_COLOR_FIELD_NUMBER;
    hash = (53 * hash) + getFullScreenTextColor().hashCode();
    if (hasBackgroundImageV2()) {
      hash = (37 * hash) + BACKGROUND_IMAGE_V2_FIELD_NUMBER;
      hash = (53 * hash) + getBackgroundImageV2().hashCode();
    }
    if (hasGiftImage()) {
      hash = (37 * hash) + GIFT_IMAGE_FIELD_NUMBER;
      hash = (53 * hash) + getGiftImage().hashCode();
    }
    hash = (37 * hash) + AGREE_MSG_ID_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getAgreeMsgId());
    hash = (37 * hash) + PRIORITY_LEVEL_FIELD_NUMBER;
    hash = (53 * hash) + getPriorityLevel();
    hash = (37 * hash) + EVENT_TIME_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getEventTime());
    hash = (37 * hash) + SEND_REVIEW_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getSendReview());
    hash = (37 * hash) + FROM_INTERCOM_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getFromIntercom());
    hash = (37 * hash) + INTERCOM_HIDE_USER_CARD_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getIntercomHideUserCard());
    hash = (37 * hash) + CHAT_BY_FIELD_NUMBER;
    hash = (53 * hash) + getChatBy().hashCode();
    hash = (37 * hash) + INDIVIDUAL_CHAT_PRIORITY_FIELD_NUMBER;
    hash = (53 * hash) + getIndividualChatPriority();
    hash = (29 * hash) + getUnknownFields().hashCode();
    memoizedHashCode = hash;
    return hash;
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      java.nio.ByteBuffer data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      java.nio.ByteBuffer data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseDelimitedWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input, extensionRegistry);
  }
  @java.lang.Override
  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder() {
    return DEFAULT_INSTANCE.toBuilder();
  }
  public static Builder newBuilder(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg prototype) {
    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
  }
  @java.lang.Override
  public Builder toBuilder() {
    return this == DEFAULT_INSTANCE
        ? new Builder() : new Builder().mergeFrom(this);
  }
  @java.lang.Override
  protected Builder newBuilderForType(
      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
      // @@protoc_insertion_point(builder_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msgOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_chat_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_descriptor;
    }
    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_chat_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.Builder.class);
    }
    // Construct using tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.newBuilder()
    private Builder() {
    }
    private Builder(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      super(parent);
    }
    @java.lang.Override
    public Builder clear() {
      super.clear();
      bitField0_ = 0;
      common_ = null;
      if (commonBuilder_ != null) {
        commonBuilder_.dispose();
        commonBuilder_ = null;
      }
      user_ = null;
      if (userBuilder_ != null) {
        userBuilder_.dispose();
        userBuilder_ = null;
      }
      content_ = "";
      visibleToSender_ = false;
      backgroundImage_ = null;
      if (backgroundImageBuilder_ != null) {
        backgroundImageBuilder_.dispose();
        backgroundImageBuilder_ = null;
      }
      fullScreenTextColor_ = "";
      backgroundImageV2_ = null;
      if (backgroundImageV2Builder_ != null) {
        backgroundImageV2Builder_.dispose();
        backgroundImageV2Builder_ = null;
      }
      giftImage_ = null;
      if (giftImageBuilder_ != null) {
        giftImageBuilder_.dispose();
        giftImageBuilder_ = null;
      }
      agreeMsgId_ = 0L;
      priorityLevel_ = 0;
      eventTime_ = 0L;
      sendReview_ = false;
      fromIntercom_ = false;
      intercomHideUserCard_ = false;
      chatBy_ = "";
      individualChatPriority_ = 0;
      return this;
    }
    @java.lang.Override
    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_chat_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_chat_message_msg_descriptor;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg getDefaultInstanceForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.getDefaultInstance();
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg build() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg buildPartial() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg result = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg(this);
      if (bitField0_ != 0) { buildPartial0(result); }
      onBuilt();
      return result;
    }
    private void buildPartial0(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg result) {
      int from_bitField0_ = bitField0_;
      if (((from_bitField0_ & 0x00000001) != 0)) {
        result.common_ = commonBuilder_ == null
            ? common_
            : commonBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000002) != 0)) {
        result.user_ = userBuilder_ == null
            ? user_
            : userBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000004) != 0)) {
        result.content_ = content_;
      }
      if (((from_bitField0_ & 0x00000008) != 0)) {
        result.visibleToSender_ = visibleToSender_;
      }
      if (((from_bitField0_ & 0x00000010) != 0)) {
        result.backgroundImage_ = backgroundImageBuilder_ == null
            ? backgroundImage_
            : backgroundImageBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000020) != 0)) {
        result.fullScreenTextColor_ = fullScreenTextColor_;
      }
      if (((from_bitField0_ & 0x00000040) != 0)) {
        result.backgroundImageV2_ = backgroundImageV2Builder_ == null
            ? backgroundImageV2_
            : backgroundImageV2Builder_.build();
      }
      if (((from_bitField0_ & 0x00000080) != 0)) {
        result.giftImage_ = giftImageBuilder_ == null
            ? giftImage_
            : giftImageBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000100) != 0)) {
        result.agreeMsgId_ = agreeMsgId_;
      }
      if (((from_bitField0_ & 0x00000200) != 0)) {
        result.priorityLevel_ = priorityLevel_;
      }
      if (((from_bitField0_ & 0x00000400) != 0)) {
        result.eventTime_ = eventTime_;
      }
      if (((from_bitField0_ & 0x00000800) != 0)) {
        result.sendReview_ = sendReview_;
      }
      if (((from_bitField0_ & 0x00001000) != 0)) {
        result.fromIntercom_ = fromIntercom_;
      }
      if (((from_bitField0_ & 0x00002000) != 0)) {
        result.intercomHideUserCard_ = intercomHideUserCard_;
      }
      if (((from_bitField0_ & 0x00004000) != 0)) {
        result.chatBy_ = chatBy_;
      }
      if (((from_bitField0_ & 0x00008000) != 0)) {
        result.individualChatPriority_ = individualChatPriority_;
      }
    }
    @java.lang.Override
    public Builder clone() {
      return super.clone();
    }
    @java.lang.Override
    public Builder setField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.setField(field, value);
    }
    @java.lang.Override
    public Builder clearField(
        com.google.protobuf.Descriptors.FieldDescriptor field) {
      return super.clearField(field);
    }
    @java.lang.Override
    public Builder clearOneof(
        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
      return super.clearOneof(oneof);
    }
    @java.lang.Override
    public Builder setRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        int index, java.lang.Object value) {
      return super.setRepeatedField(field, index, value);
    }
    @java.lang.Override
    public Builder addRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.addRepeatedField(field, value);
    }
    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg) {
        return mergeFrom((tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }
    public Builder mergeFrom(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg other) {
      if (other == tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg.getDefaultInstance()) return this;
      if (other.hasCommon()) {
        mergeCommon(other.getCommon());
      }
      if (other.hasUser()) {
        mergeUser(other.getUser());
      }
      if (!other.getContent().isEmpty()) {
        content_ = other.content_;
        bitField0_ |= 0x00000004;
        onChanged();
      }
      if (other.getVisibleToSender() != false) {
        setVisibleToSender(other.getVisibleToSender());
      }
      if (other.hasBackgroundImage()) {
        mergeBackgroundImage(other.getBackgroundImage());
      }
      if (!other.getFullScreenTextColor().isEmpty()) {
        fullScreenTextColor_ = other.fullScreenTextColor_;
        bitField0_ |= 0x00000020;
        onChanged();
      }
      if (other.hasBackgroundImageV2()) {
        mergeBackgroundImageV2(other.getBackgroundImageV2());
      }
      if (other.hasGiftImage()) {
        mergeGiftImage(other.getGiftImage());
      }
      if (other.getAgreeMsgId() != 0L) {
        setAgreeMsgId(other.getAgreeMsgId());
      }
      if (other.getPriorityLevel() != 0) {
        setPriorityLevel(other.getPriorityLevel());
      }
      if (other.getEventTime() != 0L) {
        setEventTime(other.getEventTime());
      }
      if (other.getSendReview() != false) {
        setSendReview(other.getSendReview());
      }
      if (other.getFromIntercom() != false) {
        setFromIntercom(other.getFromIntercom());
      }
      if (other.getIntercomHideUserCard() != false) {
        setIntercomHideUserCard(other.getIntercomHideUserCard());
      }
      if (!other.getChatBy().isEmpty()) {
        chatBy_ = other.chatBy_;
        bitField0_ |= 0x00004000;
        onChanged();
      }
      if (other.getIndividualChatPriority() != 0) {
        setIndividualChatPriority(other.getIndividualChatPriority());
      }
      this.mergeUnknownFields(other.getUnknownFields());
      onChanged();
      return this;
    }
    @java.lang.Override
    public final boolean isInitialized() {
      return true;
    }
    @java.lang.Override
    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              input.readMessage(
                  getCommonFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000001;
              break;
            } // case 10
            case 18: {
              input.readMessage(
                  getUserFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000002;
              break;
            } // case 18
            case 26: {
              content_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00000004;
              break;
            } // case 26
            case 32: {
              visibleToSender_ = input.readBool();
              bitField0_ |= 0x00000008;
              break;
            } // case 32
            case 42: {
              input.readMessage(
                  getBackgroundImageFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000010;
              break;
            } // case 42
            case 50: {
              fullScreenTextColor_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00000020;
              break;
            } // case 50
            case 58: {
              input.readMessage(
                  getBackgroundImageV2FieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000040;
              break;
            } // case 58
            case 82: {
              input.readMessage(
                  getGiftImageFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000080;
              break;
            } // case 82
            case 88: {
              agreeMsgId_ = input.readUInt64();
              bitField0_ |= 0x00000100;
              break;
            } // case 88
            case 96: {
              priorityLevel_ = input.readUInt32();
              bitField0_ |= 0x00000200;
              break;
            } // case 96
            case 120: {
              eventTime_ = input.readUInt64();
              bitField0_ |= 0x00000400;
              break;
            } // case 120
            case 128: {
              sendReview_ = input.readBool();
              bitField0_ |= 0x00000800;
              break;
            } // case 128
            case 136: {
              fromIntercom_ = input.readBool();
              bitField0_ |= 0x00001000;
              break;
            } // case 136
            case 144: {
              intercomHideUserCard_ = input.readBool();
              bitField0_ |= 0x00002000;
              break;
            } // case 144
            case 162: {
              chatBy_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00004000;
              break;
            } // case 162
            case 168: {
              individualChatPriority_ = input.readUInt32();
              bitField0_ |= 0x00008000;
              break;
            } // case 168
            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 tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common common_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder> commonBuilder_;
    /**
     * <code>.Common common = 1;</code>
     * @return Whether the common field is set.
     */
    public boolean hasCommon() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>.Common common = 1;</code>
     * @return The common.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common getCommon() {
      if (commonBuilder_ == null) {
        return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
      } else {
        return commonBuilder_.getMessage();
      }
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder setCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common value) {
      if (commonBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        common_ = value;
      } else {
        commonBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder setCommon(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder builderForValue) {
      if (commonBuilder_ == null) {
        common_ = builderForValue.build();
      } else {
        commonBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder mergeCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common value) {
      if (commonBuilder_ == null) {
        if (((bitField0_ & 0x00000001) != 0) &&
          common_ != null &&
          common_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance()) {
          getCommonBuilder().mergeFrom(value);
        } else {
          common_ = value;
        }
      } else {
        commonBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder clearCommon() {
      bitField0_ = (bitField0_ & ~0x00000001);
      common_ = null;
      if (commonBuilder_ != null) {
        commonBuilder_.dispose();
        commonBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder getCommonBuilder() {
      bitField0_ |= 0x00000001;
      onChanged();
      return getCommonFieldBuilder().getBuilder();
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder getCommonOrBuilder() {
      if (commonBuilder_ != null) {
        return commonBuilder_.getMessageOrBuilder();
      } else {
        return common_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
      }
    }
    /**
     * <code>.Common common = 1;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder>
        getCommonFieldBuilder() {
      if (commonBuilder_ == null) {
        commonBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder>(
                getCommon(),
                getParentForChildren(),
                isClean());
        common_ = null;
      }
      return commonBuilder_;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User user_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder> userBuilder_;
    /**
     * <code>.User user = 2;</code>
     * @return Whether the user field is set.
     */
    public boolean hasUser() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>.User user = 2;</code>
     * @return The user.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getUser() {
      if (userBuilder_ == null) {
        return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
      } else {
        return userBuilder_.getMessage();
      }
    }
    /**
     * <code>.User user = 2;</code>
     */
    public Builder setUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (userBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        user_ = value;
      } else {
        userBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 2;</code>
     */
    public Builder setUser(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder builderForValue) {
      if (userBuilder_ == null) {
        user_ = builderForValue.build();
      } else {
        userBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 2;</code>
     */
    public Builder mergeUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (userBuilder_ == null) {
        if (((bitField0_ & 0x00000002) != 0) &&
          user_ != null &&
          user_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance()) {
          getUserBuilder().mergeFrom(value);
        } else {
          user_ = value;
        }
      } else {
        userBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 2;</code>
     */
    public Builder clearUser() {
      bitField0_ = (bitField0_ & ~0x00000002);
      user_ = null;
      if (userBuilder_ != null) {
        userBuilder_.dispose();
        userBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 2;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder getUserBuilder() {
      bitField0_ |= 0x00000002;
      onChanged();
      return getUserFieldBuilder().getBuilder();
    }
    /**
     * <code>.User user = 2;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getUserOrBuilder() {
      if (userBuilder_ != null) {
        return userBuilder_.getMessageOrBuilder();
      } else {
        return user_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
      }
    }
    /**
     * <code>.User user = 2;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>
        getUserFieldBuilder() {
      if (userBuilder_ == null) {
        userBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>(
                getUser(),
                getParentForChildren(),
                isClean());
        user_ = null;
      }
      return userBuilder_;
    }
    private java.lang.Object content_ = "";
    /**
     * <code>string content = 3;</code>
     * @return The content.
     */
    public java.lang.String getContent() {
      java.lang.Object ref = content_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        content_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string content = 3;</code>
     * @return The bytes for content.
     */
    public com.google.protobuf.ByteString
        getContentBytes() {
      java.lang.Object ref = content_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        content_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string content = 3;</code>
     * @param value The content to set.
     * @return This builder for chaining.
     */
    public Builder setContent(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      content_ = value;
      bitField0_ |= 0x00000004;
      onChanged();
      return this;
    }
    /**
     * <code>string content = 3;</code>
     * @return This builder for chaining.
     */
    public Builder clearContent() {
      content_ = getDefaultInstance().getContent();
      bitField0_ = (bitField0_ & ~0x00000004);
      onChanged();
      return this;
    }
    /**
     * <code>string content = 3;</code>
     * @param value The bytes for content to set.
     * @return This builder for chaining.
     */
    public Builder setContentBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      content_ = value;
      bitField0_ |= 0x00000004;
      onChanged();
      return this;
    }
    private boolean visibleToSender_ ;
    /**
     * <code>bool visible_to_sender = 4;</code>
     * @return The visibleToSender.
     */
    @java.lang.Override
    public boolean getVisibleToSender() {
      return visibleToSender_;
    }
    /**
     * <code>bool visible_to_sender = 4;</code>
     * @param value The visibleToSender to set.
     * @return This builder for chaining.
     */
    public Builder setVisibleToSender(boolean value) {
      visibleToSender_ = value;
      bitField0_ |= 0x00000008;
      onChanged();
      return this;
    }
    /**
     * <code>bool visible_to_sender = 4;</code>
     * @return This builder for chaining.
     */
    public Builder clearVisibleToSender() {
      bitField0_ = (bitField0_ & ~0x00000008);
      visibleToSender_ = false;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image backgroundImage_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder> backgroundImageBuilder_;
    /**
     * <code>.Image background_image = 5;</code>
     * @return Whether the backgroundImage field is set.
     */
    public boolean hasBackgroundImage() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>.Image background_image = 5;</code>
     * @return The backgroundImage.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImage() {
      if (backgroundImageBuilder_ == null) {
        return backgroundImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImage_;
      } else {
        return backgroundImageBuilder_.getMessage();
      }
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public Builder setBackgroundImage(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (backgroundImageBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        backgroundImage_ = value;
      } else {
        backgroundImageBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public Builder setBackgroundImage(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder builderForValue) {
      if (backgroundImageBuilder_ == null) {
        backgroundImage_ = builderForValue.build();
      } else {
        backgroundImageBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public Builder mergeBackgroundImage(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (backgroundImageBuilder_ == null) {
        if (((bitField0_ & 0x00000010) != 0) &&
          backgroundImage_ != null &&
          backgroundImage_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance()) {
          getBackgroundImageBuilder().mergeFrom(value);
        } else {
          backgroundImage_ = value;
        }
      } else {
        backgroundImageBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public Builder clearBackgroundImage() {
      bitField0_ = (bitField0_ & ~0x00000010);
      backgroundImage_ = null;
      if (backgroundImageBuilder_ != null) {
        backgroundImageBuilder_.dispose();
        backgroundImageBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder getBackgroundImageBuilder() {
      bitField0_ |= 0x00000010;
      onChanged();
      return getBackgroundImageFieldBuilder().getBuilder();
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageOrBuilder() {
      if (backgroundImageBuilder_ != null) {
        return backgroundImageBuilder_.getMessageOrBuilder();
      } else {
        return backgroundImage_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImage_;
      }
    }
    /**
     * <code>.Image background_image = 5;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>
        getBackgroundImageFieldBuilder() {
      if (backgroundImageBuilder_ == null) {
        backgroundImageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>(
                getBackgroundImage(),
                getParentForChildren(),
                isClean());
        backgroundImage_ = null;
      }
      return backgroundImageBuilder_;
    }
    private java.lang.Object fullScreenTextColor_ = "";
    /**
     * <code>string full_screen_text_color = 6;</code>
     * @return The fullScreenTextColor.
     */
    public java.lang.String getFullScreenTextColor() {
      java.lang.Object ref = fullScreenTextColor_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        fullScreenTextColor_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string full_screen_text_color = 6;</code>
     * @return The bytes for fullScreenTextColor.
     */
    public com.google.protobuf.ByteString
        getFullScreenTextColorBytes() {
      java.lang.Object ref = fullScreenTextColor_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        fullScreenTextColor_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string full_screen_text_color = 6;</code>
     * @param value The fullScreenTextColor to set.
     * @return This builder for chaining.
     */
    public Builder setFullScreenTextColor(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      fullScreenTextColor_ = value;
      bitField0_ |= 0x00000020;
      onChanged();
      return this;
    }
    /**
     * <code>string full_screen_text_color = 6;</code>
     * @return This builder for chaining.
     */
    public Builder clearFullScreenTextColor() {
      fullScreenTextColor_ = getDefaultInstance().getFullScreenTextColor();
      bitField0_ = (bitField0_ & ~0x00000020);
      onChanged();
      return this;
    }
    /**
     * <code>string full_screen_text_color = 6;</code>
     * @param value The bytes for fullScreenTextColor to set.
     * @return This builder for chaining.
     */
    public Builder setFullScreenTextColorBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      fullScreenTextColor_ = value;
      bitField0_ |= 0x00000020;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image backgroundImageV2_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder> backgroundImageV2Builder_;
    /**
     * <code>.Image background_image_v2 = 7;</code>
     * @return Whether the backgroundImageV2 field is set.
     */
    public boolean hasBackgroundImageV2() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     * @return The backgroundImageV2.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImageV2() {
      if (backgroundImageV2Builder_ == null) {
        return backgroundImageV2_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImageV2_;
      } else {
        return backgroundImageV2Builder_.getMessage();
      }
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public Builder setBackgroundImageV2(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (backgroundImageV2Builder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        backgroundImageV2_ = value;
      } else {
        backgroundImageV2Builder_.setMessage(value);
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public Builder setBackgroundImageV2(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder builderForValue) {
      if (backgroundImageV2Builder_ == null) {
        backgroundImageV2_ = builderForValue.build();
      } else {
        backgroundImageV2Builder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public Builder mergeBackgroundImageV2(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (backgroundImageV2Builder_ == null) {
        if (((bitField0_ & 0x00000040) != 0) &&
          backgroundImageV2_ != null &&
          backgroundImageV2_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance()) {
          getBackgroundImageV2Builder().mergeFrom(value);
        } else {
          backgroundImageV2_ = value;
        }
      } else {
        backgroundImageV2Builder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public Builder clearBackgroundImageV2() {
      bitField0_ = (bitField0_ & ~0x00000040);
      backgroundImageV2_ = null;
      if (backgroundImageV2Builder_ != null) {
        backgroundImageV2Builder_.dispose();
        backgroundImageV2Builder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder getBackgroundImageV2Builder() {
      bitField0_ |= 0x00000040;
      onChanged();
      return getBackgroundImageV2FieldBuilder().getBuilder();
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageV2OrBuilder() {
      if (backgroundImageV2Builder_ != null) {
        return backgroundImageV2Builder_.getMessageOrBuilder();
      } else {
        return backgroundImageV2_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : backgroundImageV2_;
      }
    }
    /**
     * <code>.Image background_image_v2 = 7;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>
        getBackgroundImageV2FieldBuilder() {
      if (backgroundImageV2Builder_ == null) {
        backgroundImageV2Builder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>(
                getBackgroundImageV2(),
                getParentForChildren(),
                isClean());
        backgroundImageV2_ = null;
      }
      return backgroundImageV2Builder_;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image giftImage_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder> giftImageBuilder_;
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     * @return Whether the giftImage field is set.
     */
    public boolean hasGiftImage() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     * @return The giftImage.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getGiftImage() {
      if (giftImageBuilder_ == null) {
        return giftImage_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : giftImage_;
      } else {
        return giftImageBuilder_.getMessage();
      }
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public Builder setGiftImage(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (giftImageBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        giftImage_ = value;
      } else {
        giftImageBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public Builder setGiftImage(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder builderForValue) {
      if (giftImageBuilder_ == null) {
        giftImage_ = builderForValue.build();
      } else {
        giftImageBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public Builder mergeGiftImage(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image value) {
      if (giftImageBuilder_ == null) {
        if (((bitField0_ & 0x00000080) != 0) &&
          giftImage_ != null &&
          giftImage_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance()) {
          getGiftImageBuilder().mergeFrom(value);
        } else {
          giftImage_ = value;
        }
      } else {
        giftImageBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public Builder clearGiftImage() {
      bitField0_ = (bitField0_ & ~0x00000080);
      giftImage_ = null;
      if (giftImageBuilder_ != null) {
        giftImageBuilder_.dispose();
        giftImageBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder getGiftImageBuilder() {
      bitField0_ |= 0x00000080;
      onChanged();
      return getGiftImageFieldBuilder().getBuilder();
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getGiftImageOrBuilder() {
      if (giftImageBuilder_ != null) {
        return giftImageBuilder_.getMessageOrBuilder();
      } else {
        return giftImage_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.getDefaultInstance() : giftImage_;
      }
    }
    /**
     * <pre>
     * PublicAreaCommon public_area_common = 9;
     * </pre>
     *
     * <code>.Image gift_image = 10;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>
        getGiftImageFieldBuilder() {
      if (giftImageBuilder_ == null) {
        giftImageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder>(
                getGiftImage(),
                getParentForChildren(),
                isClean());
        giftImage_ = null;
      }
      return giftImageBuilder_;
    }
    private long agreeMsgId_ ;
    /**
     * <code>uint64 agree_msg_id = 11;</code>
     * @return The agreeMsgId.
     */
    @java.lang.Override
    public long getAgreeMsgId() {
      return agreeMsgId_;
    }
    /**
     * <code>uint64 agree_msg_id = 11;</code>
     * @param value The agreeMsgId to set.
     * @return This builder for chaining.
     */
    public Builder setAgreeMsgId(long value) {
      agreeMsgId_ = value;
      bitField0_ |= 0x00000100;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 agree_msg_id = 11;</code>
     * @return This builder for chaining.
     */
    public Builder clearAgreeMsgId() {
      bitField0_ = (bitField0_ & ~0x00000100);
      agreeMsgId_ = 0L;
      onChanged();
      return this;
    }
    private int priorityLevel_ ;
    /**
     * <code>uint32 priority_level = 12;</code>
     * @return The priorityLevel.
     */
    @java.lang.Override
    public int getPriorityLevel() {
      return priorityLevel_;
    }
    /**
     * <code>uint32 priority_level = 12;</code>
     * @param value The priorityLevel to set.
     * @return This builder for chaining.
     */
    public Builder setPriorityLevel(int value) {
      priorityLevel_ = value;
      bitField0_ |= 0x00000200;
      onChanged();
      return this;
    }
    /**
     * <code>uint32 priority_level = 12;</code>
     * @return This builder for chaining.
     */
    public Builder clearPriorityLevel() {
      bitField0_ = (bitField0_ & ~0x00000200);
      priorityLevel_ = 0;
      onChanged();
      return this;
    }
    private long eventTime_ ;
    /**
     * <pre>
     * LandscapeAreaCommon landscape_area_common = 13;
     * </pre>
     *
     * <code>uint64 event_time = 15;</code>
     * @return The eventTime.
     */
    @java.lang.Override
    public long getEventTime() {
      return eventTime_;
    }
    /**
     * <pre>
     * LandscapeAreaCommon landscape_area_common = 13;
     * </pre>
     *
     * <code>uint64 event_time = 15;</code>
     * @param value The eventTime to set.
     * @return This builder for chaining.
     */
    public Builder setEventTime(long value) {
      eventTime_ = value;
      bitField0_ |= 0x00000400;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * LandscapeAreaCommon landscape_area_common = 13;
     * </pre>
     *
     * <code>uint64 event_time = 15;</code>
     * @return This builder for chaining.
     */
    public Builder clearEventTime() {
      bitField0_ = (bitField0_ & ~0x00000400);
      eventTime_ = 0L;
      onChanged();
      return this;
    }
    private boolean sendReview_ ;
    /**
     * <code>bool send_review = 16;</code>
     * @return The sendReview.
     */
    @java.lang.Override
    public boolean getSendReview() {
      return sendReview_;
    }
    /**
     * <code>bool send_review = 16;</code>
     * @param value The sendReview to set.
     * @return This builder for chaining.
     */
    public Builder setSendReview(boolean value) {
      sendReview_ = value;
      bitField0_ |= 0x00000800;
      onChanged();
      return this;
    }
    /**
     * <code>bool send_review = 16;</code>
     * @return This builder for chaining.
     */
    public Builder clearSendReview() {
      bitField0_ = (bitField0_ & ~0x00000800);
      sendReview_ = false;
      onChanged();
      return this;
    }
    private boolean fromIntercom_ ;
    /**
     * <code>bool from_intercom = 17;</code>
     * @return The fromIntercom.
     */
    @java.lang.Override
    public boolean getFromIntercom() {
      return fromIntercom_;
    }
    /**
     * <code>bool from_intercom = 17;</code>
     * @param value The fromIntercom to set.
     * @return This builder for chaining.
     */
    public Builder setFromIntercom(boolean value) {
      fromIntercom_ = value;
      bitField0_ |= 0x00001000;
      onChanged();
      return this;
    }
    /**
     * <code>bool from_intercom = 17;</code>
     * @return This builder for chaining.
     */
    public Builder clearFromIntercom() {
      bitField0_ = (bitField0_ & ~0x00001000);
      fromIntercom_ = false;
      onChanged();
      return this;
    }
    private boolean intercomHideUserCard_ ;
    /**
     * <code>bool intercom_hide_user_card = 18;</code>
     * @return The intercomHideUserCard.
     */
    @java.lang.Override
    public boolean getIntercomHideUserCard() {
      return intercomHideUserCard_;
    }
    /**
     * <code>bool intercom_hide_user_card = 18;</code>
     * @param value The intercomHideUserCard to set.
     * @return This builder for chaining.
     */
    public Builder setIntercomHideUserCard(boolean value) {
      intercomHideUserCard_ = value;
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }
    /**
     * <code>bool intercom_hide_user_card = 18;</code>
     * @return This builder for chaining.
     */
    public Builder clearIntercomHideUserCard() {
      bitField0_ = (bitField0_ & ~0x00002000);
      intercomHideUserCard_ = false;
      onChanged();
      return this;
    }
    private java.lang.Object chatBy_ = "";
    /**
     * <pre>
     * repeated string chatTagsList = 19;
     * </pre>
     *
     * <code>string chat_by = 20;</code>
     * @return The chatBy.
     */
    public java.lang.String getChatBy() {
      java.lang.Object ref = chatBy_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        chatBy_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <pre>
     * repeated string chatTagsList = 19;
     * </pre>
     *
     * <code>string chat_by = 20;</code>
     * @return The bytes for chatBy.
     */
    public com.google.protobuf.ByteString
        getChatByBytes() {
      java.lang.Object ref = chatBy_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        chatBy_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <pre>
     * repeated string chatTagsList = 19;
     * </pre>
     *
     * <code>string chat_by = 20;</code>
     * @param value The chatBy to set.
     * @return This builder for chaining.
     */
    public Builder setChatBy(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      chatBy_ = value;
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * repeated string chatTagsList = 19;
     * </pre>
     *
     * <code>string chat_by = 20;</code>
     * @return This builder for chaining.
     */
    public Builder clearChatBy() {
      chatBy_ = getDefaultInstance().getChatBy();
      bitField0_ = (bitField0_ & ~0x00004000);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * repeated string chatTagsList = 19;
     * </pre>
     *
     * <code>string chat_by = 20;</code>
     * @param value The bytes for chatBy to set.
     * @return This builder for chaining.
     */
    public Builder setChatByBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      chatBy_ = value;
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }
    private int individualChatPriority_ ;
    /**
     * <pre>
     * Text rtf_content = 22 ;
     * </pre>
     *
     * <code>uint32 individual_chat_priority = 21;</code>
     * @return The individualChatPriority.
     */
    @java.lang.Override
    public int getIndividualChatPriority() {
      return individualChatPriority_;
    }
    /**
     * <pre>
     * Text rtf_content = 22 ;
     * </pre>
     *
     * <code>uint32 individual_chat_priority = 21;</code>
     * @param value The individualChatPriority to set.
     * @return This builder for chaining.
     */
    public Builder setIndividualChatPriority(int value) {
      individualChatPriority_ = value;
      bitField0_ |= 0x00008000;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * Text rtf_content = 22 ;
     * </pre>
     *
     * <code>uint32 individual_chat_priority = 21;</code>
     * @return This builder for chaining.
     */
    public Builder clearIndividualChatPriority() {
      bitField0_ = (bitField0_ & ~0x00008000);
      individualChatPriority_ = 0;
      onChanged();
      return this;
    }
    @java.lang.Override
    public final Builder setUnknownFields(
        final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.setUnknownFields(unknownFields);
    }
    @java.lang.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.douyin.protobuf.douyin_webcast_chat_message_msg)
  }
  // @@protoc_insertion_point(class_scope:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)
  private static final tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg DEFAULT_INSTANCE;
  static {
    DEFAULT_INSTANCE = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg();
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }
  private static final com.google.protobuf.Parser<douyin_webcast_chat_message_msg>
      PARSER = new com.google.protobuf.AbstractParser<douyin_webcast_chat_message_msg>() {
    @java.lang.Override
    public douyin_webcast_chat_message_msg 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<douyin_webcast_chat_message_msg> parser() {
    return PARSER;
  }
  @java.lang.Override
  public com.google.protobuf.Parser<douyin_webcast_chat_message_msg> getParserForType() {
    return PARSER;
  }
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_chat_message_msgOrBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
/*
 * 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_webcast_chat_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
public interface douyin_webcast_chat_message_msgOrBuilder extends
    // @@protoc_insertion_point(interface_extends:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_chat_message_msg)
    com.google.protobuf.MessageOrBuilder {
  /**
   * <code>.Common common = 1;</code>
   * @return Whether the common field is set.
   */
  boolean hasCommon();
  /**
   * <code>.Common common = 1;</code>
   * @return The common.
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common getCommon();
  /**
   * <code>.Common common = 1;</code>
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder getCommonOrBuilder();
  /**
   * <code>.User user = 2;</code>
   * @return Whether the user field is set.
   */
  boolean hasUser();
  /**
   * <code>.User user = 2;</code>
   * @return The user.
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getUser();
  /**
   * <code>.User user = 2;</code>
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getUserOrBuilder();
  /**
   * <code>string content = 3;</code>
   * @return The content.
   */
  java.lang.String getContent();
  /**
   * <code>string content = 3;</code>
   * @return The bytes for content.
   */
  com.google.protobuf.ByteString
      getContentBytes();
  /**
   * <code>bool visible_to_sender = 4;</code>
   * @return The visibleToSender.
   */
  boolean getVisibleToSender();
  /**
   * <code>.Image background_image = 5;</code>
   * @return Whether the backgroundImage field is set.
   */
  boolean hasBackgroundImage();
  /**
   * <code>.Image background_image = 5;</code>
   * @return The backgroundImage.
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImage();
  /**
   * <code>.Image background_image = 5;</code>
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageOrBuilder();
  /**
   * <code>string full_screen_text_color = 6;</code>
   * @return The fullScreenTextColor.
   */
  java.lang.String getFullScreenTextColor();
  /**
   * <code>string full_screen_text_color = 6;</code>
   * @return The bytes for fullScreenTextColor.
   */
  com.google.protobuf.ByteString
      getFullScreenTextColorBytes();
  /**
   * <code>.Image background_image_v2 = 7;</code>
   * @return Whether the backgroundImageV2 field is set.
   */
  boolean hasBackgroundImageV2();
  /**
   * <code>.Image background_image_v2 = 7;</code>
   * @return The backgroundImageV2.
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getBackgroundImageV2();
  /**
   * <code>.Image background_image_v2 = 7;</code>
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getBackgroundImageV2OrBuilder();
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   * @return Whether the giftImage field is set.
   */
  boolean hasGiftImage();
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   * @return The giftImage.
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.Image getGiftImage();
  /**
   * <pre>
   * PublicAreaCommon public_area_common = 9;
   * </pre>
   *
   * <code>.Image gift_image = 10;</code>
   */
  tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.ImageOuterClass.ImageOrBuilder getGiftImageOrBuilder();
  /**
   * <code>uint64 agree_msg_id = 11;</code>
   * @return The agreeMsgId.
   */
  long getAgreeMsgId();
  /**
   * <code>uint32 priority_level = 12;</code>
   * @return The priorityLevel.
   */
  int getPriorityLevel();
  /**
   * <pre>
   * LandscapeAreaCommon landscape_area_common = 13;
   * </pre>
   *
   * <code>uint64 event_time = 15;</code>
   * @return The eventTime.
   */
  long getEventTime();
  /**
   * <code>bool send_review = 16;</code>
   * @return The sendReview.
   */
  boolean getSendReview();
  /**
   * <code>bool from_intercom = 17;</code>
   * @return The fromIntercom.
   */
  boolean getFromIntercom();
  /**
   * <code>bool intercom_hide_user_card = 18;</code>
   * @return The intercomHideUserCard.
   */
  boolean getIntercomHideUserCard();
  /**
   * <pre>
   * repeated string chatTagsList = 19;
   * </pre>
   *
   * <code>string chat_by = 20;</code>
   * @return The chatBy.
   */
  java.lang.String getChatBy();
  /**
   * <pre>
   * repeated string chatTagsList = 19;
   * </pre>
   *
   * <code>string chat_by = 20;</code>
   * @return The bytes for chatBy.
   */
  com.google.protobuf.ByteString
      getChatByBytes();
  /**
   * <pre>
   * Text rtf_content = 22 ;
   * </pre>
   *
   * <code>uint32 individual_chat_priority = 21;</code>
   * @return The individualChatPriority.
   */
  int getIndividualChatPriority();
}
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_gift_message_msg.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3963 @@
/*
 * 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_webcast_gift_message_msg.proto
package tech.ordinaryroad.live.chat.client.douyin.protobuf;
/**
 * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg}
 */
public final class douyin_webcast_gift_message_msg extends
    com.google.protobuf.GeneratedMessageV3 implements
    // @@protoc_insertion_point(message_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg)
    douyin_webcast_gift_message_msgOrBuilder {
  private static final long serialVersionUID = 0L;
  // Use douyin_webcast_gift_message_msg.newBuilder() to construct.
  private douyin_webcast_gift_message_msg(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
    super(builder);
  }
  private douyin_webcast_gift_message_msg() {
    logId_ = "";
    interactGiftInfo_ = "";
    diyItemInfo_ = "";
    minAssetSetList_ = emptyLongList();
    toUserIdsList_ = emptyLongList();
    traceId_ = "";
  }
  @java.lang.Override
  @SuppressWarnings({"unused"})
  protected java.lang.Object newInstance(
      UnusedPrivateParameter unused) {
    return new douyin_webcast_gift_message_msg();
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_gift_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_descriptor;
  }
  @java.lang.Override
  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internalGetFieldAccessorTable() {
    return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_gift_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.Builder.class);
  }
  public static final int COMMON_FIELD_NUMBER = 1;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common common_;
  /**
   * <code>.Common common = 1;</code>
   * @return Whether the common field is set.
   */
  @java.lang.Override
  public boolean hasCommon() {
    return common_ != null;
  }
  /**
   * <code>.Common common = 1;</code>
   * @return The common.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common getCommon() {
    return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
  }
  /**
   * <code>.Common common = 1;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder getCommonOrBuilder() {
    return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
  }
  public static final int LONG_GIFT_ID_FIELD_NUMBER = 2;
  private long longGiftId_ = 0L;
  /**
   * <code>uint64 long_gift_id = 2;</code>
   * @return The longGiftId.
   */
  @java.lang.Override
  public long getLongGiftId() {
    return longGiftId_;
  }
  public static final int FAN_TICKET_COUNT_FIELD_NUMBER = 3;
  private long fanTicketCount_ = 0L;
  /**
   * <code>uint64 fan_ticket_count = 3;</code>
   * @return The fanTicketCount.
   */
  @java.lang.Override
  public long getFanTicketCount() {
    return fanTicketCount_;
  }
  public static final int GROUP_COUNT_FIELD_NUMBER = 4;
  private long groupCount_ = 0L;
  /**
   * <code>uint64 group_count = 4;</code>
   * @return The groupCount.
   */
  @java.lang.Override
  public long getGroupCount() {
    return groupCount_;
  }
  public static final int REPEAT_COUNT_FIELD_NUMBER = 5;
  private long repeatCount_ = 0L;
  /**
   * <code>uint64 repeat_count = 5;</code>
   * @return The repeatCount.
   */
  @java.lang.Override
  public long getRepeatCount() {
    return repeatCount_;
  }
  public static final int COMBO_COUNT_FIELD_NUMBER = 6;
  private long comboCount_ = 0L;
  /**
   * <code>uint64 combo_count = 6;</code>
   * @return The comboCount.
   */
  @java.lang.Override
  public long getComboCount() {
    return comboCount_;
  }
  public static final int USER_FIELD_NUMBER = 7;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User user_;
  /**
   * <code>.User user = 7;</code>
   * @return Whether the user field is set.
   */
  @java.lang.Override
  public boolean hasUser() {
    return user_ != null;
  }
  /**
   * <code>.User user = 7;</code>
   * @return The user.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getUser() {
    return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
  }
  /**
   * <code>.User user = 7;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getUserOrBuilder() {
    return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
  }
  public static final int TO_USER_FIELD_NUMBER = 8;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User toUser_;
  /**
   * <code>.User to_user = 8;</code>
   * @return Whether the toUser field is set.
   */
  @java.lang.Override
  public boolean hasToUser() {
    return toUser_ != null;
  }
  /**
   * <code>.User to_user = 8;</code>
   * @return The toUser.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getToUser() {
    return toUser_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : toUser_;
  }
  /**
   * <code>.User to_user = 8;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getToUserOrBuilder() {
    return toUser_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : toUser_;
  }
  public static final int REPEAT_END_FIELD_NUMBER = 9;
  private int repeatEnd_ = 0;
  /**
   * <code>uint32 repeat_end = 9;</code>
   * @return The repeatEnd.
   */
  @java.lang.Override
  public int getRepeatEnd() {
    return repeatEnd_;
  }
  public static final int TEXT_EFFECT_FIELD_NUMBER = 10;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect textEffect_;
  /**
   * <code>.TextEffect text_effect = 10;</code>
   * @return Whether the textEffect field is set.
   */
  @java.lang.Override
  public boolean hasTextEffect() {
    return textEffect_ != null;
  }
  /**
   * <code>.TextEffect text_effect = 10;</code>
   * @return The textEffect.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect getTextEffect() {
    return textEffect_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.getDefaultInstance() : textEffect_;
  }
  /**
   * <code>.TextEffect text_effect = 10;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffectOrBuilder getTextEffectOrBuilder() {
    return textEffect_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.getDefaultInstance() : textEffect_;
  }
  public static final int GROUP_ID_FIELD_NUMBER = 11;
  private long groupId_ = 0L;
  /**
   * <code>uint64 group_id = 11;</code>
   * @return The groupId.
   */
  @java.lang.Override
  public long getGroupId() {
    return groupId_;
  }
  public static final int INCOME_TASKGIFTS_FIELD_NUMBER = 12;
  private long incomeTaskgifts_ = 0L;
  /**
   * <code>uint64 income_taskgifts = 12;</code>
   * @return The incomeTaskgifts.
   */
  @java.lang.Override
  public long getIncomeTaskgifts() {
    return incomeTaskgifts_;
  }
  public static final int ROOM_FAN_TICKET_COUNT_FIELD_NUMBER = 13;
  private long roomFanTicketCount_ = 0L;
  /**
   * <code>uint64 room_fan_ticket_count = 13;</code>
   * @return The roomFanTicketCount.
   */
  @java.lang.Override
  public long getRoomFanTicketCount() {
    return roomFanTicketCount_;
  }
  public static final int PRIORITY_FIELD_NUMBER = 14;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority priority_;
  /**
   * <code>.GiftIMPriority priority = 14;</code>
   * @return Whether the priority field is set.
   */
  @java.lang.Override
  public boolean hasPriority() {
    return priority_ != null;
  }
  /**
   * <code>.GiftIMPriority priority = 14;</code>
   * @return The priority.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority getPriority() {
    return priority_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.getDefaultInstance() : priority_;
  }
  /**
   * <code>.GiftIMPriority priority = 14;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriorityOrBuilder getPriorityOrBuilder() {
    return priority_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.getDefaultInstance() : priority_;
  }
  public static final int GIFT_FIELD_NUMBER = 15;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct gift_;
  /**
   * <code>.GiftStruct gift = 15;</code>
   * @return Whether the gift field is set.
   */
  @java.lang.Override
  public boolean hasGift() {
    return gift_ != null;
  }
  /**
   * <code>.GiftStruct gift = 15;</code>
   * @return The gift.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct getGift() {
    return gift_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.getDefaultInstance() : gift_;
  }
  /**
   * <code>.GiftStruct gift = 15;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStructOrBuilder getGiftOrBuilder() {
    return gift_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.getDefaultInstance() : gift_;
  }
  public static final int LOG_ID_FIELD_NUMBER = 16;
  @SuppressWarnings("serial")
  private volatile java.lang.Object logId_ = "";
  /**
   * <code>string log_id = 16;</code>
   * @return The logId.
   */
  @java.lang.Override
  public java.lang.String getLogId() {
    java.lang.Object ref = logId_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      logId_ = s;
      return s;
    }
  }
  /**
   * <code>string log_id = 16;</code>
   * @return The bytes for logId.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getLogIdBytes() {
    java.lang.Object ref = logId_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      logId_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int SEND_TYPE_FIELD_NUMBER = 17;
  private long sendType_ = 0L;
  /**
   * <code>uint64 send_type = 17;</code>
   * @return The sendType.
   */
  @java.lang.Override
  public long getSendType() {
    return sendType_;
  }
  public static final int PUBLIC_AREA_COMMON_FIELD_NUMBER = 18;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon publicAreaCommon_;
  /**
   * <code>.PublicAreaCommon public_area_common = 18;</code>
   * @return Whether the publicAreaCommon field is set.
   */
  @java.lang.Override
  public boolean hasPublicAreaCommon() {
    return publicAreaCommon_ != null;
  }
  /**
   * <code>.PublicAreaCommon public_area_common = 18;</code>
   * @return The publicAreaCommon.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon getPublicAreaCommon() {
    return publicAreaCommon_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.getDefaultInstance() : publicAreaCommon_;
  }
  /**
   * <code>.PublicAreaCommon public_area_common = 18;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommonOrBuilder getPublicAreaCommonOrBuilder() {
    return publicAreaCommon_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.getDefaultInstance() : publicAreaCommon_;
  }
  public static final int TRAY_DISPLAY_TEXT_FIELD_NUMBER = 19;
  private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text trayDisplayText_;
  /**
   * <code>.Text tray_display_text = 19;</code>
   * @return Whether the trayDisplayText field is set.
   */
  @java.lang.Override
  public boolean hasTrayDisplayText() {
    return trayDisplayText_ != null;
  }
  /**
   * <code>.Text tray_display_text = 19;</code>
   * @return The trayDisplayText.
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text getTrayDisplayText() {
    return trayDisplayText_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.getDefaultInstance() : trayDisplayText_;
  }
  /**
   * <code>.Text tray_display_text = 19;</code>
   */
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.TextOrBuilder getTrayDisplayTextOrBuilder() {
    return trayDisplayText_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.getDefaultInstance() : trayDisplayText_;
  }
  public static final int BANNED_DISPLAY_EFFECTS_FIELD_NUMBER = 20;
  private long bannedDisplayEffects_ = 0L;
  /**
   * <code>uint64 banned_display_effects = 20;</code>
   * @return The bannedDisplayEffects.
   */
  @java.lang.Override
  public long getBannedDisplayEffects() {
    return bannedDisplayEffects_;
  }
  public static final int DISPLAY_FOR_SELF_FIELD_NUMBER = 25;
  private boolean displayForSelf_ = false;
  /**
   * <pre>
   * GiftTrayInfo trayInfo = 21;
   * AssetEffectMixInfo assetEffectMixInfo = 22;
   * </pre>
   *
   * <code>bool display_for_self = 25;</code>
   * @return The displayForSelf.
   */
  @java.lang.Override
  public boolean getDisplayForSelf() {
    return displayForSelf_;
  }
  public static final int INTERACT_GIFT_INFO_FIELD_NUMBER = 26;
  @SuppressWarnings("serial")
  private volatile java.lang.Object interactGiftInfo_ = "";
  /**
   * <code>string interact_gift_info = 26;</code>
   * @return The interactGiftInfo.
   */
  @java.lang.Override
  public java.lang.String getInteractGiftInfo() {
    java.lang.Object ref = interactGiftInfo_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      interactGiftInfo_ = s;
      return s;
    }
  }
  /**
   * <code>string interact_gift_info = 26;</code>
   * @return The bytes for interactGiftInfo.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getInteractGiftInfoBytes() {
    java.lang.Object ref = interactGiftInfo_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      interactGiftInfo_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int DIY_ITEM_INFO_FIELD_NUMBER = 27;
  @SuppressWarnings("serial")
  private volatile java.lang.Object diyItemInfo_ = "";
  /**
   * <code>string diy_item_info = 27;</code>
   * @return The diyItemInfo.
   */
  @java.lang.Override
  public java.lang.String getDiyItemInfo() {
    java.lang.Object ref = diyItemInfo_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      diyItemInfo_ = s;
      return s;
    }
  }
  /**
   * <code>string diy_item_info = 27;</code>
   * @return The bytes for diyItemInfo.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getDiyItemInfoBytes() {
    java.lang.Object ref = diyItemInfo_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      diyItemInfo_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int MIN_ASSET_SET_LIST_FIELD_NUMBER = 28;
  @SuppressWarnings("serial")
  private com.google.protobuf.Internal.LongList minAssetSetList_;
  /**
   * <code>repeated uint64 min_asset_set_list = 28;</code>
   * @return A list containing the minAssetSetList.
   */
  @java.lang.Override
  public java.util.List<java.lang.Long>
      getMinAssetSetListList() {
    return minAssetSetList_;
  }
  /**
   * <code>repeated uint64 min_asset_set_list = 28;</code>
   * @return The count of minAssetSetList.
   */
  public int getMinAssetSetListCount() {
    return minAssetSetList_.size();
  }
  /**
   * <code>repeated uint64 min_asset_set_list = 28;</code>
   * @param index The index of the element to return.
   * @return The minAssetSetList at the given index.
   */
  public long getMinAssetSetList(int index) {
    return minAssetSetList_.getLong(index);
  }
  private int minAssetSetListMemoizedSerializedSize = -1;
  public static final int TOTAL_COUNT_FIELD_NUMBER = 29;
  private long totalCount_ = 0L;
  /**
   * <code>uint64 total_count = 29;</code>
   * @return The totalCount.
   */
  @java.lang.Override
  public long getTotalCount() {
    return totalCount_;
  }
  public static final int CLIENT_GIFT_SOURCE_FIELD_NUMBER = 30;
  private int clientGiftSource_ = 0;
  /**
   * <code>uint32 client_gift_source = 30;</code>
   * @return The clientGiftSource.
   */
  @java.lang.Override
  public int getClientGiftSource() {
    return clientGiftSource_;
  }
  public static final int TO_USER_IDS_LIST_FIELD_NUMBER = 32;
  @SuppressWarnings("serial")
  private com.google.protobuf.Internal.LongList toUserIdsList_;
  /**
   * <pre>
   * AnchorGiftData anchorGift = 31;
   * </pre>
   *
   * <code>repeated uint64 to_user_ids_list = 32;</code>
   * @return A list containing the toUserIdsList.
   */
  @java.lang.Override
  public java.util.List<java.lang.Long>
      getToUserIdsListList() {
    return toUserIdsList_;
  }
  /**
   * <pre>
   * AnchorGiftData anchorGift = 31;
   * </pre>
   *
   * <code>repeated uint64 to_user_ids_list = 32;</code>
   * @return The count of toUserIdsList.
   */
  public int getToUserIdsListCount() {
    return toUserIdsList_.size();
  }
  /**
   * <pre>
   * AnchorGiftData anchorGift = 31;
   * </pre>
   *
   * <code>repeated uint64 to_user_ids_list = 32;</code>
   * @param index The index of the element to return.
   * @return The toUserIdsList at the given index.
   */
  public long getToUserIdsList(int index) {
    return toUserIdsList_.getLong(index);
  }
  private int toUserIdsListMemoizedSerializedSize = -1;
  public static final int SEND_TIMET_FIELD_NUMBER = 33;
  private long sendTimet_ = 0L;
  /**
   * <code>uint64 send_timet = 33;</code>
   * @return The sendTimet.
   */
  @java.lang.Override
  public long getSendTimet() {
    return sendTimet_;
  }
  public static final int FORCE_DISPLAY_EFFECTST_FIELD_NUMBER = 34;
  private long forceDisplayEffectst_ = 0L;
  /**
   * <code>uint64 force_display_effectst = 34;</code>
   * @return The forceDisplayEffectst.
   */
  @java.lang.Override
  public long getForceDisplayEffectst() {
    return forceDisplayEffectst_;
  }
  public static final int TRACE_ID_FIELD_NUMBER = 35;
  @SuppressWarnings("serial")
  private volatile java.lang.Object traceId_ = "";
  /**
   * <code>string trace_id = 35;</code>
   * @return The traceId.
   */
  @java.lang.Override
  public java.lang.String getTraceId() {
    java.lang.Object ref = traceId_;
    if (ref instanceof java.lang.String) {
      return (java.lang.String) ref;
    } else {
      com.google.protobuf.ByteString bs =
          (com.google.protobuf.ByteString) ref;
      java.lang.String s = bs.toStringUtf8();
      traceId_ = s;
      return s;
    }
  }
  /**
   * <code>string trace_id = 35;</code>
   * @return The bytes for traceId.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString
      getTraceIdBytes() {
    java.lang.Object ref = traceId_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b =
          com.google.protobuf.ByteString.copyFromUtf8(
              (java.lang.String) ref);
      traceId_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }
  public static final int EFFECT_DISPLAY_TS_FIELD_NUMBER = 36;
  private long effectDisplayTs_ = 0L;
  /**
   * <code>uint64 effect_display_ts = 36;</code>
   * @return The effectDisplayTs.
   */
  @java.lang.Override
  public long getEffectDisplayTs() {
    return effectDisplayTs_;
  }
  private byte memoizedIsInitialized = -1;
  @java.lang.Override
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized == 1) return true;
    if (isInitialized == 0) return false;
    memoizedIsInitialized = 1;
    return true;
  }
  @java.lang.Override
  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    getSerializedSize();
    if (common_ != null) {
      output.writeMessage(1, getCommon());
    }
    if (longGiftId_ != 0L) {
      output.writeUInt64(2, longGiftId_);
    }
    if (fanTicketCount_ != 0L) {
      output.writeUInt64(3, fanTicketCount_);
    }
    if (groupCount_ != 0L) {
      output.writeUInt64(4, groupCount_);
    }
    if (repeatCount_ != 0L) {
      output.writeUInt64(5, repeatCount_);
    }
    if (comboCount_ != 0L) {
      output.writeUInt64(6, comboCount_);
    }
    if (user_ != null) {
      output.writeMessage(7, getUser());
    }
    if (toUser_ != null) {
      output.writeMessage(8, getToUser());
    }
    if (repeatEnd_ != 0) {
      output.writeUInt32(9, repeatEnd_);
    }
    if (textEffect_ != null) {
      output.writeMessage(10, getTextEffect());
    }
    if (groupId_ != 0L) {
      output.writeUInt64(11, groupId_);
    }
    if (incomeTaskgifts_ != 0L) {
      output.writeUInt64(12, incomeTaskgifts_);
    }
    if (roomFanTicketCount_ != 0L) {
      output.writeUInt64(13, roomFanTicketCount_);
    }
    if (priority_ != null) {
      output.writeMessage(14, getPriority());
    }
    if (gift_ != null) {
      output.writeMessage(15, getGift());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logId_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 16, logId_);
    }
    if (sendType_ != 0L) {
      output.writeUInt64(17, sendType_);
    }
    if (publicAreaCommon_ != null) {
      output.writeMessage(18, getPublicAreaCommon());
    }
    if (trayDisplayText_ != null) {
      output.writeMessage(19, getTrayDisplayText());
    }
    if (bannedDisplayEffects_ != 0L) {
      output.writeUInt64(20, bannedDisplayEffects_);
    }
    if (displayForSelf_ != false) {
      output.writeBool(25, displayForSelf_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(interactGiftInfo_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 26, interactGiftInfo_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(diyItemInfo_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 27, diyItemInfo_);
    }
    if (getMinAssetSetListList().size() > 0) {
      output.writeUInt32NoTag(226);
      output.writeUInt32NoTag(minAssetSetListMemoizedSerializedSize);
    }
    for (int i = 0; i < minAssetSetList_.size(); i++) {
      output.writeUInt64NoTag(minAssetSetList_.getLong(i));
    }
    if (totalCount_ != 0L) {
      output.writeUInt64(29, totalCount_);
    }
    if (clientGiftSource_ != 0) {
      output.writeUInt32(30, clientGiftSource_);
    }
    if (getToUserIdsListList().size() > 0) {
      output.writeUInt32NoTag(258);
      output.writeUInt32NoTag(toUserIdsListMemoizedSerializedSize);
    }
    for (int i = 0; i < toUserIdsList_.size(); i++) {
      output.writeUInt64NoTag(toUserIdsList_.getLong(i));
    }
    if (sendTimet_ != 0L) {
      output.writeUInt64(33, sendTimet_);
    }
    if (forceDisplayEffectst_ != 0L) {
      output.writeUInt64(34, forceDisplayEffectst_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(traceId_)) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 35, traceId_);
    }
    if (effectDisplayTs_ != 0L) {
      output.writeUInt64(36, effectDisplayTs_);
    }
    getUnknownFields().writeTo(output);
  }
  @java.lang.Override
  public int getSerializedSize() {
    int size = memoizedSize;
    if (size != -1) return size;
    size = 0;
    if (common_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(1, getCommon());
    }
    if (longGiftId_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(2, longGiftId_);
    }
    if (fanTicketCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(3, fanTicketCount_);
    }
    if (groupCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(4, groupCount_);
    }
    if (repeatCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(5, repeatCount_);
    }
    if (comboCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(6, comboCount_);
    }
    if (user_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(7, getUser());
    }
    if (toUser_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(8, getToUser());
    }
    if (repeatEnd_ != 0) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt32Size(9, repeatEnd_);
    }
    if (textEffect_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(10, getTextEffect());
    }
    if (groupId_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(11, groupId_);
    }
    if (incomeTaskgifts_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(12, incomeTaskgifts_);
    }
    if (roomFanTicketCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(13, roomFanTicketCount_);
    }
    if (priority_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(14, getPriority());
    }
    if (gift_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(15, getGift());
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logId_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(16, logId_);
    }
    if (sendType_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(17, sendType_);
    }
    if (publicAreaCommon_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(18, getPublicAreaCommon());
    }
    if (trayDisplayText_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(19, getTrayDisplayText());
    }
    if (bannedDisplayEffects_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(20, bannedDisplayEffects_);
    }
    if (displayForSelf_ != false) {
      size += com.google.protobuf.CodedOutputStream
        .computeBoolSize(25, displayForSelf_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(interactGiftInfo_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(26, interactGiftInfo_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(diyItemInfo_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(27, diyItemInfo_);
    }
    {
      int dataSize = 0;
      for (int i = 0; i < minAssetSetList_.size(); i++) {
        dataSize += com.google.protobuf.CodedOutputStream
          .computeUInt64SizeNoTag(minAssetSetList_.getLong(i));
      }
      size += dataSize;
      if (!getMinAssetSetListList().isEmpty()) {
        size += 2;
        size += com.google.protobuf.CodedOutputStream
            .computeInt32SizeNoTag(dataSize);
      }
      minAssetSetListMemoizedSerializedSize = dataSize;
    }
    if (totalCount_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(29, totalCount_);
    }
    if (clientGiftSource_ != 0) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt32Size(30, clientGiftSource_);
    }
    {
      int dataSize = 0;
      for (int i = 0; i < toUserIdsList_.size(); i++) {
        dataSize += com.google.protobuf.CodedOutputStream
          .computeUInt64SizeNoTag(toUserIdsList_.getLong(i));
      }
      size += dataSize;
      if (!getToUserIdsListList().isEmpty()) {
        size += 2;
        size += com.google.protobuf.CodedOutputStream
            .computeInt32SizeNoTag(dataSize);
      }
      toUserIdsListMemoizedSerializedSize = dataSize;
    }
    if (sendTimet_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(33, sendTimet_);
    }
    if (forceDisplayEffectst_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(34, forceDisplayEffectst_);
    }
    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(traceId_)) {
      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(35, traceId_);
    }
    if (effectDisplayTs_ != 0L) {
      size += com.google.protobuf.CodedOutputStream
        .computeUInt64Size(36, effectDisplayTs_);
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSize = size;
    return size;
  }
  @java.lang.Override
  public boolean equals(final java.lang.Object obj) {
    if (obj == this) {
     return true;
    }
    if (!(obj instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg)) {
      return super.equals(obj);
    }
    tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg other = (tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg) obj;
    if (hasCommon() != other.hasCommon()) return false;
    if (hasCommon()) {
      if (!getCommon()
          .equals(other.getCommon())) return false;
    }
    if (getLongGiftId()
        != other.getLongGiftId()) return false;
    if (getFanTicketCount()
        != other.getFanTicketCount()) return false;
    if (getGroupCount()
        != other.getGroupCount()) return false;
    if (getRepeatCount()
        != other.getRepeatCount()) return false;
    if (getComboCount()
        != other.getComboCount()) return false;
    if (hasUser() != other.hasUser()) return false;
    if (hasUser()) {
      if (!getUser()
          .equals(other.getUser())) return false;
    }
    if (hasToUser() != other.hasToUser()) return false;
    if (hasToUser()) {
      if (!getToUser()
          .equals(other.getToUser())) return false;
    }
    if (getRepeatEnd()
        != other.getRepeatEnd()) return false;
    if (hasTextEffect() != other.hasTextEffect()) return false;
    if (hasTextEffect()) {
      if (!getTextEffect()
          .equals(other.getTextEffect())) return false;
    }
    if (getGroupId()
        != other.getGroupId()) return false;
    if (getIncomeTaskgifts()
        != other.getIncomeTaskgifts()) return false;
    if (getRoomFanTicketCount()
        != other.getRoomFanTicketCount()) return false;
    if (hasPriority() != other.hasPriority()) return false;
    if (hasPriority()) {
      if (!getPriority()
          .equals(other.getPriority())) return false;
    }
    if (hasGift() != other.hasGift()) return false;
    if (hasGift()) {
      if (!getGift()
          .equals(other.getGift())) return false;
    }
    if (!getLogId()
        .equals(other.getLogId())) return false;
    if (getSendType()
        != other.getSendType()) return false;
    if (hasPublicAreaCommon() != other.hasPublicAreaCommon()) return false;
    if (hasPublicAreaCommon()) {
      if (!getPublicAreaCommon()
          .equals(other.getPublicAreaCommon())) return false;
    }
    if (hasTrayDisplayText() != other.hasTrayDisplayText()) return false;
    if (hasTrayDisplayText()) {
      if (!getTrayDisplayText()
          .equals(other.getTrayDisplayText())) return false;
    }
    if (getBannedDisplayEffects()
        != other.getBannedDisplayEffects()) return false;
    if (getDisplayForSelf()
        != other.getDisplayForSelf()) return false;
    if (!getInteractGiftInfo()
        .equals(other.getInteractGiftInfo())) return false;
    if (!getDiyItemInfo()
        .equals(other.getDiyItemInfo())) return false;
    if (!getMinAssetSetListList()
        .equals(other.getMinAssetSetListList())) return false;
    if (getTotalCount()
        != other.getTotalCount()) return false;
    if (getClientGiftSource()
        != other.getClientGiftSource()) return false;
    if (!getToUserIdsListList()
        .equals(other.getToUserIdsListList())) return false;
    if (getSendTimet()
        != other.getSendTimet()) return false;
    if (getForceDisplayEffectst()
        != other.getForceDisplayEffectst()) return false;
    if (!getTraceId()
        .equals(other.getTraceId())) return false;
    if (getEffectDisplayTs()
        != other.getEffectDisplayTs()) return false;
    if (!getUnknownFields().equals(other.getUnknownFields())) return false;
    return true;
  }
  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    if (hasCommon()) {
      hash = (37 * hash) + COMMON_FIELD_NUMBER;
      hash = (53 * hash) + getCommon().hashCode();
    }
    hash = (37 * hash) + LONG_GIFT_ID_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getLongGiftId());
    hash = (37 * hash) + FAN_TICKET_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getFanTicketCount());
    hash = (37 * hash) + GROUP_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getGroupCount());
    hash = (37 * hash) + REPEAT_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getRepeatCount());
    hash = (37 * hash) + COMBO_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getComboCount());
    if (hasUser()) {
      hash = (37 * hash) + USER_FIELD_NUMBER;
      hash = (53 * hash) + getUser().hashCode();
    }
    if (hasToUser()) {
      hash = (37 * hash) + TO_USER_FIELD_NUMBER;
      hash = (53 * hash) + getToUser().hashCode();
    }
    hash = (37 * hash) + REPEAT_END_FIELD_NUMBER;
    hash = (53 * hash) + getRepeatEnd();
    if (hasTextEffect()) {
      hash = (37 * hash) + TEXT_EFFECT_FIELD_NUMBER;
      hash = (53 * hash) + getTextEffect().hashCode();
    }
    hash = (37 * hash) + GROUP_ID_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getGroupId());
    hash = (37 * hash) + INCOME_TASKGIFTS_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getIncomeTaskgifts());
    hash = (37 * hash) + ROOM_FAN_TICKET_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getRoomFanTicketCount());
    if (hasPriority()) {
      hash = (37 * hash) + PRIORITY_FIELD_NUMBER;
      hash = (53 * hash) + getPriority().hashCode();
    }
    if (hasGift()) {
      hash = (37 * hash) + GIFT_FIELD_NUMBER;
      hash = (53 * hash) + getGift().hashCode();
    }
    hash = (37 * hash) + LOG_ID_FIELD_NUMBER;
    hash = (53 * hash) + getLogId().hashCode();
    hash = (37 * hash) + SEND_TYPE_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getSendType());
    if (hasPublicAreaCommon()) {
      hash = (37 * hash) + PUBLIC_AREA_COMMON_FIELD_NUMBER;
      hash = (53 * hash) + getPublicAreaCommon().hashCode();
    }
    if (hasTrayDisplayText()) {
      hash = (37 * hash) + TRAY_DISPLAY_TEXT_FIELD_NUMBER;
      hash = (53 * hash) + getTrayDisplayText().hashCode();
    }
    hash = (37 * hash) + BANNED_DISPLAY_EFFECTS_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getBannedDisplayEffects());
    hash = (37 * hash) + DISPLAY_FOR_SELF_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
        getDisplayForSelf());
    hash = (37 * hash) + INTERACT_GIFT_INFO_FIELD_NUMBER;
    hash = (53 * hash) + getInteractGiftInfo().hashCode();
    hash = (37 * hash) + DIY_ITEM_INFO_FIELD_NUMBER;
    hash = (53 * hash) + getDiyItemInfo().hashCode();
    if (getMinAssetSetListCount() > 0) {
      hash = (37 * hash) + MIN_ASSET_SET_LIST_FIELD_NUMBER;
      hash = (53 * hash) + getMinAssetSetListList().hashCode();
    }
    hash = (37 * hash) + TOTAL_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getTotalCount());
    hash = (37 * hash) + CLIENT_GIFT_SOURCE_FIELD_NUMBER;
    hash = (53 * hash) + getClientGiftSource();
    if (getToUserIdsListCount() > 0) {
      hash = (37 * hash) + TO_USER_IDS_LIST_FIELD_NUMBER;
      hash = (53 * hash) + getToUserIdsListList().hashCode();
    }
    hash = (37 * hash) + SEND_TIMET_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getSendTimet());
    hash = (37 * hash) + FORCE_DISPLAY_EFFECTST_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getForceDisplayEffectst());
    hash = (37 * hash) + TRACE_ID_FIELD_NUMBER;
    hash = (53 * hash) + getTraceId().hashCode();
    hash = (37 * hash) + EFFECT_DISPLAY_TS_FIELD_NUMBER;
    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
        getEffectDisplayTs());
    hash = (29 * hash) + getUnknownFields().hashCode();
    memoizedHashCode = hash;
    return hash;
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      java.nio.ByteBuffer data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      java.nio.ByteBuffer data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseDelimitedWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg 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 tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input, extensionRegistry);
  }
  @java.lang.Override
  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder() {
    return DEFAULT_INSTANCE.toBuilder();
  }
  public static Builder newBuilder(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg prototype) {
    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
  }
  @java.lang.Override
  public Builder toBuilder() {
    return this == DEFAULT_INSTANCE
        ? new Builder() : new Builder().mergeFrom(this);
  }
  @java.lang.Override
  protected Builder newBuilderForType(
      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * Protobuf type {@code tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
      // @@protoc_insertion_point(builder_implements:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg)
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msgOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_gift_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_descriptor;
    }
    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_gift_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.class, tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.Builder.class);
    }
    // Construct using tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.newBuilder()
    private Builder() {
    }
    private Builder(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      super(parent);
    }
    @java.lang.Override
    public Builder clear() {
      super.clear();
      bitField0_ = 0;
      common_ = null;
      if (commonBuilder_ != null) {
        commonBuilder_.dispose();
        commonBuilder_ = null;
      }
      longGiftId_ = 0L;
      fanTicketCount_ = 0L;
      groupCount_ = 0L;
      repeatCount_ = 0L;
      comboCount_ = 0L;
      user_ = null;
      if (userBuilder_ != null) {
        userBuilder_.dispose();
        userBuilder_ = null;
      }
      toUser_ = null;
      if (toUserBuilder_ != null) {
        toUserBuilder_.dispose();
        toUserBuilder_ = null;
      }
      repeatEnd_ = 0;
      textEffect_ = null;
      if (textEffectBuilder_ != null) {
        textEffectBuilder_.dispose();
        textEffectBuilder_ = null;
      }
      groupId_ = 0L;
      incomeTaskgifts_ = 0L;
      roomFanTicketCount_ = 0L;
      priority_ = null;
      if (priorityBuilder_ != null) {
        priorityBuilder_.dispose();
        priorityBuilder_ = null;
      }
      gift_ = null;
      if (giftBuilder_ != null) {
        giftBuilder_.dispose();
        giftBuilder_ = null;
      }
      logId_ = "";
      sendType_ = 0L;
      publicAreaCommon_ = null;
      if (publicAreaCommonBuilder_ != null) {
        publicAreaCommonBuilder_.dispose();
        publicAreaCommonBuilder_ = null;
      }
      trayDisplayText_ = null;
      if (trayDisplayTextBuilder_ != null) {
        trayDisplayTextBuilder_.dispose();
        trayDisplayTextBuilder_ = null;
      }
      bannedDisplayEffects_ = 0L;
      displayForSelf_ = false;
      interactGiftInfo_ = "";
      diyItemInfo_ = "";
      minAssetSetList_ = emptyLongList();
      totalCount_ = 0L;
      clientGiftSource_ = 0;
      toUserIdsList_ = emptyLongList();
      sendTimet_ = 0L;
      forceDisplayEffectst_ = 0L;
      traceId_ = "";
      effectDisplayTs_ = 0L;
      return this;
    }
    @java.lang.Override
    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.Douyin_webcast_gift_message_msgProto.internal_static_tech_ordinaryroad_live_chat_client_douyin_protobuf_douyin_webcast_gift_message_msg_descriptor;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg getDefaultInstanceForType() {
      return tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.getDefaultInstance();
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg build() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }
    @java.lang.Override
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg buildPartial() {
      tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg result = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg(this);
      buildPartialRepeatedFields(result);
      if (bitField0_ != 0) { buildPartial0(result); }
      onBuilt();
      return result;
    }
    private void buildPartialRepeatedFields(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg result) {
      if (((bitField0_ & 0x00800000) != 0)) {
        minAssetSetList_.makeImmutable();
        bitField0_ = (bitField0_ & ~0x00800000);
      }
      result.minAssetSetList_ = minAssetSetList_;
      if (((bitField0_ & 0x04000000) != 0)) {
        toUserIdsList_.makeImmutable();
        bitField0_ = (bitField0_ & ~0x04000000);
      }
      result.toUserIdsList_ = toUserIdsList_;
    }
    private void buildPartial0(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg result) {
      int from_bitField0_ = bitField0_;
      if (((from_bitField0_ & 0x00000001) != 0)) {
        result.common_ = commonBuilder_ == null
            ? common_
            : commonBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000002) != 0)) {
        result.longGiftId_ = longGiftId_;
      }
      if (((from_bitField0_ & 0x00000004) != 0)) {
        result.fanTicketCount_ = fanTicketCount_;
      }
      if (((from_bitField0_ & 0x00000008) != 0)) {
        result.groupCount_ = groupCount_;
      }
      if (((from_bitField0_ & 0x00000010) != 0)) {
        result.repeatCount_ = repeatCount_;
      }
      if (((from_bitField0_ & 0x00000020) != 0)) {
        result.comboCount_ = comboCount_;
      }
      if (((from_bitField0_ & 0x00000040) != 0)) {
        result.user_ = userBuilder_ == null
            ? user_
            : userBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000080) != 0)) {
        result.toUser_ = toUserBuilder_ == null
            ? toUser_
            : toUserBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000100) != 0)) {
        result.repeatEnd_ = repeatEnd_;
      }
      if (((from_bitField0_ & 0x00000200) != 0)) {
        result.textEffect_ = textEffectBuilder_ == null
            ? textEffect_
            : textEffectBuilder_.build();
      }
      if (((from_bitField0_ & 0x00000400) != 0)) {
        result.groupId_ = groupId_;
      }
      if (((from_bitField0_ & 0x00000800) != 0)) {
        result.incomeTaskgifts_ = incomeTaskgifts_;
      }
      if (((from_bitField0_ & 0x00001000) != 0)) {
        result.roomFanTicketCount_ = roomFanTicketCount_;
      }
      if (((from_bitField0_ & 0x00002000) != 0)) {
        result.priority_ = priorityBuilder_ == null
            ? priority_
            : priorityBuilder_.build();
      }
      if (((from_bitField0_ & 0x00004000) != 0)) {
        result.gift_ = giftBuilder_ == null
            ? gift_
            : giftBuilder_.build();
      }
      if (((from_bitField0_ & 0x00008000) != 0)) {
        result.logId_ = logId_;
      }
      if (((from_bitField0_ & 0x00010000) != 0)) {
        result.sendType_ = sendType_;
      }
      if (((from_bitField0_ & 0x00020000) != 0)) {
        result.publicAreaCommon_ = publicAreaCommonBuilder_ == null
            ? publicAreaCommon_
            : publicAreaCommonBuilder_.build();
      }
      if (((from_bitField0_ & 0x00040000) != 0)) {
        result.trayDisplayText_ = trayDisplayTextBuilder_ == null
            ? trayDisplayText_
            : trayDisplayTextBuilder_.build();
      }
      if (((from_bitField0_ & 0x00080000) != 0)) {
        result.bannedDisplayEffects_ = bannedDisplayEffects_;
      }
      if (((from_bitField0_ & 0x00100000) != 0)) {
        result.displayForSelf_ = displayForSelf_;
      }
      if (((from_bitField0_ & 0x00200000) != 0)) {
        result.interactGiftInfo_ = interactGiftInfo_;
      }
      if (((from_bitField0_ & 0x00400000) != 0)) {
        result.diyItemInfo_ = diyItemInfo_;
      }
      if (((from_bitField0_ & 0x01000000) != 0)) {
        result.totalCount_ = totalCount_;
      }
      if (((from_bitField0_ & 0x02000000) != 0)) {
        result.clientGiftSource_ = clientGiftSource_;
      }
      if (((from_bitField0_ & 0x08000000) != 0)) {
        result.sendTimet_ = sendTimet_;
      }
      if (((from_bitField0_ & 0x10000000) != 0)) {
        result.forceDisplayEffectst_ = forceDisplayEffectst_;
      }
      if (((from_bitField0_ & 0x20000000) != 0)) {
        result.traceId_ = traceId_;
      }
      if (((from_bitField0_ & 0x40000000) != 0)) {
        result.effectDisplayTs_ = effectDisplayTs_;
      }
    }
    @java.lang.Override
    public Builder clone() {
      return super.clone();
    }
    @java.lang.Override
    public Builder setField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.setField(field, value);
    }
    @java.lang.Override
    public Builder clearField(
        com.google.protobuf.Descriptors.FieldDescriptor field) {
      return super.clearField(field);
    }
    @java.lang.Override
    public Builder clearOneof(
        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
      return super.clearOneof(oneof);
    }
    @java.lang.Override
    public Builder setRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        int index, java.lang.Object value) {
      return super.setRepeatedField(field, index, value);
    }
    @java.lang.Override
    public Builder addRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return super.addRepeatedField(field, value);
    }
    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg) {
        return mergeFrom((tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }
    public Builder mergeFrom(tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg other) {
      if (other == tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg.getDefaultInstance()) return this;
      if (other.hasCommon()) {
        mergeCommon(other.getCommon());
      }
      if (other.getLongGiftId() != 0L) {
        setLongGiftId(other.getLongGiftId());
      }
      if (other.getFanTicketCount() != 0L) {
        setFanTicketCount(other.getFanTicketCount());
      }
      if (other.getGroupCount() != 0L) {
        setGroupCount(other.getGroupCount());
      }
      if (other.getRepeatCount() != 0L) {
        setRepeatCount(other.getRepeatCount());
      }
      if (other.getComboCount() != 0L) {
        setComboCount(other.getComboCount());
      }
      if (other.hasUser()) {
        mergeUser(other.getUser());
      }
      if (other.hasToUser()) {
        mergeToUser(other.getToUser());
      }
      if (other.getRepeatEnd() != 0) {
        setRepeatEnd(other.getRepeatEnd());
      }
      if (other.hasTextEffect()) {
        mergeTextEffect(other.getTextEffect());
      }
      if (other.getGroupId() != 0L) {
        setGroupId(other.getGroupId());
      }
      if (other.getIncomeTaskgifts() != 0L) {
        setIncomeTaskgifts(other.getIncomeTaskgifts());
      }
      if (other.getRoomFanTicketCount() != 0L) {
        setRoomFanTicketCount(other.getRoomFanTicketCount());
      }
      if (other.hasPriority()) {
        mergePriority(other.getPriority());
      }
      if (other.hasGift()) {
        mergeGift(other.getGift());
      }
      if (!other.getLogId().isEmpty()) {
        logId_ = other.logId_;
        bitField0_ |= 0x00008000;
        onChanged();
      }
      if (other.getSendType() != 0L) {
        setSendType(other.getSendType());
      }
      if (other.hasPublicAreaCommon()) {
        mergePublicAreaCommon(other.getPublicAreaCommon());
      }
      if (other.hasTrayDisplayText()) {
        mergeTrayDisplayText(other.getTrayDisplayText());
      }
      if (other.getBannedDisplayEffects() != 0L) {
        setBannedDisplayEffects(other.getBannedDisplayEffects());
      }
      if (other.getDisplayForSelf() != false) {
        setDisplayForSelf(other.getDisplayForSelf());
      }
      if (!other.getInteractGiftInfo().isEmpty()) {
        interactGiftInfo_ = other.interactGiftInfo_;
        bitField0_ |= 0x00200000;
        onChanged();
      }
      if (!other.getDiyItemInfo().isEmpty()) {
        diyItemInfo_ = other.diyItemInfo_;
        bitField0_ |= 0x00400000;
        onChanged();
      }
      if (!other.minAssetSetList_.isEmpty()) {
        if (minAssetSetList_.isEmpty()) {
          minAssetSetList_ = other.minAssetSetList_;
          bitField0_ = (bitField0_ & ~0x00800000);
        } else {
          ensureMinAssetSetListIsMutable();
          minAssetSetList_.addAll(other.minAssetSetList_);
        }
        onChanged();
      }
      if (other.getTotalCount() != 0L) {
        setTotalCount(other.getTotalCount());
      }
      if (other.getClientGiftSource() != 0) {
        setClientGiftSource(other.getClientGiftSource());
      }
      if (!other.toUserIdsList_.isEmpty()) {
        if (toUserIdsList_.isEmpty()) {
          toUserIdsList_ = other.toUserIdsList_;
          bitField0_ = (bitField0_ & ~0x04000000);
        } else {
          ensureToUserIdsListIsMutable();
          toUserIdsList_.addAll(other.toUserIdsList_);
        }
        onChanged();
      }
      if (other.getSendTimet() != 0L) {
        setSendTimet(other.getSendTimet());
      }
      if (other.getForceDisplayEffectst() != 0L) {
        setForceDisplayEffectst(other.getForceDisplayEffectst());
      }
      if (!other.getTraceId().isEmpty()) {
        traceId_ = other.traceId_;
        bitField0_ |= 0x20000000;
        onChanged();
      }
      if (other.getEffectDisplayTs() != 0L) {
        setEffectDisplayTs(other.getEffectDisplayTs());
      }
      this.mergeUnknownFields(other.getUnknownFields());
      onChanged();
      return this;
    }
    @java.lang.Override
    public final boolean isInitialized() {
      return true;
    }
    @java.lang.Override
    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              input.readMessage(
                  getCommonFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000001;
              break;
            } // case 10
            case 16: {
              longGiftId_ = input.readUInt64();
              bitField0_ |= 0x00000002;
              break;
            } // case 16
            case 24: {
              fanTicketCount_ = input.readUInt64();
              bitField0_ |= 0x00000004;
              break;
            } // case 24
            case 32: {
              groupCount_ = input.readUInt64();
              bitField0_ |= 0x00000008;
              break;
            } // case 32
            case 40: {
              repeatCount_ = input.readUInt64();
              bitField0_ |= 0x00000010;
              break;
            } // case 40
            case 48: {
              comboCount_ = input.readUInt64();
              bitField0_ |= 0x00000020;
              break;
            } // case 48
            case 58: {
              input.readMessage(
                  getUserFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000040;
              break;
            } // case 58
            case 66: {
              input.readMessage(
                  getToUserFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000080;
              break;
            } // case 66
            case 72: {
              repeatEnd_ = input.readUInt32();
              bitField0_ |= 0x00000100;
              break;
            } // case 72
            case 82: {
              input.readMessage(
                  getTextEffectFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00000200;
              break;
            } // case 82
            case 88: {
              groupId_ = input.readUInt64();
              bitField0_ |= 0x00000400;
              break;
            } // case 88
            case 96: {
              incomeTaskgifts_ = input.readUInt64();
              bitField0_ |= 0x00000800;
              break;
            } // case 96
            case 104: {
              roomFanTicketCount_ = input.readUInt64();
              bitField0_ |= 0x00001000;
              break;
            } // case 104
            case 114: {
              input.readMessage(
                  getPriorityFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00002000;
              break;
            } // case 114
            case 122: {
              input.readMessage(
                  getGiftFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00004000;
              break;
            } // case 122
            case 130: {
              logId_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00008000;
              break;
            } // case 130
            case 136: {
              sendType_ = input.readUInt64();
              bitField0_ |= 0x00010000;
              break;
            } // case 136
            case 146: {
              input.readMessage(
                  getPublicAreaCommonFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00020000;
              break;
            } // case 146
            case 154: {
              input.readMessage(
                  getTrayDisplayTextFieldBuilder().getBuilder(),
                  extensionRegistry);
              bitField0_ |= 0x00040000;
              break;
            } // case 154
            case 160: {
              bannedDisplayEffects_ = input.readUInt64();
              bitField0_ |= 0x00080000;
              break;
            } // case 160
            case 200: {
              displayForSelf_ = input.readBool();
              bitField0_ |= 0x00100000;
              break;
            } // case 200
            case 210: {
              interactGiftInfo_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00200000;
              break;
            } // case 210
            case 218: {
              diyItemInfo_ = input.readStringRequireUtf8();
              bitField0_ |= 0x00400000;
              break;
            } // case 218
            case 224: {
              long v = input.readUInt64();
              ensureMinAssetSetListIsMutable();
              minAssetSetList_.addLong(v);
              break;
            } // case 224
            case 226: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              ensureMinAssetSetListIsMutable();
              while (input.getBytesUntilLimit() > 0) {
                minAssetSetList_.addLong(input.readUInt64());
              }
              input.popLimit(limit);
              break;
            } // case 226
            case 232: {
              totalCount_ = input.readUInt64();
              bitField0_ |= 0x01000000;
              break;
            } // case 232
            case 240: {
              clientGiftSource_ = input.readUInt32();
              bitField0_ |= 0x02000000;
              break;
            } // case 240
            case 256: {
              long v = input.readUInt64();
              ensureToUserIdsListIsMutable();
              toUserIdsList_.addLong(v);
              break;
            } // case 256
            case 258: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              ensureToUserIdsListIsMutable();
              while (input.getBytesUntilLimit() > 0) {
                toUserIdsList_.addLong(input.readUInt64());
              }
              input.popLimit(limit);
              break;
            } // case 258
            case 264: {
              sendTimet_ = input.readUInt64();
              bitField0_ |= 0x08000000;
              break;
            } // case 264
            case 272: {
              forceDisplayEffectst_ = input.readUInt64();
              bitField0_ |= 0x10000000;
              break;
            } // case 272
            case 282: {
              traceId_ = input.readStringRequireUtf8();
              bitField0_ |= 0x20000000;
              break;
            } // case 282
            case 288: {
              effectDisplayTs_ = input.readUInt64();
              bitField0_ |= 0x40000000;
              break;
            } // case 288
            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 tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common common_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder> commonBuilder_;
    /**
     * <code>.Common common = 1;</code>
     * @return Whether the common field is set.
     */
    public boolean hasCommon() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>.Common common = 1;</code>
     * @return The common.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common getCommon() {
      if (commonBuilder_ == null) {
        return common_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
      } else {
        return commonBuilder_.getMessage();
      }
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder setCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common value) {
      if (commonBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        common_ = value;
      } else {
        commonBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder setCommon(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder builderForValue) {
      if (commonBuilder_ == null) {
        common_ = builderForValue.build();
      } else {
        commonBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder mergeCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common value) {
      if (commonBuilder_ == null) {
        if (((bitField0_ & 0x00000001) != 0) &&
          common_ != null &&
          common_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance()) {
          getCommonBuilder().mergeFrom(value);
        } else {
          common_ = value;
        }
      } else {
        commonBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public Builder clearCommon() {
      bitField0_ = (bitField0_ & ~0x00000001);
      common_ = null;
      if (commonBuilder_ != null) {
        commonBuilder_.dispose();
        commonBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder getCommonBuilder() {
      bitField0_ |= 0x00000001;
      onChanged();
      return getCommonFieldBuilder().getBuilder();
    }
    /**
     * <code>.Common common = 1;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder getCommonOrBuilder() {
      if (commonBuilder_ != null) {
        return commonBuilder_.getMessageOrBuilder();
      } else {
        return common_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.getDefaultInstance() : common_;
      }
    }
    /**
     * <code>.Common common = 1;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder>
        getCommonFieldBuilder() {
      if (commonBuilder_ == null) {
        commonBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.Common.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.CommonOuterClass.CommonOrBuilder>(
                getCommon(),
                getParentForChildren(),
                isClean());
        common_ = null;
      }
      return commonBuilder_;
    }
    private long longGiftId_ ;
    /**
     * <code>uint64 long_gift_id = 2;</code>
     * @return The longGiftId.
     */
    @java.lang.Override
    public long getLongGiftId() {
      return longGiftId_;
    }
    /**
     * <code>uint64 long_gift_id = 2;</code>
     * @param value The longGiftId to set.
     * @return This builder for chaining.
     */
    public Builder setLongGiftId(long value) {
      longGiftId_ = value;
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 long_gift_id = 2;</code>
     * @return This builder for chaining.
     */
    public Builder clearLongGiftId() {
      bitField0_ = (bitField0_ & ~0x00000002);
      longGiftId_ = 0L;
      onChanged();
      return this;
    }
    private long fanTicketCount_ ;
    /**
     * <code>uint64 fan_ticket_count = 3;</code>
     * @return The fanTicketCount.
     */
    @java.lang.Override
    public long getFanTicketCount() {
      return fanTicketCount_;
    }
    /**
     * <code>uint64 fan_ticket_count = 3;</code>
     * @param value The fanTicketCount to set.
     * @return This builder for chaining.
     */
    public Builder setFanTicketCount(long value) {
      fanTicketCount_ = value;
      bitField0_ |= 0x00000004;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 fan_ticket_count = 3;</code>
     * @return This builder for chaining.
     */
    public Builder clearFanTicketCount() {
      bitField0_ = (bitField0_ & ~0x00000004);
      fanTicketCount_ = 0L;
      onChanged();
      return this;
    }
    private long groupCount_ ;
    /**
     * <code>uint64 group_count = 4;</code>
     * @return The groupCount.
     */
    @java.lang.Override
    public long getGroupCount() {
      return groupCount_;
    }
    /**
     * <code>uint64 group_count = 4;</code>
     * @param value The groupCount to set.
     * @return This builder for chaining.
     */
    public Builder setGroupCount(long value) {
      groupCount_ = value;
      bitField0_ |= 0x00000008;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 group_count = 4;</code>
     * @return This builder for chaining.
     */
    public Builder clearGroupCount() {
      bitField0_ = (bitField0_ & ~0x00000008);
      groupCount_ = 0L;
      onChanged();
      return this;
    }
    private long repeatCount_ ;
    /**
     * <code>uint64 repeat_count = 5;</code>
     * @return The repeatCount.
     */
    @java.lang.Override
    public long getRepeatCount() {
      return repeatCount_;
    }
    /**
     * <code>uint64 repeat_count = 5;</code>
     * @param value The repeatCount to set.
     * @return This builder for chaining.
     */
    public Builder setRepeatCount(long value) {
      repeatCount_ = value;
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 repeat_count = 5;</code>
     * @return This builder for chaining.
     */
    public Builder clearRepeatCount() {
      bitField0_ = (bitField0_ & ~0x00000010);
      repeatCount_ = 0L;
      onChanged();
      return this;
    }
    private long comboCount_ ;
    /**
     * <code>uint64 combo_count = 6;</code>
     * @return The comboCount.
     */
    @java.lang.Override
    public long getComboCount() {
      return comboCount_;
    }
    /**
     * <code>uint64 combo_count = 6;</code>
     * @param value The comboCount to set.
     * @return This builder for chaining.
     */
    public Builder setComboCount(long value) {
      comboCount_ = value;
      bitField0_ |= 0x00000020;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 combo_count = 6;</code>
     * @return This builder for chaining.
     */
    public Builder clearComboCount() {
      bitField0_ = (bitField0_ & ~0x00000020);
      comboCount_ = 0L;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User user_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder> userBuilder_;
    /**
     * <code>.User user = 7;</code>
     * @return Whether the user field is set.
     */
    public boolean hasUser() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>.User user = 7;</code>
     * @return The user.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getUser() {
      if (userBuilder_ == null) {
        return user_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
      } else {
        return userBuilder_.getMessage();
      }
    }
    /**
     * <code>.User user = 7;</code>
     */
    public Builder setUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (userBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        user_ = value;
      } else {
        userBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 7;</code>
     */
    public Builder setUser(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder builderForValue) {
      if (userBuilder_ == null) {
        user_ = builderForValue.build();
      } else {
        userBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 7;</code>
     */
    public Builder mergeUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (userBuilder_ == null) {
        if (((bitField0_ & 0x00000040) != 0) &&
          user_ != null &&
          user_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance()) {
          getUserBuilder().mergeFrom(value);
        } else {
          user_ = value;
        }
      } else {
        userBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 7;</code>
     */
    public Builder clearUser() {
      bitField0_ = (bitField0_ & ~0x00000040);
      user_ = null;
      if (userBuilder_ != null) {
        userBuilder_.dispose();
        userBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.User user = 7;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder getUserBuilder() {
      bitField0_ |= 0x00000040;
      onChanged();
      return getUserFieldBuilder().getBuilder();
    }
    /**
     * <code>.User user = 7;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getUserOrBuilder() {
      if (userBuilder_ != null) {
        return userBuilder_.getMessageOrBuilder();
      } else {
        return user_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : user_;
      }
    }
    /**
     * <code>.User user = 7;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>
        getUserFieldBuilder() {
      if (userBuilder_ == null) {
        userBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>(
                getUser(),
                getParentForChildren(),
                isClean());
        user_ = null;
      }
      return userBuilder_;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User toUser_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder> toUserBuilder_;
    /**
     * <code>.User to_user = 8;</code>
     * @return Whether the toUser field is set.
     */
    public boolean hasToUser() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>.User to_user = 8;</code>
     * @return The toUser.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User getToUser() {
      if (toUserBuilder_ == null) {
        return toUser_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : toUser_;
      } else {
        return toUserBuilder_.getMessage();
      }
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public Builder setToUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (toUserBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        toUser_ = value;
      } else {
        toUserBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public Builder setToUser(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder builderForValue) {
      if (toUserBuilder_ == null) {
        toUser_ = builderForValue.build();
      } else {
        toUserBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public Builder mergeToUser(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User value) {
      if (toUserBuilder_ == null) {
        if (((bitField0_ & 0x00000080) != 0) &&
          toUser_ != null &&
          toUser_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance()) {
          getToUserBuilder().mergeFrom(value);
        } else {
          toUser_ = value;
        }
      } else {
        toUserBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public Builder clearToUser() {
      bitField0_ = (bitField0_ & ~0x00000080);
      toUser_ = null;
      if (toUserBuilder_ != null) {
        toUserBuilder_.dispose();
        toUserBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder getToUserBuilder() {
      bitField0_ |= 0x00000080;
      onChanged();
      return getToUserFieldBuilder().getBuilder();
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder getToUserOrBuilder() {
      if (toUserBuilder_ != null) {
        return toUserBuilder_.getMessageOrBuilder();
      } else {
        return toUser_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.getDefaultInstance() : toUser_;
      }
    }
    /**
     * <code>.User to_user = 8;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>
        getToUserFieldBuilder() {
      if (toUserBuilder_ == null) {
        toUserBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.User.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.UserOuterClass.UserOrBuilder>(
                getToUser(),
                getParentForChildren(),
                isClean());
        toUser_ = null;
      }
      return toUserBuilder_;
    }
    private int repeatEnd_ ;
    /**
     * <code>uint32 repeat_end = 9;</code>
     * @return The repeatEnd.
     */
    @java.lang.Override
    public int getRepeatEnd() {
      return repeatEnd_;
    }
    /**
     * <code>uint32 repeat_end = 9;</code>
     * @param value The repeatEnd to set.
     * @return This builder for chaining.
     */
    public Builder setRepeatEnd(int value) {
      repeatEnd_ = value;
      bitField0_ |= 0x00000100;
      onChanged();
      return this;
    }
    /**
     * <code>uint32 repeat_end = 9;</code>
     * @return This builder for chaining.
     */
    public Builder clearRepeatEnd() {
      bitField0_ = (bitField0_ & ~0x00000100);
      repeatEnd_ = 0;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect textEffect_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffectOrBuilder> textEffectBuilder_;
    /**
     * <code>.TextEffect text_effect = 10;</code>
     * @return Whether the textEffect field is set.
     */
    public boolean hasTextEffect() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     * @return The textEffect.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect getTextEffect() {
      if (textEffectBuilder_ == null) {
        return textEffect_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.getDefaultInstance() : textEffect_;
      } else {
        return textEffectBuilder_.getMessage();
      }
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public Builder setTextEffect(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect value) {
      if (textEffectBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        textEffect_ = value;
      } else {
        textEffectBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00000200;
      onChanged();
      return this;
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public Builder setTextEffect(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.Builder builderForValue) {
      if (textEffectBuilder_ == null) {
        textEffect_ = builderForValue.build();
      } else {
        textEffectBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00000200;
      onChanged();
      return this;
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public Builder mergeTextEffect(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect value) {
      if (textEffectBuilder_ == null) {
        if (((bitField0_ & 0x00000200) != 0) &&
          textEffect_ != null &&
          textEffect_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.getDefaultInstance()) {
          getTextEffectBuilder().mergeFrom(value);
        } else {
          textEffect_ = value;
        }
      } else {
        textEffectBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00000200;
      onChanged();
      return this;
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public Builder clearTextEffect() {
      bitField0_ = (bitField0_ & ~0x00000200);
      textEffect_ = null;
      if (textEffectBuilder_ != null) {
        textEffectBuilder_.dispose();
        textEffectBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.Builder getTextEffectBuilder() {
      bitField0_ |= 0x00000200;
      onChanged();
      return getTextEffectFieldBuilder().getBuilder();
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffectOrBuilder getTextEffectOrBuilder() {
      if (textEffectBuilder_ != null) {
        return textEffectBuilder_.getMessageOrBuilder();
      } else {
        return textEffect_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.getDefaultInstance() : textEffect_;
      }
    }
    /**
     * <code>.TextEffect text_effect = 10;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffectOrBuilder>
        getTextEffectFieldBuilder() {
      if (textEffectBuilder_ == null) {
        textEffectBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffect.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextEffectOuterClass.TextEffectOrBuilder>(
                getTextEffect(),
                getParentForChildren(),
                isClean());
        textEffect_ = null;
      }
      return textEffectBuilder_;
    }
    private long groupId_ ;
    /**
     * <code>uint64 group_id = 11;</code>
     * @return The groupId.
     */
    @java.lang.Override
    public long getGroupId() {
      return groupId_;
    }
    /**
     * <code>uint64 group_id = 11;</code>
     * @param value The groupId to set.
     * @return This builder for chaining.
     */
    public Builder setGroupId(long value) {
      groupId_ = value;
      bitField0_ |= 0x00000400;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 group_id = 11;</code>
     * @return This builder for chaining.
     */
    public Builder clearGroupId() {
      bitField0_ = (bitField0_ & ~0x00000400);
      groupId_ = 0L;
      onChanged();
      return this;
    }
    private long incomeTaskgifts_ ;
    /**
     * <code>uint64 income_taskgifts = 12;</code>
     * @return The incomeTaskgifts.
     */
    @java.lang.Override
    public long getIncomeTaskgifts() {
      return incomeTaskgifts_;
    }
    /**
     * <code>uint64 income_taskgifts = 12;</code>
     * @param value The incomeTaskgifts to set.
     * @return This builder for chaining.
     */
    public Builder setIncomeTaskgifts(long value) {
      incomeTaskgifts_ = value;
      bitField0_ |= 0x00000800;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 income_taskgifts = 12;</code>
     * @return This builder for chaining.
     */
    public Builder clearIncomeTaskgifts() {
      bitField0_ = (bitField0_ & ~0x00000800);
      incomeTaskgifts_ = 0L;
      onChanged();
      return this;
    }
    private long roomFanTicketCount_ ;
    /**
     * <code>uint64 room_fan_ticket_count = 13;</code>
     * @return The roomFanTicketCount.
     */
    @java.lang.Override
    public long getRoomFanTicketCount() {
      return roomFanTicketCount_;
    }
    /**
     * <code>uint64 room_fan_ticket_count = 13;</code>
     * @param value The roomFanTicketCount to set.
     * @return This builder for chaining.
     */
    public Builder setRoomFanTicketCount(long value) {
      roomFanTicketCount_ = value;
      bitField0_ |= 0x00001000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 room_fan_ticket_count = 13;</code>
     * @return This builder for chaining.
     */
    public Builder clearRoomFanTicketCount() {
      bitField0_ = (bitField0_ & ~0x00001000);
      roomFanTicketCount_ = 0L;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority priority_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriorityOrBuilder> priorityBuilder_;
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     * @return Whether the priority field is set.
     */
    public boolean hasPriority() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     * @return The priority.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority getPriority() {
      if (priorityBuilder_ == null) {
        return priority_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.getDefaultInstance() : priority_;
      } else {
        return priorityBuilder_.getMessage();
      }
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public Builder setPriority(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority value) {
      if (priorityBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        priority_ = value;
      } else {
        priorityBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public Builder setPriority(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.Builder builderForValue) {
      if (priorityBuilder_ == null) {
        priority_ = builderForValue.build();
      } else {
        priorityBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public Builder mergePriority(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority value) {
      if (priorityBuilder_ == null) {
        if (((bitField0_ & 0x00002000) != 0) &&
          priority_ != null &&
          priority_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.getDefaultInstance()) {
          getPriorityBuilder().mergeFrom(value);
        } else {
          priority_ = value;
        }
      } else {
        priorityBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public Builder clearPriority() {
      bitField0_ = (bitField0_ & ~0x00002000);
      priority_ = null;
      if (priorityBuilder_ != null) {
        priorityBuilder_.dispose();
        priorityBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.Builder getPriorityBuilder() {
      bitField0_ |= 0x00002000;
      onChanged();
      return getPriorityFieldBuilder().getBuilder();
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriorityOrBuilder getPriorityOrBuilder() {
      if (priorityBuilder_ != null) {
        return priorityBuilder_.getMessageOrBuilder();
      } else {
        return priority_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.getDefaultInstance() : priority_;
      }
    }
    /**
     * <code>.GiftIMPriority priority = 14;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriorityOrBuilder>
        getPriorityFieldBuilder() {
      if (priorityBuilder_ == null) {
        priorityBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriority.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftIMPriorityOuterClass.GiftIMPriorityOrBuilder>(
                getPriority(),
                getParentForChildren(),
                isClean());
        priority_ = null;
      }
      return priorityBuilder_;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct gift_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStructOrBuilder> giftBuilder_;
    /**
     * <code>.GiftStruct gift = 15;</code>
     * @return Whether the gift field is set.
     */
    public boolean hasGift() {
      return ((bitField0_ & 0x00004000) != 0);
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     * @return The gift.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct getGift() {
      if (giftBuilder_ == null) {
        return gift_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.getDefaultInstance() : gift_;
      } else {
        return giftBuilder_.getMessage();
      }
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public Builder setGift(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct value) {
      if (giftBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        gift_ = value;
      } else {
        giftBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public Builder setGift(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.Builder builderForValue) {
      if (giftBuilder_ == null) {
        gift_ = builderForValue.build();
      } else {
        giftBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public Builder mergeGift(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct value) {
      if (giftBuilder_ == null) {
        if (((bitField0_ & 0x00004000) != 0) &&
          gift_ != null &&
          gift_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.getDefaultInstance()) {
          getGiftBuilder().mergeFrom(value);
        } else {
          gift_ = value;
        }
      } else {
        giftBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public Builder clearGift() {
      bitField0_ = (bitField0_ & ~0x00004000);
      gift_ = null;
      if (giftBuilder_ != null) {
        giftBuilder_.dispose();
        giftBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.Builder getGiftBuilder() {
      bitField0_ |= 0x00004000;
      onChanged();
      return getGiftFieldBuilder().getBuilder();
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStructOrBuilder getGiftOrBuilder() {
      if (giftBuilder_ != null) {
        return giftBuilder_.getMessageOrBuilder();
      } else {
        return gift_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.getDefaultInstance() : gift_;
      }
    }
    /**
     * <code>.GiftStruct gift = 15;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStructOrBuilder>
        getGiftFieldBuilder() {
      if (giftBuilder_ == null) {
        giftBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStruct.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.GiftStructOuterClass.GiftStructOrBuilder>(
                getGift(),
                getParentForChildren(),
                isClean());
        gift_ = null;
      }
      return giftBuilder_;
    }
    private java.lang.Object logId_ = "";
    /**
     * <code>string log_id = 16;</code>
     * @return The logId.
     */
    public java.lang.String getLogId() {
      java.lang.Object ref = logId_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        logId_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string log_id = 16;</code>
     * @return The bytes for logId.
     */
    public com.google.protobuf.ByteString
        getLogIdBytes() {
      java.lang.Object ref = logId_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        logId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string log_id = 16;</code>
     * @param value The logId to set.
     * @return This builder for chaining.
     */
    public Builder setLogId(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      logId_ = value;
      bitField0_ |= 0x00008000;
      onChanged();
      return this;
    }
    /**
     * <code>string log_id = 16;</code>
     * @return This builder for chaining.
     */
    public Builder clearLogId() {
      logId_ = getDefaultInstance().getLogId();
      bitField0_ = (bitField0_ & ~0x00008000);
      onChanged();
      return this;
    }
    /**
     * <code>string log_id = 16;</code>
     * @param value The bytes for logId to set.
     * @return This builder for chaining.
     */
    public Builder setLogIdBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      logId_ = value;
      bitField0_ |= 0x00008000;
      onChanged();
      return this;
    }
    private long sendType_ ;
    /**
     * <code>uint64 send_type = 17;</code>
     * @return The sendType.
     */
    @java.lang.Override
    public long getSendType() {
      return sendType_;
    }
    /**
     * <code>uint64 send_type = 17;</code>
     * @param value The sendType to set.
     * @return This builder for chaining.
     */
    public Builder setSendType(long value) {
      sendType_ = value;
      bitField0_ |= 0x00010000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 send_type = 17;</code>
     * @return This builder for chaining.
     */
    public Builder clearSendType() {
      bitField0_ = (bitField0_ & ~0x00010000);
      sendType_ = 0L;
      onChanged();
      return this;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon publicAreaCommon_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommonOrBuilder> publicAreaCommonBuilder_;
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     * @return Whether the publicAreaCommon field is set.
     */
    public boolean hasPublicAreaCommon() {
      return ((bitField0_ & 0x00020000) != 0);
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     * @return The publicAreaCommon.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon getPublicAreaCommon() {
      if (publicAreaCommonBuilder_ == null) {
        return publicAreaCommon_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.getDefaultInstance() : publicAreaCommon_;
      } else {
        return publicAreaCommonBuilder_.getMessage();
      }
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public Builder setPublicAreaCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon value) {
      if (publicAreaCommonBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        publicAreaCommon_ = value;
      } else {
        publicAreaCommonBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00020000;
      onChanged();
      return this;
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public Builder setPublicAreaCommon(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.Builder builderForValue) {
      if (publicAreaCommonBuilder_ == null) {
        publicAreaCommon_ = builderForValue.build();
      } else {
        publicAreaCommonBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00020000;
      onChanged();
      return this;
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public Builder mergePublicAreaCommon(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon value) {
      if (publicAreaCommonBuilder_ == null) {
        if (((bitField0_ & 0x00020000) != 0) &&
          publicAreaCommon_ != null &&
          publicAreaCommon_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.getDefaultInstance()) {
          getPublicAreaCommonBuilder().mergeFrom(value);
        } else {
          publicAreaCommon_ = value;
        }
      } else {
        publicAreaCommonBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00020000;
      onChanged();
      return this;
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public Builder clearPublicAreaCommon() {
      bitField0_ = (bitField0_ & ~0x00020000);
      publicAreaCommon_ = null;
      if (publicAreaCommonBuilder_ != null) {
        publicAreaCommonBuilder_.dispose();
        publicAreaCommonBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.Builder getPublicAreaCommonBuilder() {
      bitField0_ |= 0x00020000;
      onChanged();
      return getPublicAreaCommonFieldBuilder().getBuilder();
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommonOrBuilder getPublicAreaCommonOrBuilder() {
      if (publicAreaCommonBuilder_ != null) {
        return publicAreaCommonBuilder_.getMessageOrBuilder();
      } else {
        return publicAreaCommon_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.getDefaultInstance() : publicAreaCommon_;
      }
    }
    /**
     * <code>.PublicAreaCommon public_area_common = 18;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommonOrBuilder>
        getPublicAreaCommonFieldBuilder() {
      if (publicAreaCommonBuilder_ == null) {
        publicAreaCommonBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommon.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.PublicAreaCommonOuterClass.PublicAreaCommonOrBuilder>(
                getPublicAreaCommon(),
                getParentForChildren(),
                isClean());
        publicAreaCommon_ = null;
      }
      return publicAreaCommonBuilder_;
    }
    private tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text trayDisplayText_;
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.TextOrBuilder> trayDisplayTextBuilder_;
    /**
     * <code>.Text tray_display_text = 19;</code>
     * @return Whether the trayDisplayText field is set.
     */
    public boolean hasTrayDisplayText() {
      return ((bitField0_ & 0x00040000) != 0);
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     * @return The trayDisplayText.
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text getTrayDisplayText() {
      if (trayDisplayTextBuilder_ == null) {
        return trayDisplayText_ == null ? tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.getDefaultInstance() : trayDisplayText_;
      } else {
        return trayDisplayTextBuilder_.getMessage();
      }
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public Builder setTrayDisplayText(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text value) {
      if (trayDisplayTextBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        trayDisplayText_ = value;
      } else {
        trayDisplayTextBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00040000;
      onChanged();
      return this;
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public Builder setTrayDisplayText(
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.Builder builderForValue) {
      if (trayDisplayTextBuilder_ == null) {
        trayDisplayText_ = builderForValue.build();
      } else {
        trayDisplayTextBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00040000;
      onChanged();
      return this;
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public Builder mergeTrayDisplayText(tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text value) {
      if (trayDisplayTextBuilder_ == null) {
        if (((bitField0_ & 0x00040000) != 0) &&
          trayDisplayText_ != null &&
          trayDisplayText_ != tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.getDefaultInstance()) {
          getTrayDisplayTextBuilder().mergeFrom(value);
        } else {
          trayDisplayText_ = value;
        }
      } else {
        trayDisplayTextBuilder_.mergeFrom(value);
      }
      bitField0_ |= 0x00040000;
      onChanged();
      return this;
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public Builder clearTrayDisplayText() {
      bitField0_ = (bitField0_ & ~0x00040000);
      trayDisplayText_ = null;
      if (trayDisplayTextBuilder_ != null) {
        trayDisplayTextBuilder_.dispose();
        trayDisplayTextBuilder_ = null;
      }
      onChanged();
      return this;
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.Builder getTrayDisplayTextBuilder() {
      bitField0_ |= 0x00040000;
      onChanged();
      return getTrayDisplayTextFieldBuilder().getBuilder();
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    public tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.TextOrBuilder getTrayDisplayTextOrBuilder() {
      if (trayDisplayTextBuilder_ != null) {
        return trayDisplayTextBuilder_.getMessageOrBuilder();
      } else {
        return trayDisplayText_ == null ?
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.getDefaultInstance() : trayDisplayText_;
      }
    }
    /**
     * <code>.Text tray_display_text = 19;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.TextOrBuilder>
        getTrayDisplayTextFieldBuilder() {
      if (trayDisplayTextBuilder_ == null) {
        trayDisplayTextBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.Text.Builder, tech.ordinaryroad.live.chat.client.douyin.protobuf.dto.TextOuterClass.TextOrBuilder>(
                getTrayDisplayText(),
                getParentForChildren(),
                isClean());
        trayDisplayText_ = null;
      }
      return trayDisplayTextBuilder_;
    }
    private long bannedDisplayEffects_ ;
    /**
     * <code>uint64 banned_display_effects = 20;</code>
     * @return The bannedDisplayEffects.
     */
    @java.lang.Override
    public long getBannedDisplayEffects() {
      return bannedDisplayEffects_;
    }
    /**
     * <code>uint64 banned_display_effects = 20;</code>
     * @param value The bannedDisplayEffects to set.
     * @return This builder for chaining.
     */
    public Builder setBannedDisplayEffects(long value) {
      bannedDisplayEffects_ = value;
      bitField0_ |= 0x00080000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 banned_display_effects = 20;</code>
     * @return This builder for chaining.
     */
    public Builder clearBannedDisplayEffects() {
      bitField0_ = (bitField0_ & ~0x00080000);
      bannedDisplayEffects_ = 0L;
      onChanged();
      return this;
    }
    private boolean displayForSelf_ ;
    /**
     * <pre>
     * GiftTrayInfo trayInfo = 21;
     * AssetEffectMixInfo assetEffectMixInfo = 22;
     * </pre>
     *
     * <code>bool display_for_self = 25;</code>
     * @return The displayForSelf.
     */
    @java.lang.Override
    public boolean getDisplayForSelf() {
      return displayForSelf_;
    }
    /**
     * <pre>
     * GiftTrayInfo trayInfo = 21;
     * AssetEffectMixInfo assetEffectMixInfo = 22;
     * </pre>
     *
     * <code>bool display_for_self = 25;</code>
     * @param value The displayForSelf to set.
     * @return This builder for chaining.
     */
    public Builder setDisplayForSelf(boolean value) {
      displayForSelf_ = value;
      bitField0_ |= 0x00100000;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * GiftTrayInfo trayInfo = 21;
     * AssetEffectMixInfo assetEffectMixInfo = 22;
     * </pre>
     *
     * <code>bool display_for_self = 25;</code>
     * @return This builder for chaining.
     */
    public Builder clearDisplayForSelf() {
      bitField0_ = (bitField0_ & ~0x00100000);
      displayForSelf_ = false;
      onChanged();
      return this;
    }
    private java.lang.Object interactGiftInfo_ = "";
    /**
     * <code>string interact_gift_info = 26;</code>
     * @return The interactGiftInfo.
     */
    public java.lang.String getInteractGiftInfo() {
      java.lang.Object ref = interactGiftInfo_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        interactGiftInfo_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string interact_gift_info = 26;</code>
     * @return The bytes for interactGiftInfo.
     */
    public com.google.protobuf.ByteString
        getInteractGiftInfoBytes() {
      java.lang.Object ref = interactGiftInfo_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        interactGiftInfo_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string interact_gift_info = 26;</code>
     * @param value The interactGiftInfo to set.
     * @return This builder for chaining.
     */
    public Builder setInteractGiftInfo(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      interactGiftInfo_ = value;
      bitField0_ |= 0x00200000;
      onChanged();
      return this;
    }
    /**
     * <code>string interact_gift_info = 26;</code>
     * @return This builder for chaining.
     */
    public Builder clearInteractGiftInfo() {
      interactGiftInfo_ = getDefaultInstance().getInteractGiftInfo();
      bitField0_ = (bitField0_ & ~0x00200000);
      onChanged();
      return this;
    }
    /**
     * <code>string interact_gift_info = 26;</code>
     * @param value The bytes for interactGiftInfo to set.
     * @return This builder for chaining.
     */
    public Builder setInteractGiftInfoBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      interactGiftInfo_ = value;
      bitField0_ |= 0x00200000;
      onChanged();
      return this;
    }
    private java.lang.Object diyItemInfo_ = "";
    /**
     * <code>string diy_item_info = 27;</code>
     * @return The diyItemInfo.
     */
    public java.lang.String getDiyItemInfo() {
      java.lang.Object ref = diyItemInfo_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        diyItemInfo_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string diy_item_info = 27;</code>
     * @return The bytes for diyItemInfo.
     */
    public com.google.protobuf.ByteString
        getDiyItemInfoBytes() {
      java.lang.Object ref = diyItemInfo_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        diyItemInfo_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string diy_item_info = 27;</code>
     * @param value The diyItemInfo to set.
     * @return This builder for chaining.
     */
    public Builder setDiyItemInfo(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      diyItemInfo_ = value;
      bitField0_ |= 0x00400000;
      onChanged();
      return this;
    }
    /**
     * <code>string diy_item_info = 27;</code>
     * @return This builder for chaining.
     */
    public Builder clearDiyItemInfo() {
      diyItemInfo_ = getDefaultInstance().getDiyItemInfo();
      bitField0_ = (bitField0_ & ~0x00400000);
      onChanged();
      return this;
    }
    /**
     * <code>string diy_item_info = 27;</code>
     * @param value The bytes for diyItemInfo to set.
     * @return This builder for chaining.
     */
    public Builder setDiyItemInfoBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      diyItemInfo_ = value;
      bitField0_ |= 0x00400000;
      onChanged();
      return this;
    }
    private com.google.protobuf.Internal.LongList minAssetSetList_ = emptyLongList();
    private void ensureMinAssetSetListIsMutable() {
      if (!((bitField0_ & 0x00800000) != 0)) {
        minAssetSetList_ = mutableCopy(minAssetSetList_);
        bitField0_ |= 0x00800000;
      }
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @return A list containing the minAssetSetList.
     */
    public java.util.List<java.lang.Long>
        getMinAssetSetListList() {
      return ((bitField0_ & 0x00800000) != 0) ?
               java.util.Collections.unmodifiableList(minAssetSetList_) : minAssetSetList_;
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @return The count of minAssetSetList.
     */
    public int getMinAssetSetListCount() {
      return minAssetSetList_.size();
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @param index The index of the element to return.
     * @return The minAssetSetList at the given index.
     */
    public long getMinAssetSetList(int index) {
      return minAssetSetList_.getLong(index);
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @param index The index to set the value at.
     * @param value The minAssetSetList to set.
     * @return This builder for chaining.
     */
    public Builder setMinAssetSetList(
        int index, long value) {
      ensureMinAssetSetListIsMutable();
      minAssetSetList_.setLong(index, value);
      onChanged();
      return this;
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @param value The minAssetSetList to add.
     * @return This builder for chaining.
     */
    public Builder addMinAssetSetList(long value) {
      ensureMinAssetSetListIsMutable();
      minAssetSetList_.addLong(value);
      onChanged();
      return this;
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @param values The minAssetSetList to add.
     * @return This builder for chaining.
     */
    public Builder addAllMinAssetSetList(
        java.lang.Iterable<? extends java.lang.Long> values) {
      ensureMinAssetSetListIsMutable();
      com.google.protobuf.AbstractMessageLite.Builder.addAll(
          values, minAssetSetList_);
      onChanged();
      return this;
    }
    /**
     * <code>repeated uint64 min_asset_set_list = 28;</code>
     * @return This builder for chaining.
     */
    public Builder clearMinAssetSetList() {
      minAssetSetList_ = emptyLongList();
      bitField0_ = (bitField0_ & ~0x00800000);
      onChanged();
      return this;
    }
    private long totalCount_ ;
    /**
     * <code>uint64 total_count = 29;</code>
     * @return The totalCount.
     */
    @java.lang.Override
    public long getTotalCount() {
      return totalCount_;
    }
    /**
     * <code>uint64 total_count = 29;</code>
     * @param value The totalCount to set.
     * @return This builder for chaining.
     */
    public Builder setTotalCount(long value) {
      totalCount_ = value;
      bitField0_ |= 0x01000000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 total_count = 29;</code>
     * @return This builder for chaining.
     */
    public Builder clearTotalCount() {
      bitField0_ = (bitField0_ & ~0x01000000);
      totalCount_ = 0L;
      onChanged();
      return this;
    }
    private int clientGiftSource_ ;
    /**
     * <code>uint32 client_gift_source = 30;</code>
     * @return The clientGiftSource.
     */
    @java.lang.Override
    public int getClientGiftSource() {
      return clientGiftSource_;
    }
    /**
     * <code>uint32 client_gift_source = 30;</code>
     * @param value The clientGiftSource to set.
     * @return This builder for chaining.
     */
    public Builder setClientGiftSource(int value) {
      clientGiftSource_ = value;
      bitField0_ |= 0x02000000;
      onChanged();
      return this;
    }
    /**
     * <code>uint32 client_gift_source = 30;</code>
     * @return This builder for chaining.
     */
    public Builder clearClientGiftSource() {
      bitField0_ = (bitField0_ & ~0x02000000);
      clientGiftSource_ = 0;
      onChanged();
      return this;
    }
    private com.google.protobuf.Internal.LongList toUserIdsList_ = emptyLongList();
    private void ensureToUserIdsListIsMutable() {
      if (!((bitField0_ & 0x04000000) != 0)) {
        toUserIdsList_ = mutableCopy(toUserIdsList_);
        bitField0_ |= 0x04000000;
      }
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @return A list containing the toUserIdsList.
     */
    public java.util.List<java.lang.Long>
        getToUserIdsListList() {
      return ((bitField0_ & 0x04000000) != 0) ?
               java.util.Collections.unmodifiableList(toUserIdsList_) : toUserIdsList_;
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @return The count of toUserIdsList.
     */
    public int getToUserIdsListCount() {
      return toUserIdsList_.size();
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @param index The index of the element to return.
     * @return The toUserIdsList at the given index.
     */
    public long getToUserIdsList(int index) {
      return toUserIdsList_.getLong(index);
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @param index The index to set the value at.
     * @param value The toUserIdsList to set.
     * @return This builder for chaining.
     */
    public Builder setToUserIdsList(
        int index, long value) {
      ensureToUserIdsListIsMutable();
      toUserIdsList_.setLong(index, value);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @param value The toUserIdsList to add.
     * @return This builder for chaining.
     */
    public Builder addToUserIdsList(long value) {
      ensureToUserIdsListIsMutable();
      toUserIdsList_.addLong(value);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @param values The toUserIdsList to add.
     * @return This builder for chaining.
     */
    public Builder addAllToUserIdsList(
        java.lang.Iterable<? extends java.lang.Long> values) {
      ensureToUserIdsListIsMutable();
      com.google.protobuf.AbstractMessageLite.Builder.addAll(
          values, toUserIdsList_);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * AnchorGiftData anchorGift = 31;
     * </pre>
     *
     * <code>repeated uint64 to_user_ids_list = 32;</code>
     * @return This builder for chaining.
     */
    public Builder clearToUserIdsList() {
      toUserIdsList_ = emptyLongList();
      bitField0_ = (bitField0_ & ~0x04000000);
      onChanged();
      return this;
    }
    private long sendTimet_ ;
    /**
     * <code>uint64 send_timet = 33;</code>
     * @return The sendTimet.
     */
    @java.lang.Override
    public long getSendTimet() {
      return sendTimet_;
    }
    /**
     * <code>uint64 send_timet = 33;</code>
     * @param value The sendTimet to set.
     * @return This builder for chaining.
     */
    public Builder setSendTimet(long value) {
      sendTimet_ = value;
      bitField0_ |= 0x08000000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 send_timet = 33;</code>
     * @return This builder for chaining.
     */
    public Builder clearSendTimet() {
      bitField0_ = (bitField0_ & ~0x08000000);
      sendTimet_ = 0L;
      onChanged();
      return this;
    }
    private long forceDisplayEffectst_ ;
    /**
     * <code>uint64 force_display_effectst = 34;</code>
     * @return The forceDisplayEffectst.
     */
    @java.lang.Override
    public long getForceDisplayEffectst() {
      return forceDisplayEffectst_;
    }
    /**
     * <code>uint64 force_display_effectst = 34;</code>
     * @param value The forceDisplayEffectst to set.
     * @return This builder for chaining.
     */
    public Builder setForceDisplayEffectst(long value) {
      forceDisplayEffectst_ = value;
      bitField0_ |= 0x10000000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 force_display_effectst = 34;</code>
     * @return This builder for chaining.
     */
    public Builder clearForceDisplayEffectst() {
      bitField0_ = (bitField0_ & ~0x10000000);
      forceDisplayEffectst_ = 0L;
      onChanged();
      return this;
    }
    private java.lang.Object traceId_ = "";
    /**
     * <code>string trace_id = 35;</code>
     * @return The traceId.
     */
    public java.lang.String getTraceId() {
      java.lang.Object ref = traceId_;
      if (!(ref instanceof java.lang.String)) {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        traceId_ = s;
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }
    /**
     * <code>string trace_id = 35;</code>
     * @return The bytes for traceId.
     */
    public com.google.protobuf.ByteString
        getTraceIdBytes() {
      java.lang.Object ref = traceId_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        traceId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }
    /**
     * <code>string trace_id = 35;</code>
     * @param value The traceId to set.
     * @return This builder for chaining.
     */
    public Builder setTraceId(
        java.lang.String value) {
      if (value == null) { throw new NullPointerException(); }
      traceId_ = value;
      bitField0_ |= 0x20000000;
      onChanged();
      return this;
    }
    /**
     * <code>string trace_id = 35;</code>
     * @return This builder for chaining.
     */
    public Builder clearTraceId() {
      traceId_ = getDefaultInstance().getTraceId();
      bitField0_ = (bitField0_ & ~0x20000000);
      onChanged();
      return this;
    }
    /**
     * <code>string trace_id = 35;</code>
     * @param value The bytes for traceId to set.
     * @return This builder for chaining.
     */
    public Builder setTraceIdBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) { throw new NullPointerException(); }
      checkByteStringIsUtf8(value);
      traceId_ = value;
      bitField0_ |= 0x20000000;
      onChanged();
      return this;
    }
    private long effectDisplayTs_ ;
    /**
     * <code>uint64 effect_display_ts = 36;</code>
     * @return The effectDisplayTs.
     */
    @java.lang.Override
    public long getEffectDisplayTs() {
      return effectDisplayTs_;
    }
    /**
     * <code>uint64 effect_display_ts = 36;</code>
     * @param value The effectDisplayTs to set.
     * @return This builder for chaining.
     */
    public Builder setEffectDisplayTs(long value) {
      effectDisplayTs_ = value;
      bitField0_ |= 0x40000000;
      onChanged();
      return this;
    }
    /**
     * <code>uint64 effect_display_ts = 36;</code>
     * @return This builder for chaining.
     */
    public Builder clearEffectDisplayTs() {
      bitField0_ = (bitField0_ & ~0x40000000);
      effectDisplayTs_ = 0L;
      onChanged();
      return this;
    }
    @java.lang.Override
    public final Builder setUnknownFields(
        final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.setUnknownFields(unknownFields);
    }
    @java.lang.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.douyin.protobuf.douyin_webcast_gift_message_msg)
  }
  // @@protoc_insertion_point(class_scope:tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg)
  private static final tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg DEFAULT_INSTANCE;
  static {
    DEFAULT_INSTANCE = new tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg();
  }
  public static tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }
  private static final com.google.protobuf.Parser<douyin_webcast_gift_message_msg>
      PARSER = new com.google.protobuf.AbstractParser<douyin_webcast_gift_message_msg>() {
    @java.lang.Override
    public douyin_webcast_gift_message_msg 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<douyin_webcast_gift_message_msg> parser() {
    return PARSER;
  }
  @java.lang.Override
  public com.google.protobuf.Parser<douyin_webcast_gift_message_msg> getParserForType() {
    return PARSER;
  }
  @java.lang.Override
  public tech.ordinaryroad.live.chat.client.douyin.protobuf.douyin_webcast_gift_message_msg getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }
}
在上述文件截断后对比
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_gift_message_msgOrBuilder.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_like_message_msg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_like_message_msgOrBuilder.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_like_message_msgProto.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_member_message_msg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_webcast_member_message_msgOrBuilder.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_websocket_frame.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_websocket_frameOrBuilder.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_websocket_frame_msg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_websocket_frame_msgOrBuilder.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/douyin_websocket_frame_msgProto.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/CommonOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/DoubleLikeDetailOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/GiftIMPriorityOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/GiftStructOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/ImageOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/PatternRefOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/PublicAreaCommonOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextEffectDetailOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextEffectOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextFormatOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPieceGiftOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPieceHeartOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPieceImageOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPieceOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPiecePatternRefOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/TextPieceUserOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/protobuf/dto/UserOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/Common.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/DoubleLikeDetail.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/GiftIMPriority.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/GiftStruct.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/Image.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/PatternRef.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/PublicAreaCommon.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/Text.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextEffect.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextEffectDetail.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextFormat.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPiece.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPieceGift.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPieceHeart.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPieceImage.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPiecePatternRef.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/TextPieceUser.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/User.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_cmd_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_webcast_chat_message_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_webcast_gift_message_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_webcast_like_message_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_webcast_member_message_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_websocket_frame.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/resources/proto/douyin_websocket_frame_msg.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/test/java/tech/ordinaryroad/live/chat/client/douyin/api/DouyinApisTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/test/java/tech/ordinaryroad/live/chat/client/douyin/client/DouyinLiveChatClientTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/README.md ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/pom.xml ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/api/DouyuApis.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/client/DouyuDanmuLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/client/DouyuLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/client/DouyuWsLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/client/base/BaseDouyuLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/config/DouyuLiveChatClientConfig.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/constant/DouyuClientModeEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/constant/DouyuCmdEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/listener/IDouyuConnectionListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/listener/IDouyuMsgListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/ChatmessageMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/ChatmsgMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/DgbMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/DouyuCmdMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/H5ckreqMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/H5csMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/H5gkcreqMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/HeartbeatMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/HeartbeatReplyMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/JoingroupMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/KeepliveMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/LoginreqMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/LoginresMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/MapkbMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/MsgrepeaterproxylistMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/SubMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/UenterMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/base/BaseDouyuCmdMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/base/IDouyuMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/dto/GiftListInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/dto/GiftPropInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/msg/dto/GiftPropSingle.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/frame/AuthWebSocketFrame.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/frame/HeartbeatWebSocketFrame.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/frame/KeepliveWebSocketFrame.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/frame/base/BaseDouyuWebSocketFrame.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/frame/factory/DouyuWebSocketFrameFactory.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/handler/DouyuBinaryFrameHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/netty/handler/DouyuConnectionHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/main/java/tech/ordinaryroad/live/chat/client/douyu/util/DouyuCodecUtil.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/api/DouyuApisTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/client/ChatChoice.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/client/ChatCompletionResponse.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/client/DouyuLiveChatClientTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/client/Message.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/client/Usage.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyu/src/test/java/tech/ordinaryroad/live/chat/client/douyu/util/DouyuCodecUtilTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/pom.xml ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/api/HuyaApis.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/client/HuyaLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/config/HuyaLiveChatClientConfig.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaClientTemplateTypeEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaCmdEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaDecorationAppTypeEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaDecorationViewTypeEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaGenderEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaLiveSource.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaOperationEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaStreamLineTypeEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/constant/HuyaWupFunctionEnum.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/listener/IHuyaConnectionListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/listener/IHuyaMsgListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/BaseWup.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/ConnectParaInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/LiveLaunchRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/MessageNoticeMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/PushMessage.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/PushMessage_V2.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/RegisterGroupRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/RegisterRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/SendItemSubBroadcastPacketMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/UserInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/VerifyCookieRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/VipEnterBannerMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/WebSocketCommand.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/WupRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/base/BaseHuyaCmdMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/base/BaseHuyaMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/base/IHuyaCmdMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/base/IHuyaMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/ACEnterBanner.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/BadgeInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/BulletBorderGroundFormat.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/BulletFormat.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/ChannelPair.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/CommEnterBanner.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/ContentFormat.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/CustomBadgeDynamicExternal.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/DIYBigGiftEffect.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/DecorationInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/DecorationInfoRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/DeviceInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/DisplayInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/FaithInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/FaithPresenter.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/GuardInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/ItemEffectInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/LiveAppUAEx.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/LiveProxyValue.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/LiveUserbase.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/MessageContentExpand.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/MessageTagInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/MsgItem.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/MsgStatInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/NobleInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/NobleLevelAttr.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/NobleLevelInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/NoblePetAttr.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/PresenterChannelInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/PropView.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/PropsIdentity.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/PropsItem.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/SendMessageFormat.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/SenderInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/SpecialInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/SuperFansInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/UidNickName.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/UserId.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/UserIdentityInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/UserRidePetInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/dto/WeekRankInfo.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/GetLivingInfoReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/GetPropsListReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/GetPropsListRsp.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/LaunchReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/LiveLaunchReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/RegisterGroupReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/SendMessageReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/UpdateUserInfoReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/UserHeartBeatReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/VerifyCookieReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/msg/req/WupReq.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/netty/frame/factory/HuyaWebSocketFrameFactory.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/netty/handler/HuyaBinaryFrameHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/netty/handler/HuyaConnectionHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/main/java/tech/ordinaryroad/live/chat/client/huya/util/HuyaCodecUtil.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/test/java/tech/ordinaryroad/live/chat/client/huya/api/HuyaApisTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/test/java/tech/ordinaryroad/live/chat/client/huya/client/HuyaLiveChatClientTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-huya/src/test/java/tech/ordinaryroad/live/chat/client/huya/util/HuyaCodecUtilTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/pom.xml ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/ClientModeExample.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/api/KuaishouApis.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/client/KuaishouLiveChatClient.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/config/KuaishouLiveChatClientConfig.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/listener/IKuaishouConnectionListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/listener/IKuaishouMsgListener.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/msg/KuaishouDanmuMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/msg/KuaishouGiftMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/msg/KuaishouLikeMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/msg/base/IKuaishouCmdMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/msg/base/IKuaishouMsg.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/netty/handler/KuaishouBinaryFrameHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/netty/handler/KuaishouConnectionHandler.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/AuditAudienceMaskOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSErrorOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSHeartbeatOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSPingOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSWebEnterRoomOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSWebErrorOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSWebHeartbeatOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSWebUserExitOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/CSWebUserPauseOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/ClientIdOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/ConfigSwitchItemOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/ConfigSwitchTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/GzoneNameplateOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/LiveAudienceStateOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/LiveCdnNodeViewOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/LiveFansGroupStateOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/PSHostInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/PayloadTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/PicUrlOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCEchoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCErrorOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCHeartbeatAckOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCLiveWarningMaskStatusChangedAudienceOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCPingAckOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebAuthorPauseOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebAuthorResumeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebBetChangedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebBetClosedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebCurrentRedPackFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebEnterRoomAckOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebErrorOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebFeedPushOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebGuessClosedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebGuessOpenedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebHeartbeatAckOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebLiveSpecialAccountConfigStateOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebLiveWatchingUsersOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebPipEndedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebPipStartedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebRefreshWalletOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebRideChangedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SCWebSuspectedViolationOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SimpleUserInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/SocketMessageOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/UserInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebComboCommentFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebCommentFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebCommentFeedShowTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebGiftFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebLikeFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebLiveAssistantTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebPauseTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebRedPackCoverTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebRedPackInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebShareFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebSystemNoticeFeedOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebUserPauseTypeOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/java/tech/ordinaryroad/live/chat/client/kuaishou/protobuf/WebWatchingUserInfoOuterClass.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/AuditAudienceMask.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSError.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSHeartbeat.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSPing.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSWebEnterRoom.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSWebError.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSWebHeartbeat.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSWebUserExit.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/CSWebUserPause.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/ClientId.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/ConfigSwitchItem.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/ConfigSwitchType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/GzoneNameplate.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/LiveAudienceState.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/LiveCdnNodeView.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/LiveFansGroupState.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/PSHostInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/PayloadType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/PicUrl.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCEcho.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCError.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCHeartbeatAck.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCLiveWarningMaskStatusChangedAudience.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCPingAck.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebAuthorPause.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebAuthorResume.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebBetChanged.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebBetClosed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebCurrentRedPackFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebEnterRoomAck.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebError.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebFeedPush.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebGuessClosed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebGuessOpened.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebHeartbeatAck.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebLiveSpecialAccountConfigState.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebLiveWatchingUsers.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebPipEnded.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebPipStarted.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebRefreshWallet.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebRideChanged.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SCWebSuspectedViolation.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SimpleUserInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/SocketMessage.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/UserInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebComboCommentFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebCommentFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebCommentFeedShowType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebGiftFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebLikeFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebLiveAssistantType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebPauseType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebRedPackCoverType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebRedPackInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebShareFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebSystemNoticeFeed.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebUserPauseType.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/main/resources/proto/WebWatchingUserInfo.proto ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/test/java/tech/ordinaryroad/live/chat/client/kuaishou/api/KuaishouApisTest.java ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-kuaishou/src/test/java/tech/ordinaryroad/live/chat/client/kuaishou/client/KuaishouLiveChatClientTest.java ruoyi-modules/ruoyi-live/live-chat-clients/pom.xml ruoyi-modules/ruoyi-live/pom.xml ruoyi-modules/ruoyi-midjourney/pom.xml ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/Constants.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/ProxyApplication.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/ProxyProperties.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/ReturnCode.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/controller/AccountController.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/controller/SubmitController.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/controller/TaskController.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/domain/DiscordAccount.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/domain/DomainObject.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/BaseSubmitDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitBlendDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitChangeDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitDescribeDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitImagineDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitSimpleChangeDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/TaskConditionDTO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/enums/BlendDimensions.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/enums/MessageType.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/enums/TaskAction.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/enums/TaskStatus.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/enums/TranslateWay.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/exception/BannedPromptException.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/exception/SnowFlakeException.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/DiscordInstance.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/DiscordInstanceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/DiscordLoadBalancer.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/rule/BestWaitIdleRule.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/rule/IRule.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/loadbalancer/rule/RoundRobinRule.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/result/Message.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/result/SubmitResultVO.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/DiscordService.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/DiscordServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/NotifyService.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/NotifyServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/TaskService.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/TaskServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/TaskStoreService.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/TranslateService.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/store/InMemoryTaskStoreServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/store/RedisTaskStoreServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/translate/BaiduTranslateServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/translate/GPTTranslateServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/service/translate/NoTranslateServiceImpl.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/ApiAuthorizeInterceptor.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/DiscordAccountHelper.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/DiscordAccountInitializer.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/DiscordHelper.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/SpringContextHolder.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/Task.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/TaskCondition.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/support/TaskTimeoutSchedule.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/AsyncLockUtils.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/BannedPromptUtils.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/ContentParseData.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/ConvertUtils.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/MimeTypeUtils.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/SnowFlake.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/TaskChangeParams.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/util/UVContentParseData.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/WebSocketStarter.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/BlendSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/DescribeSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/ErrorMessageHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/ImagineSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/MessageHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/RerollSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/StartAndProgressHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/UpscaleSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/handle/VariationSuccessHandler.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/user/UserMessageListener.java ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/wss/user/UserWebSocketStarter.java ruoyi-modules/ruoyi-midjourney/src/main/java/spring/config/BeanConfig.java ruoyi-modules/ruoyi-midjourney/src/main/java/spring/config/WebMvcConfig.java ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/blend.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/describe.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/imagine.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/message.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/reroll.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/upscale.json ruoyi-modules/ruoyi-midjourney/src/main/resources/api-params/variation.json ruoyi-modules/ruoyi-midjourney/src/main/resources/banned-words.txt ruoyi-modules/ruoyi-midjourney/src/main/resources/mime.types ruoyi-modules/ruoyi-system/pom.xml ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/cofing/GptConfig.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/cofing/KeywordConfig.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/cofing/QqConfig.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/cofing/WechatConfig.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/handler/WechatMessageHandler.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/listener/SSEEventSourceListener.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/IChatService.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISseService.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/IChatServiceImpl.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/ISseServiceImpl.java ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/util/BotUtil.java script/sql/ry-vue.sql