| | |
| | | <artifactId>ruoyi-fusion</artifactId> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-knowledge</artifactId> |
| | | </dependency> |
| | | |
| | | |
| | | <!-- demo模å --> |
| | |
| | | <artifactId>thumbnailator</artifactId> |
| | | <version>0.4.11</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.github.ollama4j</groupId> |
| | | <artifactId>ollama4j</artifactId> |
| | | <version>1.0.79</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi; |
| | | |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; |
| | | |
| | | /** |
| | | * å¯å¨ç¨åº |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | @SpringBootApplication |
| | | public class RuoYiAIApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication application = new SpringApplication(RuoYiAIApplication.class); |
| | | application.setApplicationStartup(new BufferingApplicationStartup(2048)); |
| | | application.run(args); |
| | | System.out.println("(â¥â â¿â )ï¾ï¾ RuoYiAIå¯å¨æå á(´ڡ`á)ï¾"); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi; |
| | | |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | |
| | | /** |
| | | * web容å¨ä¸è¿è¡é¨ç½² |
| | | * |
| | | * @author Lion Li |
| | | */ |
| | | public class RuoYiAIServletInitializer extends SpringBootServletInitializer { |
| | | |
| | | @Override |
| | | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { |
| | | return application.sources(RuoYiAIApplication.class); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.controller; |
| | | |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import com.theokanning.openai.completion.chat.ChatMessageRole; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.Valid; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.chat.config.ChatConfig; |
| | | import org.ruoyi.common.chat.domain.request.ChatRequest; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletion; |
| | | import org.ruoyi.common.chat.entity.chat.Message; |
| | | import org.ruoyi.common.chat.openai.OpenAiStreamClient; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.validate.AddGroup; |
| | | import org.ruoyi.common.excel.utils.ExcelUtil; |
| | | import org.ruoyi.common.log.annotation.Log; |
| | | import org.ruoyi.common.log.enums.BusinessType; |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeFragmentBo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeInfoBo; |
| | | import org.ruoyi.knowledge.domain.req.KnowledgeInfoUploadRequest; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeAttachVo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeFragmentVo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; |
| | | import org.ruoyi.knowledge.service.EmbeddingService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeAttachService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeFragmentService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeInfoService; |
| | | import org.ruoyi.system.listener.SSEEventSourceListener; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.ruoyi.knowledge.chain.vectorstore.VectorStore; |
| | | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * ç¥è¯åº |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Validated |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/knowledge") |
| | | public class KnowledgeController extends BaseController { |
| | | |
| | | private final IKnowledgeInfoService knowledgeInfoService; |
| | | |
| | | private final VectorStore vectorStore; |
| | | |
| | | private final IKnowledgeAttachService attachService; |
| | | |
| | | private final IKnowledgeFragmentService fragmentService; |
| | | |
| | | private final EmbeddingService embeddingService; |
| | | |
| | | private OpenAiStreamClient openAiStreamClient; |
| | | |
| | | private final ChatConfig chatConfig; |
| | | |
| | | /** |
| | | * ç¥è¯åºå¯¹è¯ |
| | | */ |
| | | @PostMapping("/send") |
| | | public SseEmitter send(@RequestBody @Valid ChatRequest chatRequest) { |
| | | |
| | | openAiStreamClient = chatConfig.getOpenAiStreamClient(); |
| | | SseEmitter sseEmitter = new SseEmitter(0L); |
| | | SSEEventSourceListener openAIEventSourceListener = new SSEEventSourceListener(sseEmitter); |
| | | |
| | | List<Message> messages = chatRequest.getMessages(); |
| | | String content = messages.get(messages.size() - 1).getContent().toString(); |
| | | List<String> nearestList; |
| | | List<Double> queryVector = embeddingService.getQueryVector(content); |
| | | nearestList = vectorStore.nearest(queryVector,chatRequest.getKid()); |
| | | for (String prompt : nearestList) { |
| | | Message sysMessage = Message.builder().content(prompt).role(Message.Role.USER).build(); |
| | | messages.add(sysMessage); |
| | | } |
| | | Message userMessage = Message.builder().content(content + (nearestList.size() > 0 ? "\n\n注æï¼åçé®é¢æ¶ï¼é¡»ä¸¥æ ¼æ ¹æ®æç»ä½ çç³»ç»ä¸ä¸æå
容åæè¿è¡åçï¼è¯·ä¸è¦èªå·±åæ¥,åçæ¶ä¿æåæ¥ææ¬çæ®µè½å±çº§" : "") ).role(Message.Role.USER).build(); |
| | | messages.add(userMessage); |
| | | |
| | | |
| | | ChatCompletion completion = ChatCompletion |
| | | .builder() |
| | | .messages(messages) |
| | | .model(chatRequest.getModel()) |
| | | .temperature(chatRequest.getTemperature()) |
| | | .topP(chatRequest.getTop_p()) |
| | | .stream(true) |
| | | .build(); |
| | | openAiStreamClient.streamChatCompletion(completion, openAIEventSourceListener); |
| | | |
| | | return sseEmitter; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·ä¿¡æ¯æ¥è¯¢æ¬å°ç¥è¯åº |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo<KnowledgeInfoVo> list(KnowledgeInfoBo bo, PageQuery pageQuery) { |
| | | if(!StpUtil.isLogin()){ |
| | | throw new SecurityException("请å
å»ç»å½!"); |
| | | } |
| | | bo.setUid(LoginHelper.getUserId()); |
| | | return knowledgeInfoService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯åº |
| | | */ |
| | | @Log(title = "ç¥è¯åº", businessType = BusinessType.INSERT) |
| | | @PostMapping("/save") |
| | | public R<Void> save(@Validated(AddGroup.class) @RequestBody KnowledgeInfoBo bo) { |
| | | knowledgeInfoService.saveOne(bo); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ç¥è¯åº |
| | | */ |
| | | @PostMapping("/remove/{id}") |
| | | public R<String> remove(@PathVariable String id){ |
| | | knowledgeInfoService.removeKnowledge(id); |
| | | return R.ok("å é¤ç¥è¯åºæå!"); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯åº |
| | | */ |
| | | @Log(title = "ç¥è¯åº", businessType = BusinessType.UPDATE) |
| | | @PostMapping("/edit") |
| | | public R<Void> edit( @RequestBody KnowledgeInfoBo bo) { |
| | | return toAjax(knowledgeInfoService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * 导åºç¥è¯åºå表 |
| | | */ |
| | | @Log(title = "ç¥è¯åº", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(KnowledgeInfoBo bo, HttpServletResponse response) { |
| | | List<KnowledgeInfoVo> list = knowledgeInfoService.queryList(bo); |
| | | ExcelUtil.exportExcel(list, "ç¥è¯åº", KnowledgeInfoVo.class, response); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯éä»¶ä¿¡æ¯ |
| | | */ |
| | | @GetMapping("/detail/{kid}") |
| | | public TableDataInfo<KnowledgeAttachVo> attach(KnowledgeAttachBo bo, PageQuery pageQuery,@PathVariable String kid){ |
| | | bo.setKid(kid); |
| | | return attachService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ ç¥è¯åºéä»¶ |
| | | */ |
| | | @PostMapping(value = "/attach/upload") |
| | | public R<String> upload(KnowledgeInfoUploadRequest request){ |
| | | knowledgeInfoService.upload(request); |
| | | return R.ok("ä¸ä¼ ç¥è¯åºéä»¶æå!"); |
| | | } |
| | | |
| | | /** |
| | | * è·åç¥è¯åºé件详ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @GetMapping("attach/info/{id}") |
| | | public R<KnowledgeAttachVo> getAttachInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long id) { |
| | | return R.ok(attachService.queryById(id)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ç¥è¯åºéä»¶ |
| | | * |
| | | */ |
| | | @PostMapping("attach/remove/{kid}") |
| | | public R<Void> removeAttach(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable String kid) { |
| | | attachService.removeKnowledgeAttach(kid); |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段 |
| | | */ |
| | | @GetMapping("/fragment/list/{docId}") |
| | | public TableDataInfo<KnowledgeFragmentVo> fragmentList(KnowledgeFragmentBo bo, PageQuery pageQuery, @PathVariable String docId) { |
| | | bo.setDocId(docId); |
| | | return fragmentService.queryPageList(bo, pageQuery); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.controller; |
| | | |
| | | |
| | | import io.github.ollama4j.OllamaAPI; |
| | | import io.github.ollama4j.exceptions.OllamaBaseException; |
| | | import io.github.ollama4j.models.chat.OllamaChatMessageRole; |
| | | import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; |
| | | import io.github.ollama4j.models.chat.OllamaChatRequestModel; |
| | | import io.github.ollama4j.models.chat.OllamaChatResult; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * æè¿°ï¼Ollama APIè°ç¨ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2024/11/6 |
| | | */ |
| | | @RestController |
| | | public class OllamaController { |
| | | |
| | | |
| | | @RequestMapping(value = "/qianwen-ai2") |
| | | private void ollama2(@RequestParam(value = "msg") String msg) { |
| | | |
| | | } |
| | | |
| | | public static void main(String[] args) throws OllamaBaseException, IOException, InterruptedException { |
| | | |
| | | String host = "http://localhost:11434/"; |
| | | |
| | | OllamaAPI ollama = new OllamaAPI(host); |
| | | OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance("qwen2.5:7b"); |
| | | // 设置è¶
æ¶æ¶é´ |
| | | ollama.setRequestTimeoutSeconds(100); |
| | | // create first user question |
| | | String text = ""; |
| | | |
| | | String json = "{\"instruction\": \"è§£ç以䏿°å¦é®é¢ã\",\"input\": \"è®¡ç® 2 + 3 çç»æã\",\"output\": \"2 + 3 = 5\"}"; |
| | | |
| | | OllamaChatRequestModel requestModel = builder.withMessage |
| | | (OllamaChatMessageRole.USER, "###ææ¬:"+text+"###,çè§£ææ¬å
容ï¼å¹¶ä¸å°ææ¬å
容转æ¢ä¸º:"+json+"è¾åºJSONæ ¼å¼,ä¸è¦å
å«å
¶ä»æ å
³å
容,å
é¨ä½¿ç¨æ éè±æ") |
| | | .withGetJsonResponse() |
| | | .withStreaming() |
| | | .build(); |
| | | |
| | | // start conversation with model |
| | | OllamaChatResult chatResult = ollama.chat(requestModel); |
| | | |
| | | System.out.println("First answer: " + chatResult.getResponse()); |
| | | |
| | | // create next userQuestion |
| | | // requestModel = builder.withMessages(chatResult.getChatHistory()).withMessage(OllamaChatMessageRole.USER, "And what is the second largest city?").build(); |
| | | |
| | | // "continue" conversation with model |
| | | // chatResult = ollamaAPI.chat(requestModel); |
| | | |
| | | //System.out.println("Second answer: " + chatResult.getResponse()); |
| | | |
| | | // åå²è®°å½ |
| | | //System.out.println("Chat History: " + chatResult.getChatHistory()); |
| | | } |
| | | |
| | | } |
| | |
| | | username: ruoyi |
| | | password: 123456 |
| | | |
| | | --- # xxl-job é
ç½® |
| | | xxl.job: |
| | | # æ§è¡å¨å¼å
³ |
| | | enabled: false |
| | | # è°åº¦ä¸å¿å°åï¼å¦è°åº¦ä¸å¿é群é¨ç½²åå¨å¤ä¸ªå°ååç¨éå·åéã |
| | | admin-addresses: http://localhost:9100/xxl-job-admin |
| | | # æ§è¡å¨é讯TOKENï¼é空æ¶å¯ç¨ |
| | | access-token: xxl-job |
| | | executor: |
| | | # æ§è¡å¨AppNameï¼æ§è¡å¨å¿è·³æ³¨ååç»ä¾æ®ï¼ä¸ºç©ºåå
³éèªå¨æ³¨å |
| | | appname: xxl-job-executor |
| | | # æ§è¡å¨ç«¯å£å· æ§è¡å¨ä»9101å¼å§å¾åå |
| | | port: 9101 |
| | | # æ§è¡å¨æ³¨åï¼é»è®¤IP:PORT |
| | | address: |
| | | # æ§è¡å¨IPï¼é»è®¤èªå¨è·åIP |
| | | ip: |
| | | # æ§è¡å¨è¿è¡æ¥å¿æä»¶åå¨ç£çè·¯å¾ |
| | | logpath: ./logs/xxl-job |
| | | # æ§è¡å¨æ¥å¿æä»¶ä¿å天æ°ï¼å¤§äº3çæ |
| | | logretentiondays: 30 |
| | | |
| | | --- # æ°æ®æºé
ç½® |
| | | spring: |
| | | datasource: |
| | |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://43.139.70.230:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true |
| | | username: ruoyi-ai |
| | | password: TZ7yaGtSRWeeBaBJ |
| | | password: eCaZ278N62k6fhYj |
| | | |
| | | hikari: |
| | | # æå¤§è¿æ¥æ± æ°é |
| | | maxPoolSize: 20 |
| | |
| | | # æ°æ®åºç´¢å¼ |
| | | database: 0 |
| | | # å¯ç (妿²¡æå¯ç 请注éæ) |
| | | #password: |
| | | # password: 123456 |
| | | # è¿æ¥è¶
æ¶æ¶é´ |
| | | timeout: 10S |
| | | # æ¯å¦å¼å¯ssl |
| | |
| | | # çæ¬ |
| | | version: ${revision} |
| | | # çæå¹´ä»½ |
| | | copyrightYear: 2023 |
| | | copyrightYear: 2025 |
| | | # å®ä¾æ¼ç¤ºå¼å
³ |
| | | demoEnabled: true |
| | | # è·åipå°åå¼å
³ |
| | |
| | | websocket: |
| | | enabled: true |
| | | # è·¯å¾ |
| | | path: '' |
| | | path: '/resource/websocket' |
| | | # è®¾ç½®è®¿é®æºå°å |
| | | allowedOrigins: '*' |
| | | |
| | |
| | | aesKey: #微信å°ç¨åºæ¶æ¯æå¡å¨é
ç½®çEncodingAESKey |
| | | msgDataFormat: JSON |
| | | |
| | | # ä¼ä¸å¾®ä¿¡åºç¨ |
| | | wechat: |
| | | # æ¯å¦ä½¿ç¨å¾®ä¿¡ true/false |
| | | enable: true |
| | | # çæçç»å½äºç»´ç è·¯å¾ é»è®¤ä¸é¡¹ç®å级 |
| | | qrPath: "./" |
| | | # ä¼ä¸å¾®ä¿¡åºç¨ |
| | | cp: |
| | | corpId: |
| | | appConfigs: |
| | | - agentId: |
| | | secret: '' |
| | | token: '' |
| | | aesKey: '' |
| | | |
| | | # ç¥è¯åºé
ç½® |
| | | chain: |
| | | split: |
| | | chunk: |
| | | endspliter: "<STOP>" |
| | | # ååææ¬å¤§å° |
| | | size: 500 |
| | | overlay: 0 |
| | | qaspliter: "######" |
| | | size: 200 |
| | | overlay: 30 |
| | | qaspliter: "###" |
| | | # ç¥è¯åºä¸æ£ç´¢çæ¡æ° |
| | | limits: 5 |
| | | vectorization: |
| | | type: openai |
| | | openai: |
| | | model: 'text-embedding-3-small' |
| | | baidu: |
| | | model: bge-large-zh |
| | | zhipu: |
| | | model: embedding-2 |
| | | # æºæ®API KEY |
| | | token: xx |
| | | vector: |
| | | model: 'text-embedding-3-small' |
| | | store: |
| | | type: weaviate |
| | | weaviate: |
| | |
| | | port: 19530 |
| | | dimension: 1536 |
| | | collection: LocalKnowledge |
| | | llm: |
| | | openai: |
| | | token: sk-xx |
| | | model: gpt-4-1106-preview |
| | | chatglm: |
| | | baseurl: http://127.0.0.1:8000/ |
| | | model: chatglm2-6b |
| | | baidu: |
| | | appKey: xx |
| | | secretKey: xx |
| | | model: ernie_bot |
| | | zhipu: |
| | | model: glm-4 |
| | | audio: |
| | | type: openai |
| | | text: |
| | | type: openai |
| | | function: |
| | | type: baidu |
| | | vision: |
| | | type: openai |
| | | image: |
| | | type: openai |
| | | |
| | | upload: |
| | | path: /data/upload |
| | | |
| | | proxy: |
| | | socket: |
| | | host: 127.0.0.1 |
| | | port: 7890 |
| | | |
| | | resource: |
| | | domain: http://127.0.0.1:${server.port}/resources |
| | | |
| | |
| | | <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> |
| | |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- 微信模å --> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-wechat</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- AIç»ç» --> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | |
| | | <artifactId>ruoyi-common-core</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.azure</groupId> |
| | | <artifactId>azure-ai-openai</artifactId> |
| | | <version>1.0.0-beta.12</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>io.github.ollama4j</groupId> |
| | | <artifactId>ollama4j</artifactId> |
| | | <version>1.0.79</version> |
| | | </dependency> |
| | | |
| | | <!-- åºå忍¡å --> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-satoken</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-websocket</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>5.8.12</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-websocket</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
| | |
| | | // é坿ä¼çæ |
| | | @Bean |
| | | public OpenAiStreamClient openAiStreamClient() { |
| | | |
| | | String apiHost = configService.getConfigValue("chat", "apiHost"); |
| | | String apiKey = configService.getConfigValue("chat", "apiKey"); |
| | | openAiStreamClient = createOpenAiStreamClient(apiHost,apiKey); |
| | |
| | | public WebSocketConfigurer webSocketConfigurer(HandshakeInterceptor handshakeInterceptor, |
| | | WebSocketHandler webSocketHandler, |
| | | WebSocketProperties webSocketProperties) { |
| | | // 妿WebSocketçè·¯å¾ä¸ºç©ºï¼å设置é»è®¤è·¯å¾ä¸º "/websocket" |
| | | if (StrUtil.isBlank(webSocketProperties.getPath())) { |
| | | webSocketProperties.setPath("/websocket"); |
| | | } |
| | | |
| | | // 妿å
许跨å访é®çå°å为空ï¼å设置为 "*"ï¼è¡¨ç¤ºå
è®¸æææ¥æºçè·¨åè¯·æ± |
| | | if (StrUtil.isBlank(webSocketProperties.getAllowedOrigins())) { |
| | | webSocketProperties.setAllowedOrigins("*"); |
| | | } |
| | | |
| | | // è¿åä¸ä¸ªWebSocketConfigurer对象ï¼ç¨äºé
ç½®WebSocket |
| | | return registry -> registry |
| | | // æ·»å WebSocketå¤çç¨åºåæ¦æªå¨å°æå®è·¯å¾ï¼è®¾ç½®å
许çè·¨åæ¥æº |
| | | .addHandler(webSocketHandler, webSocketProperties.getPath()) |
| | | .addInterceptors(handshakeInterceptor) |
| | | .setAllowedOrigins(webSocketProperties.getAllowedOrigins()); |
| | |
| | | |
| | | private double top_p = 1; |
| | | |
| | | // private String userId; |
| | | /** |
| | | * ç¥è¯åºid |
| | | */ |
| | | private String kid; |
| | | |
| | | private String userId; |
| | | // |
| | | // /** |
| | | // * ç¥è¯åºid |
| | | // */ |
| | | // private String kid; |
| | | |
| | | // |
| | | // /** |
| | | // * gptçé»è®¤è®¾ç½® |
| | |
| | | import org.ruoyi.common.chat.openai.OpenAiStreamClient; |
| | | import org.ruoyi.common.chat.utils.WebSocketUtils; |
| | | import org.ruoyi.common.core.utils.SpringUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.web.socket.*; |
| | | import org.springframework.web.socket.handler.AbstractWebSocketHandler; |
| | | |
| | |
| | | LocalCache.CACHE.put(session.getId(), JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®keyè·åValueå¼ |
| | | * |
| | | * @Date 2023/7/27 |
| | | * @param jsonObject |
| | | * @param key |
| | | * @param defaultValue |
| | | * @return String |
| | | **/ |
| | | public String getValue(JSONObject jsonObject,String key,String defaultValue){ |
| | | String value = (String)jsonObject.get(key); |
| | | if(StrUtil.isEmpty(value)){ |
| | | return defaultValue; |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | @Override |
| | | protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception { |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¯å¦æ¯æåçæ¶æ¯ |
| | | * æç¤ºå¤çç¨åºæ¯å¦æ¯ææ¥æ¶é¨åæ¶æ¯ |
| | | * |
| | | * @return |
| | | * @return å¦ææ¯ææ¥æ¶é¨åæ¶æ¯ï¼åè¿åtrueï¼å¦åè¿åfalse |
| | | */ |
| | | @Override |
| | | public boolean supportsPartialMessages() { |
| | |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletion; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletionWithPicture; |
| | | import org.ruoyi.common.chat.entity.embeddings.Embedding; |
| | | import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse; |
| | | import org.ruoyi.common.chat.entity.files.UploadFileResponse; |
| | | import org.ruoyi.common.chat.entity.images.Image; |
| | | import org.ruoyi.common.chat.entity.images.ImageResponse; |
| | |
| | | } |
| | | |
| | | /** |
| | | * ææ¬è½¬æ¢åé |
| | | * |
| | | * @param embedding å
¥å |
| | | * @return EmbeddingResponse |
| | | */ |
| | | public EmbeddingResponse embeddings(Embedding embedding) { |
| | | Single<EmbeddingResponse> embeddings = this.openAiApi.embeddings(embedding); |
| | | return embeddings.blockingGet(); |
| | | } |
| | | |
| | | /** |
| | | * è´¦æ·ä¿¡æ¯æ¥è¯¢ï¼éé¢å
嫿»éé¢çä¿¡æ¯ |
| | | * |
| | | * @return è´¦æ·ä¿¡æ¯ |
| | |
| | | <artifactId>lombok</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.binarywang</groupId> |
| | | <artifactId>weixin-java-cp</artifactId> |
| | | <version>${weixin-java-miniapp.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.github.binarywang</groupId> |
| | | <artifactId>weixin-java-cp</artifactId> |
| | | <version>${weixin-java-cp.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- èªå¨çæYMLé
ç½®å
³èJSONæä»¶ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | |
| | | Integer CAPTCHA_EXPIRATION = 30; |
| | | |
| | | /** |
| | | * æå¤å¤apiToken KEY |
| | | */ |
| | | String WDD_TOKEN_KEY = "sys_chat:wdd_api_token:"; |
| | | |
| | | /** |
| | | * æå¤å¤apiTokenæææï¼åéï¼ |
| | | */ |
| | | Integer WDD_TOKEN_EXPIRATION = 60 * 2; |
| | | |
| | | /** |
| | | * 令ç |
| | | */ |
| | | String TOKEN = "token"; |
| | |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-tomcat</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | |
| | | <!-- web 容å¨ä½¿ç¨ undertow æ§è½æ´å¼º --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-undertow</artifactId> |
| | | </dependency> |
| | | |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-actuator</artifactId> |
| | |
| | | <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"> |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>com.xmzs</groupId> |
| | | <groupId>org.ruoyi</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> |
| | | |
| | | <version>1.0.0</version> |
| | | <description>ruoyi-common-wechat 微信æå¡</description> |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <!-- emoji --> |
| | | <dependency> |
| | | <groupId>com.jfinal</groupId> |
| | | <artifactId>jfinal</artifactId> |
| | | <version>3.5</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.jfinal</groupId> |
| | | <artifactId>cos</artifactId> |
| | | <version>2017.5</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.jfinal</groupId> |
| | | <artifactId>jfinal-undertow</artifactId> |
| | | <version>1.4</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>druid</artifactId> |
| | | <version>1.0.29</version> |
| | | </dependency> |
| | | |
| | | <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> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-common-json</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | <version>1.2.31</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.api; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | 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.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.RecommendInfo; |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.Config; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.StorageLoginInfoEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.VerifyFriendEnum; |
| | | import org.ruoyi.common.wechat.web.constant.UploadConstant; |
| | | |
| | | import javax.activation.MimetypesFileTypeMap; |
| | | import java.io.File; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * æ¶æ¯å¤çç±» |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´4æ23æ¥ ä¸å2:30:37 |
| | | * @version 1.0 |
| | | * |
| | | * @author WesleyOne ä¿®æ¹ |
| | | */ |
| | | public class MessageTools implements LogInterface { |
| | | |
| | | |
| | | /** |
| | | * éè¿UserNameåéæ¶æ¯ |
| | | * @param toUserName |
| | | * @param uniqueKey |
| | | * @param data |
| | | * @param type |
| | | * @return |
| | | */ |
| | | public static boolean send(String toUserName, String uniqueKey, String data, String type){ |
| | | String nickName = WechatTools.getNickNameByUserName(toUserName, uniqueKey); |
| | | if (SendMsgType.TEXT.toValue().equals(type)){ |
| | | LOG.info("åéææ¬ {}:{}", nickName, data); |
| | | return MessageTools.sendMsgById(data,toUserName,uniqueKey); |
| | | }else if (SendMsgType.IMG.toValue().equals(type)){ |
| | | LOG.info("åéå¾ç {}:{}", nickName, UploadConstant.IMG_PATH_SEP+data); |
| | | return MessageTools.sendPicMsgByUserId(toUserName,UploadConstant.IMG_PATH_SEP+data,uniqueKey); |
| | | }else if (SendMsgType.FILE.toValue().equals(type)){ |
| | | LOG.info("åéæä»¶ {}:{}",nickName,UploadConstant.FILE_PATH_SEP+data); |
| | | return MessageTools.sendFileMsgByUserId(toUserName,UploadConstant.FILE_PATH_SEP+data,uniqueKey); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * éè¿NickNameåéæ¶æ¯ |
| | | * @param nickName |
| | | * @param uniqueKey |
| | | * @param data |
| | | * @param type |
| | | * @param isGroup |
| | | * @return |
| | | */ |
| | | public static boolean sendByNickName(String nickName, String uniqueKey, String data, String type,boolean isGroup){ |
| | | |
| | | if (SendMsgType.TEXT.toValue().equals(type)){ |
| | | LOG.info("åéææ¬ {}:{}", nickName, data); |
| | | return MessageTools.sendMsgByNickNameApi(data, nickName, uniqueKey, isGroup); |
| | | }else if (SendMsgType.IMG.toValue().equals(type)){ |
| | | LOG.info("åéå¾ç {}:{}", nickName, UploadConstant.IMG_PATH_SEP+data); |
| | | return MessageTools.sendPicMsgByNickNameApi(nickName, UploadConstant.IMG_PATH_SEP + data, uniqueKey, isGroup); |
| | | }else if (SendMsgType.FILE.toValue().equals(type)){ |
| | | LOG.info("åéæä»¶ {}:{}",nickName,UploadConstant.FILE_PATH_SEP+data); |
| | | return MessageTools.sendFileMsgByNickNameApi(nickName,UploadConstant.FILE_PATH_SEP+data,uniqueKey,isGroup); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®UserNameåéææ¬æ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ6æ¥ ä¸å11:45:51 |
| | | * @param text |
| | | * @param toUserName |
| | | * @param uniqueKey |
| | | */ |
| | | public static boolean sendMsgById(String text, String toUserName, String uniqueKey) { |
| | | if (text == null) { |
| | | return false; |
| | | } |
| | | return webWxSendMsg(1, text, toUserName, uniqueKey); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®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, String uniqueKey) { |
| | | if (nickName != null) { |
| | | String toUserName = WechatTools.getContactUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | return sendMsgById(text, toUserName, uniqueKey); |
| | | } |
| | | } |
| | | return false; |
| | | |
| | | } |
| | | |
| | | public static boolean sendMsgByNickNameApi(String text, String nickName, String uniqueKey, boolean isGroup){ |
| | | if (isGroup){ |
| | | return sendGroupMsgByNickName(text,nickName,uniqueKey); |
| | | }else{ |
| | | return sendMsgByNickName(text,nickName,uniqueKey); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®NickNameåéç¾¤ææ¬æ¶æ¯ |
| | | * @param text |
| | | * @param nickName |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | private static boolean sendGroupMsgByNickName(String text, String nickName, String uniqueKey) { |
| | | if (nickName != null) { |
| | | String toUserName = WechatTools.getGroupUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | return sendMsgById(text, toUserName, uniqueKey); |
| | | } |
| | | } |
| | | return false; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * æ¶æ¯åé |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ23æ¥ ä¸å2:32:02 |
| | | * @param msgType |
| | | * @param content |
| | | * @param toUserName |
| | | */ |
| | | public static boolean webWxSendMsg(int msgType, String content, String toUserName, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | if (!core.isAlive()){ |
| | | return false; |
| | | } |
| | | String url = String.format(URLEnum.WEB_WX_SEND_MSG.getUrl(), core.getLoginInfo().get("url")); |
| | | Map<String, Object> msgMap = new HashMap<String, Object>(12); |
| | | msgMap.put("Type", msgType); |
| | | msgMap.put("Content", content); |
| | | msgMap.put("FromUserName", core.getUserName()); |
| | | msgMap.put("ToUserName", toUserName == null ? core.getUserName() : toUserName); |
| | | msgMap.put("LocalID", System.currentTimeMillis() * 10); |
| | | msgMap.put("ClientMsgId", System.currentTimeMillis() * 10); |
| | | Map<String, Object> paramMap = core.getParamMap(); |
| | | paramMap.put("Msg", msgMap); |
| | | paramMap.put("Scene", 0); |
| | | try { |
| | | String paramStr = JSON.toJSONString(paramMap); |
| | | HttpEntity entity = core.getMyHttpClient().doPost(url, paramStr); |
| | | EntityUtils.toString(entity, Consts.UTF_8); |
| | | return true; |
| | | } catch (Exception e) { |
| | | LOG.error("webWxSendMsg", e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ä¸ä¼ å¤åªä½æä»¶å° 微信æå¡å¨ï¼ç®ååºè¯¥æ¯æ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, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | File f = new File(filePath); |
| | | if (!f.exists() || !f.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(f); |
| | | 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 = f.length(); |
| | | String passTicket = (String) core.getLoginInfo().get("pass_ticket"); |
| | | String clientMediaId = String.valueOf(System.currentTimeMillis()) |
| | | + String.valueOf(new Random().nextLong()).substring(0, 4); |
| | | String webwxDataTicket = core.getMyHttpClient().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", f, ContentType.create(mimeType), filePath); |
| | | HttpEntity reqEntity = builder.build(); |
| | | HttpEntity entity = core.getMyHttpClient().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; |
| | | } |
| | | |
| | | |
| | | public static boolean sendPicMsgByNickNameApi(String nickName, String filePath, String uniqueKey,boolean isGroup){ |
| | | if (isGroup){ |
| | | return sendGroupPicMsgByNickName(nickName, filePath, uniqueKey); |
| | | }else { |
| | | return sendPicMsgByNickName(nickName, filePath, uniqueKey); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®NickNameåéå¾çæ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ7æ¥ ä¸å10:32:45 |
| | | * @param nickName |
| | | * @param filePath |
| | | * @return |
| | | */ |
| | | public static boolean sendPicMsgByNickName(String nickName, String filePath, String uniqueKey) { |
| | | String toUserName = WechatTools.getContactUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | LOG.info("åéå¾ç {}:{}",nickName,filePath); |
| | | return sendPicMsgByUserId(toUserName, filePath, uniqueKey); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¾¤çNickNameåéå¾çæ¶æ¯å°ç¾¤ |
| | | * @param nickName |
| | | * @param filePath |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static boolean sendGroupPicMsgByNickName(String nickName, String filePath, String uniqueKey) { |
| | | String toUserName = WechatTools.getGroupUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | LOG.info("åé群å¾ç {}:{}",nickName,filePath); |
| | | return sendPicMsgByUserId(toUserName, filePath, uniqueKey); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·idåéå¾çæ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ7æ¥ ä¸å10:34:24 |
| | | * @param userId |
| | | * @param filePath |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static boolean sendPicMsgByUserId(String userId, String filePath, String uniqueKey) { |
| | | JSONObject responseObj = webWxUploadMedia(filePath, uniqueKey); |
| | | if (responseObj != null) { |
| | | String mediaId = responseObj.getString("MediaId"); |
| | | if (mediaId != null) { |
| | | return webWxSendMsgImg(userId, mediaId, uniqueKey); |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * åéå¾çæ¶æ¯ï¼å
é¨è°ç¨ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ7æ¥ ä¸å10:38:55 |
| | | * @return |
| | | */ |
| | | private static boolean webWxSendMsgImg(String userId, String mediaId, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | if (!core.isAlive()){ |
| | | return false; |
| | | } |
| | | 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>(8); |
| | | msgMap.put("Type", 3); |
| | | msgMap.put("MediaId", mediaId); |
| | | msgMap.put("FromUserName", core.getUserSelf().getString("UserName")); |
| | | msgMap.put("ToUserName", userId); |
| | | String clientMsgId = String.valueOf(System.currentTimeMillis()) |
| | | + 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 = core.getMyHttpClient().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 |
| | | */ |
| | | private static boolean sendFileMsgByUserId(String userId, String filePath, String uniqueKey) { |
| | | String title = new File(filePath).getName(); |
| | | Map<String, String> data = new HashMap<String, String>(12); |
| | | 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, uniqueKey); |
| | | if (responseObj != null) { |
| | | data.put("totallen", responseObj.getString("StartPos")); |
| | | data.put("attachid", responseObj.getString("MediaId")); |
| | | } else { |
| | | LOG.error("sednFileMsgByUserId é误: ", data); |
| | | } |
| | | return webWxSendAppMsg(userId, data, uniqueKey); |
| | | } |
| | | |
| | | public static boolean sendFileMsgByNickNameApi(String nickName, String filePath, String uniqueKey, boolean isGroup){ |
| | | if (isGroup){ |
| | | return sendGroupFileMsgByNickName(nickName,filePath,uniqueKey); |
| | | }else { |
| | | return sendFileMsgByNickName(nickName,filePath,uniqueKey); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·æµç§°åéæä»¶æ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ10æ¥ ä¸å10:59:27 |
| | | * @param nickName |
| | | * @param filePath |
| | | * @return |
| | | */ |
| | | private static boolean sendFileMsgByNickName(String nickName, String filePath, String uniqueKey) { |
| | | String toUserName = WechatTools.getContactUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | LOG.info("åéæä»¶ {}:{}",nickName,filePath); |
| | | return sendFileMsgByUserId(toUserName, filePath, uniqueKey); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ç¾¤æµç§°åéæä»¶æ¶æ¯ |
| | | * @param nickName |
| | | * @param filePath |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | private static boolean sendGroupFileMsgByNickName(String nickName, String filePath, String uniqueKey) { |
| | | String toUserName = WechatTools.getGroupUserNameByNickName(nickName,uniqueKey); |
| | | if (toUserName != null) { |
| | | LOG.info("åéæä»¶ {}:{}",nickName,filePath); |
| | | return sendFileMsgByUserId(toUserName, filePath, uniqueKey); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * å
é¨è°ç¨ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ10æ¥ ä¸å12:21:28 |
| | | * @param userId |
| | | * @param data |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | private static boolean webWxSendAppMsg(String userId, Map<String, String> data, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | if (!core.isAlive()){ |
| | | return false; |
| | | } |
| | | 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(System.currentTimeMillis()) |
| | | + 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>(12); |
| | | 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 = core.getMyHttpClient().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 æç» |
| | | */ |
| | | private static void addFriend(BaseMsg msg, boolean accept, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | 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 = core.getMyHttpClient().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); |
| | | |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.api; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.http.Consts; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.StorageLoginInfoEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 微信å°å·¥å
·ï¼å¦è·å¥½åå表,æ ¹æ®æµç§°æ¥æ¾å¥½åæç¾¤ç |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´5æ4æ¥ ä¸å10:49:16 |
| | | * @version 1.0 |
| | | * |
| | | * @author WesleyOne ä¿®æ¹ |
| | | */ |
| | | public class WechatTools implements LogInterface { |
| | | |
| | | /** |
| | | * è¿åå¥½åæµç§°å表 |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static List<String> getContactNickNameList(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | List<String> contactNickNameList = new ArrayList<String>(); |
| | | for (JSONObject o : core.getContactList()) { |
| | | contactNickNameList.add(o.getString("NickName")); |
| | | // 顺便å·ä¸ç¼å |
| | | core.getUserInfoMap().put(o.getString("NickName"),o); |
| | | core.getUserInfoMap().put(o.getString("UserName"),o); |
| | | } |
| | | return contactNickNameList; |
| | | } |
| | | |
| | | /** |
| | | * è¿å好å宿´ä¿¡æ¯å表 |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static List<JSONObject> getContactList(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | return core.getContactList(); |
| | | } |
| | | |
| | | /** |
| | | * è¿å群å表 |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static List<JSONObject> getGroupList(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | return core.getGroupList(); |
| | | } |
| | | |
| | | /** |
| | | * è·å群NickNameå表 |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static List<String> getGroupNickNameList(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | List<String> groupNickNameList = new ArrayList<String>(); |
| | | for (JSONObject o : core.getGroupList()) { |
| | | groupNickNameList.add(o.getString("NickName")); |
| | | } |
| | | return groupNickNameList; |
| | | } |
| | | |
| | | /** |
| | | * è·åç¾¤æææåä¿¡æ¯ |
| | | * @param groupId |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static JSONArray getGroupMemberByGroupId(String groupId, String uniqueKey){ |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | JSONObject jsonObject = core.getGroupInfoMap().get(groupId); |
| | | if (jsonObject == null){ |
| | | return new JSONArray(); |
| | | } |
| | | return jsonObject.getJSONArray("MemberList"); |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¾¤æåIDè·åæµç§° |
| | | * @param groupId |
| | | * @param uniqueKey |
| | | * @param memberId |
| | | * @return |
| | | */ |
| | | public static String getMemberNickName(String groupId, String uniqueKey, String memberId){ |
| | | JSONArray members = getGroupMemberByGroupId(groupId, uniqueKey); |
| | | int size = members.size(); |
| | | if (size > 0){ |
| | | for (int i=0;i<size;i++){ |
| | | JSONObject jsonObject = members.getJSONObject(i); |
| | | if (memberId.equals(jsonObject.getString("UserName"))){ |
| | | return jsonObject.getString("NickName"); |
| | | } |
| | | } |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * éåºå¾®ä¿¡ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ18æ¥ ä¸å11:56:54 |
| | | */ |
| | | public static void logout(String uniqueKey) { |
| | | webWxLogout(uniqueKey); |
| | | } |
| | | |
| | | private static boolean webWxLogout(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | 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()); |
| | | } finally { |
| | | // 强å¶éåºï¼æç¤ºç¸å
³çº¿ç¨éåº |
| | | core.setAlive(false); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public static void setUserInfo(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | 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 nickName |
| | | * @param remName |
| | | */ |
| | | public static void remarkNameByNickName(String nickName, String remName, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | 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>(8); |
| | | Map<String, Object> msgMap_BaseRequest = new HashMap<String, Object>(8); |
| | | 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(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | return core.isAlive(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * |
| | | * @param userName |
| | | * @param nickName |
| | | * @return |
| | | */ |
| | | private static JSONObject getContactByNickNameAndUserName(String userName, String nickName, String uniqueKey){ |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | // éè¿userNameæ¥è¯¢ |
| | | if (StringUtils.isNotEmpty(userName) && StringUtils.isEmpty(nickName)){ |
| | | for (JSONObject contact:core.getContactList()){ |
| | | if (userName.equals(contact.getString("UserName"))){ |
| | | return contact; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // éè¿ç¾¤æµç§°æ¥è¯¢ |
| | | if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(userName)){ |
| | | for (JSONObject contact:core.getContactList()){ |
| | | if (nickName.equals(contact.getString("NickName"))){ |
| | | return contact; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // éè¿userNameåæµç§°è忥 |
| | | if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(nickName)){ |
| | | for (JSONObject contact:core.getContactList()){ |
| | | if (nickName.equals(contact.getString("NickName")) && userName.equals(contact.getString("UserName"))){ |
| | | return contact; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¾¤idæ¥æ¾ç¾¤æµç§° |
| | | * @param userName |
| | | * @return |
| | | */ |
| | | public static String getContactNickNameByUserName(String userName, String uniqueKey){ |
| | | JSONObject contact = getContactByNickNameAndUserName(userName,null, uniqueKey); |
| | | if (contact!=null && StringUtils.isNotEmpty(contact.getString("NickName"))){ |
| | | return contact.getString("NickName"); |
| | | }else{ |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¾¤æµç§°æ¥æ¾ç¾¤id |
| | | * @param nickName |
| | | * @return |
| | | */ |
| | | public static String getContactUserNameByNickName(String nickName, String uniqueKey){ |
| | | JSONObject contact = getContactByNickNameAndUserName(null,nickName,uniqueKey); |
| | | if (contact!=null && StringUtils.isNotEmpty(contact.getString("UserName"))){ |
| | | return contact.getString("UserName"); |
| | | }else{ |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿userNameææµç§°æ¥æ¾ç¾¤ä¿¡æ¯ |
| | | * @param userName |
| | | * @return |
| | | */ |
| | | private static JSONObject getGroupByNickNameAndUserName(String userName, String nickName, String uniqueKey){ |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | // éè¿userNameæ¥è¯¢ |
| | | if (StringUtils.isNotEmpty(userName) && StringUtils.isEmpty(nickName)){ |
| | | for (JSONObject group:core.getGroupList()){ |
| | | if (userName.equals(group.getString("UserName"))){ |
| | | return group; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // éè¿ç¾¤æµç§°æ¥è¯¢ |
| | | if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(userName)){ |
| | | for (JSONObject group:core.getGroupList()){ |
| | | if (nickName.equals(group.getString("NickName"))){ |
| | | return group; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // éè¿userNameåæµç§°è忥 |
| | | if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(nickName)){ |
| | | for (JSONObject group:core.getGroupList()){ |
| | | if (nickName.equals(group.getString("NickName")) && userName.equals(group.getString("UserName"))){ |
| | | return group; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¾¤idæ¥æ¾ç¾¤æµç§° |
| | | * @param userName |
| | | * @return |
| | | */ |
| | | public static String getGroupNickNameByUserName(String userName, String uniqueKey){ |
| | | JSONObject group = getGroupByNickNameAndUserName(userName,null,uniqueKey); |
| | | if (group!=null && StringUtils.isNotEmpty(group.getString("NickName"))){ |
| | | return group.getString("NickName"); |
| | | }else{ |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿ç¾¤æµç§°æ¥æ¾ç¾¤id |
| | | * @param nickName |
| | | * @return |
| | | */ |
| | | public static String getGroupUserNameByNickName(String nickName, String uniqueKey){ |
| | | JSONObject group = getGroupByNickNameAndUserName(null,nickName, uniqueKey); |
| | | if (group!=null && StringUtils.isNotEmpty(group.getString("UserName"))){ |
| | | return group.getString("UserName"); |
| | | }else{ |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * éè¿UserNameæ¥æ¾NickName |
| | | * åªæ¥ç¾¤åå好åå |
| | | * @param userName |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static String getNickNameByUserName(String userName, String uniqueKey){ |
| | | if (userName.startsWith("@@")){ |
| | | return getGroupNickNameByUserName(userName,uniqueKey); |
| | | }else if (userName.startsWith("@")){ |
| | | return getContactNickNameByUserName(userName,uniqueKey); |
| | | }else { |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | private boolean atMe; |
| | | // 群åéè
IDæµç§° |
| | | private String sendMemberId; |
| | | private String memberNickname; |
| | | /** æ¶æ¯åéè
ID **/ |
| | | private String fromUserName; |
| | | private String oriContent; |
| | | private String fileSize; |
| | | private String fromNickName; |
| | | |
| | | 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; |
| | | } |
| | | |
| | | public String getMemberNickname() { |
| | | return memberNickname; |
| | | } |
| | | |
| | | public void setMemberNickname(String memberNickname) { |
| | | this.memberNickname = memberNickname; |
| | | } |
| | | |
| | | public String getFromNickName() { |
| | | return fromNickName; |
| | | } |
| | | |
| | | public void setFromNickName(String fromNickName) { |
| | | this.fromNickName = fromNickName; |
| | | } |
| | | |
| | | public String getSendMemberId() { |
| | | return sendMemberId; |
| | | } |
| | | |
| | | public void setSendMemberId(String sendMemberId) { |
| | | this.sendMemberId = sendMemberId; |
| | | } |
| | | |
| | | public boolean isAtMe() { |
| | | return atMe; |
| | | } |
| | | |
| | | public void setAtMe(boolean atMe) { |
| | | this.atMe = atMe; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | @Deprecated |
| | | public class BaseResponse { |
| | | |
| | | private Integer Ret; |
| | | private String ErrMsg; |
| | | |
| | | public Integer getRet() { |
| | | return Ret; |
| | | } |
| | | |
| | | public void setRet(Integer ret) { |
| | | Ret = ret; |
| | | } |
| | | |
| | | public String getErrMsg() { |
| | | return ErrMsg; |
| | | } |
| | | |
| | | public void setErrMsg(String errMsg) { |
| | | ErrMsg = errMsg; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æåä¿¡æ¯å¯¹è±¡ |
| | | * |
| | | * æ¥èªè·å好åå表 |
| | | * /cgi-bin/mmwebwx-bin/webwxgetcontact |
| | | * MemberListä¸åä½ |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | @Deprecated |
| | | public class Member { |
| | | |
| | | private String Alias; |
| | | private Integer AppAccountFlag; |
| | | private Integer AttrStatus; |
| | | private Integer ChatRoomId; |
| | | private String City; |
| | | private Integer ContactFlag; |
| | | /** |
| | | * 群æµç§° |
| | | */ |
| | | private String DisplayName; |
| | | private String EncryChatRoomId; |
| | | private String HeadImgUrl; |
| | | private Integer HideInputBarFlag; |
| | | private Integer IsOwner; |
| | | private String KeyWord; |
| | | private Integer MemberCount; |
| | | private List<Member> MemberList; |
| | | private String NickName; |
| | | private Integer OwnerUin; |
| | | private String PYInitial; |
| | | private String PYQuanPin; |
| | | private String Province; |
| | | /** |
| | | * 夿³¨åã馿¼ãå
¨æ¼ |
| | | */ |
| | | private String RemarkName; |
| | | private String RemarkPYInitial; |
| | | private String RemarkPYQuanPin; |
| | | |
| | | private Integer Sex; |
| | | private String Signature; |
| | | private Integer SnsFlag; |
| | | private Integer StarFriend; |
| | | private Integer Statues; |
| | | private Integer Uin; |
| | | private Integer UniFriend; |
| | | private String UserName; |
| | | /** |
| | | * ç¨æ¥å¤ææ¯å¦æ¯å
¬ä¼å·ææå¡å·çåæ®µ |
| | | */ |
| | | private String VerifyFlag; |
| | | |
| | | public String getAlias() { |
| | | return Alias; |
| | | } |
| | | |
| | | public void setAlias(String alias) { |
| | | Alias = alias; |
| | | } |
| | | |
| | | public Integer getAppAccountFlag() { |
| | | return AppAccountFlag; |
| | | } |
| | | |
| | | public void setAppAccountFlag(Integer appAccountFlag) { |
| | | AppAccountFlag = appAccountFlag; |
| | | } |
| | | |
| | | public Integer getAttrStatus() { |
| | | return AttrStatus; |
| | | } |
| | | |
| | | public void setAttrStatus(Integer attrStatus) { |
| | | AttrStatus = attrStatus; |
| | | } |
| | | |
| | | public Integer getChatRoomId() { |
| | | return ChatRoomId; |
| | | } |
| | | |
| | | public void setChatRoomId(Integer chatRoomId) { |
| | | ChatRoomId = chatRoomId; |
| | | } |
| | | |
| | | public String getCity() { |
| | | return City; |
| | | } |
| | | |
| | | public void setCity(String city) { |
| | | City = city; |
| | | } |
| | | |
| | | public Integer getContactFlag() { |
| | | return ContactFlag; |
| | | } |
| | | |
| | | public void setContactFlag(Integer contactFlag) { |
| | | ContactFlag = contactFlag; |
| | | } |
| | | |
| | | public String getDisplayName() { |
| | | return DisplayName; |
| | | } |
| | | |
| | | public void setDisplayName(String displayName) { |
| | | DisplayName = displayName; |
| | | } |
| | | |
| | | public String getEncryChatRoomId() { |
| | | return EncryChatRoomId; |
| | | } |
| | | |
| | | public void setEncryChatRoomId(String encryChatRoomId) { |
| | | EncryChatRoomId = encryChatRoomId; |
| | | } |
| | | |
| | | public String getHeadImgUrl() { |
| | | return HeadImgUrl; |
| | | } |
| | | |
| | | public void setHeadImgUrl(String headImgUrl) { |
| | | HeadImgUrl = headImgUrl; |
| | | } |
| | | |
| | | public Integer getHideInputBarFlag() { |
| | | return HideInputBarFlag; |
| | | } |
| | | |
| | | public void setHideInputBarFlag(Integer hideInputBarFlag) { |
| | | HideInputBarFlag = hideInputBarFlag; |
| | | } |
| | | |
| | | public Integer getIsOwner() { |
| | | return IsOwner; |
| | | } |
| | | |
| | | public void setIsOwner(Integer isOwner) { |
| | | IsOwner = isOwner; |
| | | } |
| | | |
| | | public String getKeyWord() { |
| | | return KeyWord; |
| | | } |
| | | |
| | | public void setKeyWord(String keyWord) { |
| | | KeyWord = keyWord; |
| | | } |
| | | |
| | | public Integer getMemberCount() { |
| | | return MemberCount; |
| | | } |
| | | |
| | | public void setMemberCount(Integer memberCount) { |
| | | MemberCount = memberCount; |
| | | } |
| | | |
| | | public List<Member> getMemberList() { |
| | | return MemberList; |
| | | } |
| | | |
| | | public void setMemberList(List<Member> memberList) { |
| | | MemberList = memberList; |
| | | } |
| | | |
| | | public String getNickName() { |
| | | return NickName; |
| | | } |
| | | |
| | | public void setNickName(String nickName) { |
| | | NickName = nickName; |
| | | } |
| | | |
| | | public Integer getOwnerUin() { |
| | | return OwnerUin; |
| | | } |
| | | |
| | | public void setOwnerUin(Integer ownerUin) { |
| | | OwnerUin = ownerUin; |
| | | } |
| | | |
| | | public String getPYInitial() { |
| | | return PYInitial; |
| | | } |
| | | |
| | | public void setPYInitial(String PYInitial) { |
| | | this.PYInitial = PYInitial; |
| | | } |
| | | |
| | | public String getPYQuanPin() { |
| | | return PYQuanPin; |
| | | } |
| | | |
| | | public void setPYQuanPin(String PYQuanPin) { |
| | | this.PYQuanPin = PYQuanPin; |
| | | } |
| | | |
| | | public String getProvince() { |
| | | return Province; |
| | | } |
| | | |
| | | public void setProvince(String province) { |
| | | Province = province; |
| | | } |
| | | |
| | | public String getRemarkName() { |
| | | return RemarkName; |
| | | } |
| | | |
| | | public void setRemarkName(String remarkName) { |
| | | RemarkName = remarkName; |
| | | } |
| | | |
| | | public String getRemarkPYInitial() { |
| | | return RemarkPYInitial; |
| | | } |
| | | |
| | | public void setRemarkPYInitial(String remarkPYInitial) { |
| | | RemarkPYInitial = remarkPYInitial; |
| | | } |
| | | |
| | | public String getRemarkPYQuanPin() { |
| | | return RemarkPYQuanPin; |
| | | } |
| | | |
| | | public void setRemarkPYQuanPin(String remarkPYQuanPin) { |
| | | RemarkPYQuanPin = remarkPYQuanPin; |
| | | } |
| | | |
| | | public Integer getSex() { |
| | | return Sex; |
| | | } |
| | | |
| | | public void setSex(Integer sex) { |
| | | Sex = sex; |
| | | } |
| | | |
| | | public String getSignature() { |
| | | return Signature; |
| | | } |
| | | |
| | | public void setSignature(String signature) { |
| | | Signature = signature; |
| | | } |
| | | |
| | | public Integer getSnsFlag() { |
| | | return SnsFlag; |
| | | } |
| | | |
| | | public void setSnsFlag(Integer snsFlag) { |
| | | SnsFlag = snsFlag; |
| | | } |
| | | |
| | | public Integer getStarFriend() { |
| | | return StarFriend; |
| | | } |
| | | |
| | | public void setStarFriend(Integer starFriend) { |
| | | StarFriend = starFriend; |
| | | } |
| | | |
| | | public Integer getStatues() { |
| | | return Statues; |
| | | } |
| | | |
| | | public void setStatues(Integer statues) { |
| | | Statues = statues; |
| | | } |
| | | |
| | | public Integer getUin() { |
| | | return Uin; |
| | | } |
| | | |
| | | public void setUin(Integer uin) { |
| | | Uin = uin; |
| | | } |
| | | |
| | | public Integer getUniFriend() { |
| | | return UniFriend; |
| | | } |
| | | |
| | | public void setUniFriend(Integer uniFriend) { |
| | | UniFriend = uniFriend; |
| | | } |
| | | |
| | | public String getUserName() { |
| | | return UserName; |
| | | } |
| | | |
| | | public void setUserName(String userName) { |
| | | UserName = userName; |
| | | } |
| | | |
| | | public String getVerifyFlag() { |
| | | return VerifyFlag; |
| | | } |
| | | |
| | | public void setVerifyFlag(String verifyFlag) { |
| | | VerifyFlag = verifyFlag; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * åéæ¶æ¯ä½ |
| | | * @author WesleyOne |
| | | * @create 2019/1/7 |
| | | */ |
| | | public class SendMsg implements Serializable { |
| | | |
| | | private String userName; |
| | | private String nickName; |
| | | private String message; |
| | | private SendMsgType msgType; |
| | | private boolean isGroup; |
| | | |
| | | 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 String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public void setMessage(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public SendMsgType getMsgType() { |
| | | return msgType; |
| | | } |
| | | |
| | | public void setMsgType(SendMsgType msgType) { |
| | | this.msgType = msgType; |
| | | } |
| | | |
| | | public boolean isGroup() { |
| | | return isGroup; |
| | | } |
| | | |
| | | public void setGroup(boolean group) { |
| | | isGroup = group; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | @Deprecated |
| | | public class SyncKey { |
| | | |
| | | private Integer Count; |
| | | |
| | | private List<KV> List; |
| | | |
| | | public Integer getCount() { |
| | | return Count; |
| | | } |
| | | |
| | | public void setCount(Integer count) { |
| | | Count = count; |
| | | } |
| | | |
| | | public java.util.List<KV> getList() { |
| | | return List; |
| | | } |
| | | |
| | | public void setList(java.util.List<KV> list) { |
| | | List = list; |
| | | } |
| | | |
| | | class KV{ |
| | | private Integer Key; |
| | | private Long Val; |
| | | |
| | | public Integer getKey() { |
| | | return Key; |
| | | } |
| | | |
| | | public void setKey(Integer key) { |
| | | Key = key; |
| | | } |
| | | |
| | | public Long getVal() { |
| | | return Val; |
| | | } |
| | | |
| | | public void setVal(Long val) { |
| | | Val = val; |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | /* |
| | | AppAccountFlag: 0 |
| | | ContactFlag: 0 |
| | | HeadImgFlag: 1 |
| | | HeadImgUrl: "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=778915892&username=@7e6934104b3cf1f92dd11344c63a06833ae54bd43b34229b5cc472c4d05eba4a&skey=@crypt_a24169c_f4c07f70afe861da5e8a6e1947044b6e" |
| | | HideInputBarFlag: 0 |
| | | NickName: "[è¡°]æâ¢âçâÅ" |
| | | PYInitial: "" |
| | | PYQuanPin: "" |
| | | RemarkName: "" |
| | | RemarkPYInitial: "" |
| | | RemarkPYQuanPin: "" |
| | | Sex: 1 |
| | | Signature: "人工æâ¢ÂºÃ©Å¡Å" |
| | | SnsFlag: 49 |
| | | StarFriend: 0 |
| | | Uin: 902478981 |
| | | UserName: "@7e6934104b3cf1f92dd11344c63a06833ae54bd43b34229b5cc472c4d05eba4a" |
| | | VerifyFlag: 0 |
| | | WebWxPluginSwitch: 0 |
| | | */ |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | @Deprecated |
| | | public class User { |
| | | |
| | | private String AppAccountFlag; |
| | | private String ContactFlag; |
| | | private String HeadImgFlag; |
| | | private String HeadImgUrl; |
| | | private String HideInputBarFlag; |
| | | private String NickName; |
| | | private String PYInitial; |
| | | private String PYQuanPin; |
| | | private String RemarkName; |
| | | private String RemarkPYInitial; |
| | | private String RemarkPYQuanPin; |
| | | private String Sex; |
| | | /** |
| | | * ç¾å |
| | | */ |
| | | private String Signature; |
| | | private String SnsFlag; |
| | | private String StarFriend; |
| | | private String Uin; |
| | | private String UserName; |
| | | private String VerifyFlag; |
| | | private String WebWxPluginSwitch; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.beans; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | @Deprecated |
| | | public class WebWxInit { |
| | | |
| | | private BaseResponse BaseResponse; |
| | | |
| | | private String ChatSet; |
| | | |
| | | private Long ClickReportInterval; |
| | | |
| | | private Long ClientVersion; |
| | | |
| | | private List<Member> ContactList; |
| | | |
| | | private Integer Count; |
| | | |
| | | private Integer GrayScale; |
| | | |
| | | private Integer InviteStartCount; |
| | | |
| | | /** |
| | | * 订é
å·å段çç¥ |
| | | * MPSubscribeMsgCount |
| | | * MPSubscribeMsgList |
| | | */ |
| | | |
| | | private String SKey; |
| | | |
| | | private SyncKey SyncKey; |
| | | |
| | | private Long SystemTime; |
| | | |
| | | private User User; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.client; |
| | | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.http.client.CookieStore; |
| | | |
| | | import java.util.HashMap; |
| | | |
| | | /** |
| | | * å¤å¼è¯·æ±ç±»ç®¡ç |
| | | * @author WesleyOne |
| | | * @create 2018/12/15 |
| | | */ |
| | | public class HttpClientManage { |
| | | |
| | | private static HashMap<String,SingleHttpClient> clientMap = new HashMap<>(32); |
| | | |
| | | public static SingleHttpClient getInstance(String uniqueKey){ |
| | | return getInstance(uniqueKey,null); |
| | | } |
| | | |
| | | public static SingleHttpClient getInstance(String uniqueKey,CookieStore outCookieStore) { |
| | | if (StringUtils.isEmpty(uniqueKey)){ |
| | | return null; |
| | | } |
| | | SingleHttpClient client; |
| | | |
| | | // outCookieStoreä¸ä¸ºç©ºæ¶ä¹éæ°æé ,主è¦ç¨äºçç»å½ |
| | | if (!clientMap.containsKey(uniqueKey) || clientMap.get(uniqueKey) == null || outCookieStore != null){ |
| | | client = SingleHttpClient.getInstance(outCookieStore); |
| | | clientMap.put(uniqueKey, client); |
| | | } |
| | | return clientMap.get(uniqueKey); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.client; |
| | | |
| | | 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.DefaultHttpRequestRetryHandler; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.Config; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/15 |
| | | */ |
| | | public class SingleHttpClient { |
| | | private Logger logger = LoggerFactory.getLogger("UTILLOG"); |
| | | |
| | | private CloseableHttpClient httpClient ; |
| | | |
| | | private CookieStore cookieStore; |
| | | |
| | | private String uniqueKey; |
| | | |
| | | public String getCookie(String name) { |
| | | List<Cookie> cookies = cookieStore.getCookies(); |
| | | for (Cookie cookie : cookies) { |
| | | if (cookie.getName().equalsIgnoreCase(name)) { |
| | | return cookie.getValue(); |
| | | } |
| | | } |
| | | return null; |
| | | |
| | | } |
| | | |
| | | private SingleHttpClient(CookieStore outCookieStore){ |
| | | if (outCookieStore == null){ |
| | | outCookieStore = new BasicCookieStore(); |
| | | } |
| | | this.cookieStore = outCookieStore; |
| | | httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).setRetryHandler(new DefaultHttpRequestRetryHandler(0,false)).build(); |
| | | } |
| | | |
| | | private SingleHttpClient(){ |
| | | this(null); |
| | | } |
| | | |
| | | public static SingleHttpClient getInstance(CookieStore outCookieStore){ |
| | | return new SingleHttpClient(outCookieStore); |
| | | } |
| | | |
| | | /** |
| | | * å¤ç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); |
| | | // System.out.println(url + "?" + paramStr); |
| | | } else { |
| | | httpGet = new HttpGet(url); |
| | | } |
| | | if (!redirect) { |
| | | // ç¦æ¢éå®å |
| | | httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build()); |
| | | } |
| | | httpGet.setHeader("User-Agent", Config.USER_AGENT); |
| | | if (headerMap != null) { |
| | | Set<Map.Entry<String, String>> entries = headerMap.entrySet(); |
| | | for (Map.Entry<String, String> entry : entries) { |
| | | httpGet.setHeader(entry.getKey(), entry.getValue()); |
| | | } |
| | | } |
| | | CloseableHttpResponse response = httpClient.execute(httpGet); |
| | | entity = response.getEntity(); |
| | | } catch (ClientProtocolException e) { |
| | | logger.error(e.getMessage()); |
| | | } catch (IOException e) { |
| | | logger.error(e.getMessage()); |
| | | } catch (Exception e){ |
| | | logger.error(e.getMessage()); |
| | | } |
| | | return entity; |
| | | } |
| | | |
| | | /** |
| | | * å¤çPOSTè¯·æ± |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ9æ¥ ä¸å7:06:35 |
| | | * @param url |
| | | * @param paramsStr |
| | | * @return |
| | | */ |
| | | public HttpEntity doPost(String url, String paramsStr) { |
| | | return doPost(url,paramsStr,null); |
| | | } |
| | | |
| | | public HttpEntity doPost(String url, String paramsStr, Map<String, String> headerMap) { |
| | | 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); |
| | | if (headerMap != null) { |
| | | Set<Map.Entry<String, String>> entries = headerMap.entrySet(); |
| | | for (Map.Entry<String, String> entry : entries) { |
| | | httpPost.setHeader(entry.getKey(), entry.getValue()); |
| | | } |
| | | } |
| | | CloseableHttpResponse response = httpClient.execute(httpPost); |
| | | entity = response.getEntity(); |
| | | } catch (ClientProtocolException e) { |
| | | logger.error(e.getMessage()); |
| | | } catch (IOException e) { |
| | | logger.error(e.getMessage()); |
| | | } catch (Exception e){ |
| | | logger.error(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.setEntity(reqEntity); |
| | | try { |
| | | CloseableHttpResponse response = httpClient.execute(httpPost); |
| | | entity = response.getEntity(); |
| | | |
| | | } catch (Exception e) { |
| | | logger.error(e.getMessage()); |
| | | } |
| | | return entity; |
| | | } |
| | | |
| | | |
| | | public CookieStore getCookieStore() { |
| | | return this.cookieStore; |
| | | } |
| | | |
| | | public void setCookieStore(CookieStore cookieStore) { |
| | | this.cookieStore = cookieStore; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.controller; |
| | | |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.core.MsgCenter; |
| | | import org.ruoyi.common.wechat.itchat4j.service.ILoginService; |
| | | import org.ruoyi.common.wechat.itchat4j.service.impl.LoginServiceImpl; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.SleepUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum; |
| | | import org.ruoyi.common.wechat.web.base.BaseException; |
| | | |
| | | /** |
| | | * ç»éæ§å¶å¨ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´5æ13æ¥ ä¸å12:56:07 |
| | | * @version 1.0 |
| | | * |
| | | * @author WesleyOne ä¿®æ¹ |
| | | */ |
| | | public class LoginController implements LogInterface { |
| | | |
| | | private ILoginService loginService; |
| | | private String uniqueKey; |
| | | private Core core; |
| | | |
| | | public LoginController(String uniqueKey){ |
| | | this.uniqueKey = uniqueKey; |
| | | this.loginService = new LoginServiceImpl(uniqueKey); |
| | | this.core = CoreManage.getInstance(uniqueKey); |
| | | } |
| | | |
| | | /** |
| | | * è·åäºç»´ç å°å |
| | | * é£é©:å·²ç»å½è´¦å·ä¸å¯è°ç¨è¯¥æ¥å£,ä¼ç§»é¤å½åcoreä¿¡æ¯ |
| | | * @return |
| | | */ |
| | | public String login_1() throws BaseException { |
| | | if (core.isAlive()) { |
| | | LOG.warn("微信已ç»é"); |
| | | throw new BaseException("微信已ç»é"); |
| | | } |
| | | LOG.info("1.è·å微信UUID"); |
| | | while (loginService.getUuid() == null) { |
| | | LOG.warn("1.1. è·å微信UUID失败ï¼ä¸ç§åéæ°è·å"); |
| | | SleepUtils.sleep(1000); |
| | | } |
| | | LOG.info("2. è·åç»éäºç»´ç å¾ç"); |
| | | return URLEnum.QRCODE_URL.getUrl() + core.getUuid(); |
| | | } |
| | | |
| | | /** |
| | | * 确认ç»å½ |
| | | * @return |
| | | */ |
| | | public boolean login_2(){ |
| | | |
| | | boolean result = false; |
| | | |
| | | LOG.info("3. è¯·æ«æäºç»´ç å¾çï¼å¹¶å¨ææºä¸ç¡®è®¤"); |
| | | if (!core.isAlive()) { |
| | | if (loginService.login()){ |
| | | core.setAlive(true); |
| | | LOG.info(("3.1ç»éæå")); |
| | | result = true; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * å è½½æ°æ® |
| | | * @return |
| | | */ |
| | | public boolean login_3() { |
| | | |
| | | boolean result = true; |
| | | |
| | | LOG.info("4.微信åå§å"); |
| | | if (!loginService.webWxInit()) { |
| | | LOG.info("4.1 微信åå§åå¼å¸¸"); |
| | | result = false; |
| | | } |
| | | |
| | | if (result){ |
| | | |
| | | LOG.info("5. å¼å¯å¾®ä¿¡ç¶æéç¥"); |
| | | loginService.wxStatusNotify(); |
| | | |
| | | LOG.info(String.format("欢è¿åæ¥ï¼ %s", core.getNickName())); |
| | | LOG.info("6.+++å¼å¯æ¶æ¯åé线ç¨["+uniqueKey+"]+++"); |
| | | Thread sendThread = new Thread(core.getThreadGroup(), () -> MsgCenter.sendMsg(uniqueKey), "SEND-" + uniqueKey); |
| | | sendThread.start(); |
| | | |
| | | LOG.info("8. +++å¼å§æ¥æ¶æ¶æ¯çº¿ç¨["+uniqueKey+"]+++"); |
| | | loginService.startReceiving(); |
| | | |
| | | LOG.info("9. è·åè系人信æ¯"); |
| | | loginService.webWxGetContact(); |
| | | |
| | | LOG.info("10. è·å群好åå群好åå表åç¼å"); |
| | | loginService.WebWxBatchGetContact(); |
| | | |
| | | } |
| | | |
| | | if (!result){ |
| | | core.setAlive(false); |
| | | return false; |
| | | } |
| | | |
| | | core.setFinishInit(true); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | public boolean reboot(){ |
| | | |
| | | core.setFinishInit(false); |
| | | // éæ°å è½½æ°æ® |
| | | boolean result = true; |
| | | LOG.info("1.å·æ°åå§åä¿¡æ¯"); |
| | | if (!loginService.webWxInit()) { |
| | | LOG.info("1.1 微信åå§åå¼å¸¸"); |
| | | result = false; |
| | | } |
| | | |
| | | if (result){ |
| | | LOG.info("2. å·æ°å¼å¯å¾®ä¿¡ç¶æéç¥"); |
| | | loginService.wxStatusNotify(); |
| | | |
| | | LOG.info("3. å·æ°è·åè系人信æ¯"); |
| | | loginService.webWxGetContact(); |
| | | |
| | | LOG.info("4. å·æ°è·å群好åå群好åå表"); |
| | | loginService.WebWxBatchGetContact(); |
| | | } |
| | | |
| | | if (!result){ |
| | | core.setAlive(false); |
| | | return false; |
| | | } |
| | | |
| | | core.setFinishInit(true); |
| | | return true; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.core; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.alibaba.fastjson.annotation.JSONField; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.SendMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.User; |
| | | import org.ruoyi.common.wechat.itchat4j.client.HttpClientManage; |
| | | import org.ruoyi.common.wechat.itchat4j.client.SingleHttpClient; |
| | | import org.ruoyi.common.wechat.itchat4j.service.impl.LoginServiceImpl; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.BaseParaEnum; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æ ¸å¿åå¨ç±»ï¼å
¨å±åªä¿åä¸ä»½ï¼å便¨¡å¼ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @author WesleyOne ä¿®æ¹ |
| | | * @version 1.0 |
| | | * @date å建æ¶é´ï¼2017å¹´4æ23æ¥ ä¸å2:33:56 |
| | | */ |
| | | public class Core { |
| | | |
| | | private Core() { |
| | | |
| | | } |
| | | |
| | | private Core(String uniqueKey) { |
| | | this.uniqueKey = uniqueKey; |
| | | this.myHttpClient = HttpClientManage.getInstance(this.uniqueKey); |
| | | this.threadGroup = new ThreadGroup(this.uniqueKey); |
| | | } |
| | | |
| | | protected static Core getInstance(String uniqueKey) { |
| | | return new Core(uniqueKey); |
| | | } |
| | | |
| | | private String uniqueKey; |
| | | |
| | | boolean alive = false; |
| | | |
| | | /** |
| | | * 管çå½åæºå¨äººçææä¸å¡çº¿ç¨ |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private ThreadGroup threadGroup; |
| | | |
| | | @JSONField(serialize = false) |
| | | boolean isFinishInit = false; |
| | | |
| | | /** |
| | | * login,webWxInit |
| | | * ç»å½æ¥å£è·å |
| | | */ |
| | | private String indexUrl; |
| | | private String userName; |
| | | private String nickName; |
| | | String uuid = null; |
| | | /** |
| | | * webWxInit |
| | | * InviteStartCount |
| | | * SyncKey |
| | | * synckey éçæ¯æ¬¡è·åææ°æ¶æ¯åçè¿å弿´æ°ï¼å
¶ç®çå¨äºæ¯æ¬¡åæ¥æ¶æ¯åè®°å½ä¸ä¸ªå½å忥çç¶æ |
| | | */ |
| | | Map<String, Object> loginInfo = new HashMap<String, Object>(); |
| | | |
| | | /** |
| | | * webWxInit |
| | | * ç»éè´¦å·èªèº«ä¿¡æ¯ |
| | | * |
| | | * @see User |
| | | */ |
| | | private JSONObject userSelf; |
| | | |
| | | |
| | | /** |
| | | * åå§å/cgi-bin/mmwebwx-bin/webwxinit |
| | | * æå䏿¬¡æ¶å°æ£å¸¸retcodeçæ¶é´ï¼ç§ä¸ºåä½ |
| | | * <p> |
| | | * synccheckå·æ° |
| | | */ |
| | | private long lastNormalRetcodeTime; |
| | | |
| | | |
| | | /** |
| | | * synccheckåwebWxSync容鿬¡æ°,è¶
è¿éåº |
| | | */ |
| | | int receivingRetryCount = 5; |
| | | |
| | | |
| | | @JSONField(serialize = false) |
| | | SingleHttpClient myHttpClient; |
| | | |
| | | public SingleHttpClient getMyHttpClient() { |
| | | return HttpClientManage.getInstance(uniqueKey); |
| | | } |
| | | |
| | | /** |
| | | * åå§è¯æ¶è·åè系人æ¶å建 |
| | | * @see LoginServiceImpl#webWxGetContact() |
| | | */ |
| | | /** |
| | | * memberListé¿åº¦ |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private int memberCount = 0; |
| | | /** |
| | | * 好å+群è+å
¬ä¼å·+ç¹æ®è´¦å· |
| | | * 注æï¼ä¸ä¸»å¨æå
¥,è·åæ¶éè¿å
¶ä»å 个账å·éååå¹¶ |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<JSONObject> memberList = new ArrayList<JSONObject>(); |
| | | /** |
| | | * 好å |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<JSONObject> contactList = new ArrayList<JSONObject>(); |
| | | /** |
| | | * 群 |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<JSONObject> groupList = new ArrayList<JSONObject>(); |
| | | /** |
| | | * å
¬ä¼å·/æå¡å· |
| | | */ |
| | | @Deprecated |
| | | @JSONField(serialize = false) |
| | | private List<JSONObject> publicUsersList = new ArrayList<JSONObject>(); |
| | | /** |
| | | * ç¹æ®è´¦å· |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<JSONObject> specialUsersList = new ArrayList<JSONObject>(); |
| | | |
| | | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ |
| | | |
| | | /** |
| | | * synccheckåwebWxSynctæ·»å |
| | | * 弿¥æ¥åæ¶æ¯åå¨ |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<BaseMsg> msgList = new ArrayList<>(); |
| | | |
| | | /** |
| | | * 弿¥åéæ¶æ¯åå¨ |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private List<SendMsg> sendList = new ArrayList(); |
| | | |
| | | /******************************** |
| | | * ç¼ååæ®µ,ç¨äºå¿«éæ¥æ¾ |
| | | ********************************/ |
| | | |
| | | /** |
| | | * 微信æµç§°ä¸è½è¶
è¿16ä½ï¼èIDæ¯è¾é¿ï¼å¹²èç¨ä¸ä¸ªMap |
| | | * 群IDææµç§°,ç¾¤ä¿¡æ¯ |
| | | * 注æ:åå¨ç¸åæµç§°ä¼åè
è¦çåè
|
| | | * <p> |
| | | * WebWxBatchGetContactä¹åå¯ä»¥éè¿ |
| | | * .getJSONArray("MemberList")è·å群æåå表 |
| | | */ |
| | | @JSONField(serialize = false) |
| | | private Map<String, JSONObject> groupInfoMap = new HashMap<>(1024); |
| | | |
| | | /** |
| | | * 微信æµç§°ä¸è½è¶
è¿16ä½ï¼èIDæ¯è¾é¿ï¼å¹²èç¨ä¸ä¸ªMap |
| | | * ç©å®¶IDææµç§°ï¼ç©å®¶ä¿¡æ¯ |
| | | * 注æ:åå¨ç¸åæµç§°ä¼åè
è¦çåè
|
| | | */ |
| | | @JSONField(serialize = false) |
| | | private Map<String, JSONObject> userInfoMap = new HashMap<>(1024); |
| | | |
| | | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ |
| | | |
| | | /** |
| | | * 请æ±åæ° |
| | | */ |
| | | @JSONField(serialize = false) |
| | | public Map<String, Object> getParamMap() { |
| | | return new HashMap<String, Object>(1) { |
| | | /** |
| | | * |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | { |
| | | Map<String, String> map = new HashMap<>(16); |
| | | for (BaseParaEnum baseRequest : BaseParaEnum.values()) { |
| | | map.put(baseRequest.para(), getLoginInfo().get(baseRequest.value()).toString()); |
| | | } |
| | | put("BaseRequest", map); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public String getUniqueKey() { |
| | | return uniqueKey; |
| | | } |
| | | |
| | | public void setUniqueKey(String uniqueKey) { |
| | | this.uniqueKey = uniqueKey; |
| | | } |
| | | |
| | | public boolean isAlive() { |
| | | return alive; |
| | | } |
| | | |
| | | public void setAlive(boolean alive) { |
| | | this.alive = alive; |
| | | if (!alive) { |
| | | this.isFinishInit = false; |
| | | } |
| | | } |
| | | |
| | | public String getIndexUrl() { |
| | | return indexUrl; |
| | | } |
| | | |
| | | public void setIndexUrl(String indexUrl) { |
| | | this.indexUrl = indexUrl; |
| | | } |
| | | |
| | | 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 String getUuid() { |
| | | return uuid; |
| | | } |
| | | |
| | | public void setUuid(String uuid) { |
| | | this.uuid = uuid; |
| | | } |
| | | |
| | | public Map<String, Object> getLoginInfo() { |
| | | return loginInfo; |
| | | } |
| | | |
| | | public void setLoginInfo(Map<String, Object> loginInfo) { |
| | | this.loginInfo = loginInfo; |
| | | } |
| | | |
| | | public JSONObject getUserSelf() { |
| | | return userSelf; |
| | | } |
| | | |
| | | public void setUserSelf(JSONObject userSelf) { |
| | | this.userSelf = userSelf; |
| | | } |
| | | |
| | | public long getLastNormalRetcodeTime() { |
| | | return lastNormalRetcodeTime; |
| | | } |
| | | |
| | | public void setLastNormalRetcodeTime(long lastNormalRetcodeTime) { |
| | | this.lastNormalRetcodeTime = lastNormalRetcodeTime; |
| | | } |
| | | |
| | | public int getReceivingRetryCount() { |
| | | return receivingRetryCount; |
| | | } |
| | | |
| | | public void setReceivingRetryCount(int receivingRetryCount) { |
| | | this.receivingRetryCount = receivingRetryCount; |
| | | } |
| | | |
| | | public int getMemberCount() { |
| | | return getContactList().size() + getGroupList().size() + getPublicUsersList().size() + getSpecialUsersList().size(); |
| | | } |
| | | |
| | | public List<JSONObject> getMemberList() { |
| | | List<JSONObject> memberList = new ArrayList<>(); |
| | | memberList.addAll(this.getContactList()); |
| | | memberList.addAll(this.getGroupList()); |
| | | memberList.addAll(this.getPublicUsersList()); |
| | | memberList.addAll(this.getSpecialUsersList()); |
| | | return memberList; |
| | | } |
| | | |
| | | 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 List<BaseMsg> getMsgList() { |
| | | return msgList; |
| | | } |
| | | |
| | | public void setMsgList(List<BaseMsg> msgList) { |
| | | this.msgList = msgList; |
| | | } |
| | | |
| | | public Map<String, JSONObject> getGroupInfoMap() { |
| | | return groupInfoMap; |
| | | } |
| | | |
| | | public void setGroupInfoMap(Map<String, JSONObject> groupInfoMap) { |
| | | this.groupInfoMap = groupInfoMap; |
| | | } |
| | | |
| | | public Map<String, JSONObject> getUserInfoMap() { |
| | | return userInfoMap; |
| | | } |
| | | |
| | | public void setUserInfoMap(Map<String, JSONObject> userInfoMap) { |
| | | this.userInfoMap = userInfoMap; |
| | | } |
| | | |
| | | public boolean isFinishInit() { |
| | | return isFinishInit; |
| | | } |
| | | |
| | | public void setFinishInit(boolean finishInit) { |
| | | isFinishInit = finishInit; |
| | | } |
| | | |
| | | public ThreadGroup getThreadGroup() { |
| | | return threadGroup; |
| | | } |
| | | |
| | | public void setThreadGroup(ThreadGroup threadGroup) { |
| | | this.threadGroup = threadGroup; |
| | | } |
| | | |
| | | public List<SendMsg> getSendList() { |
| | | return sendList; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.core; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.http.impl.client.BasicCookieStore; |
| | | import org.apache.http.impl.cookie.BasicClientCookie; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.SendMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.client.HttpClientManage; |
| | | import org.ruoyi.common.wechat.itchat4j.controller.LoginController; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools; |
| | | |
| | | import java.io.*; |
| | | import java.util.Collection; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | |
| | | /** |
| | | * å¤å¼ç®¡ç |
| | | * |
| | | * @author WesleyOne |
| | | * @create 2018/12/13 |
| | | */ |
| | | public class CoreManage implements LogInterface { |
| | | |
| | | static int MAX_CORE_NUM = 50; |
| | | private static HashMap<String, Core> coreMap = new HashMap<>(MAX_CORE_NUM / 3 * 4 + 1); |
| | | |
| | | // æ¯å¦çå è½½ |
| | | public static boolean USE_HOT_RELOAD = false; |
| | | public static String HOT_RELOAD_DIR = "/Users/wesley/output/hotreload/wxwobot.hot"; |
| | | |
| | | public static Core getInstance(String uniqueKey) { |
| | | if (StringUtils.isEmpty(uniqueKey)) { |
| | | return null; |
| | | } |
| | | Core core; |
| | | if (!coreMap.containsKey(uniqueKey) || coreMap.get(uniqueKey) == null) { |
| | | core = Core.getInstance(uniqueKey); |
| | | coreMap.put(uniqueKey, core); |
| | | } |
| | | return coreMap.get(uniqueKey); |
| | | } |
| | | |
| | | /** |
| | | * ç§»é¤ |
| | | * |
| | | * @param uniqueKey |
| | | */ |
| | | public static void remove(String uniqueKey) { |
| | | if (coreMap.containsKey(uniqueKey)) { |
| | | coreMap.remove(uniqueKey); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¯å¦å¨çº¿ |
| | | * |
| | | * @param uniqueKey |
| | | * @return |
| | | */ |
| | | public static boolean isActive(String uniqueKey) { |
| | | if (StringUtils.isNotEmpty(uniqueKey) && coreMap.containsKey(uniqueKey) && coreMap.get(uniqueKey).isAlive()) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * æä¹
å |
| | | */ |
| | | public static void persistence() { |
| | | |
| | | // æ ¼å¼åæ°æ® |
| | | Collection<Core> valueCollection = coreMap.values(); |
| | | int size = valueCollection.size(); |
| | | // æ²¡ææ°æ®ä¸æä½ |
| | | if (size <= 0) { |
| | | return; |
| | | } |
| | | LOG.info("ç»å½æ°æ®æä¹
åä¸"); |
| | | Iterator<Core> iterator = valueCollection.iterator(); |
| | | JSONArray jsonArray = new JSONArray(); |
| | | while (iterator.hasNext()) { |
| | | Core core = iterator.next(); |
| | | if (core.isAlive()) { |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("core", core); |
| | | jsonObject.put("cookies", core.getMyHttpClient().getCookieStore().getCookies()); |
| | | jsonArray.add(jsonObject); |
| | | } |
| | | } |
| | | |
| | | try { |
| | | File file = new File(HOT_RELOAD_DIR); |
| | | if (!file.exists()) { |
| | | file.createNewFile(); |
| | | } |
| | | // æ¯æ¬¡è¦ç |
| | | FileWriter fileWritter = new FileWriter(HOT_RELOAD_DIR, false); |
| | | fileWritter.write(jsonArray.toJSONString()); |
| | | fileWritter.close(); |
| | | |
| | | LOG.info("ç»å½æ°æ®æä¹
å宿"); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¯å¨å è½½æä¹
åæä»¶ |
| | | */ |
| | | public static void reload() { |
| | | if (USE_HOT_RELOAD) { |
| | | File file = new File(HOT_RELOAD_DIR); |
| | | if (file.exists()) { |
| | | LOG.info("ç»å½æ°æ®çå è½½ä¸"); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | try { |
| | | FileReader fr = new FileReader(HOT_RELOAD_DIR); |
| | | BufferedReader bf = new BufferedReader(fr); |
| | | String str; |
| | | // æè¡è¯»åå符串 |
| | | while ((str = bf.readLine()) != null) { |
| | | stringBuilder.append(str); |
| | | } |
| | | bf.close(); |
| | | fr.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | return; |
| | | } |
| | | String result = stringBuilder.toString(); |
| | | if (StringUtils.isEmpty(result)) { |
| | | return; |
| | | } |
| | | |
| | | JSONArray jsonArray = JSONArray.parseArray(result); |
| | | int size = jsonArray.size(); |
| | | if (size > 0) { |
| | | // å°è£
æçº¿ç¨æä½ |
| | | for (int i = 0; i < size; i++) { |
| | | JSONObject jsonObject = jsonArray.getJSONObject(i); |
| | | ReloadThread reloadThread = new ReloadThread(jsonObject); |
| | | Thread thread = new Thread(reloadThread); |
| | | thread.start(); |
| | | } |
| | | } |
| | | |
| | | LOG.info("ç»å½æ°æ®çå è½½å®æ"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private static class ReloadThread implements Runnable { |
| | | |
| | | private JSONObject reloadObject; |
| | | |
| | | public ReloadThread(JSONObject object) { |
| | | this.reloadObject = object; |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | Core core = null; |
| | | try { |
| | | /** |
| | | * åå§åCore, |
| | | * 1.è·åç»å
¥çç¶æä¿¡æ¯å¹¶è£
å
¥CoreManage |
| | | * 2.æå»ºThreadGroup |
| | | * 3.è·åCookieså¹¶è£
å
¥HttpClientManage |
| | | * 4.è·åä¿¡æ¯åå¯å¨çº¿ç¨ |
| | | */ |
| | | JSONObject jsonObject = this.reloadObject; |
| | | core = jsonObject.getObject("core", Core.class); |
| | | String uniqueKey = core.getUniqueKey(); |
| | | if (core.isAlive()) { |
| | | core.setThreadGroup(new ThreadGroup(uniqueKey)); |
| | | coreMap.put(uniqueKey, core); |
| | | |
| | | JSONArray cookiesJsonArray = jsonObject.getJSONArray("cookies"); |
| | | int arraySize = cookiesJsonArray.size(); |
| | | if (arraySize <= 0) { |
| | | return; |
| | | } |
| | | |
| | | // è£
è½½åcookieä¿¡æ¯,jsonè§£æcookieå¼å¸¸ï¼å¹²èæå¨å°è£
|
| | | BasicCookieStore cookieStore = new BasicCookieStore(); |
| | | for (int ci = 0; ci < arraySize; ci++) { |
| | | JSONObject cookieJson = cookiesJsonArray.getJSONObject(ci); |
| | | String name = cookieJson.getString("name"); |
| | | String value = cookieJson.getString("value"); |
| | | String domain = cookieJson.getString("domain"); |
| | | String path = cookieJson.getString("path"); |
| | | Boolean persistent = cookieJson.getBoolean("persistent"); |
| | | Boolean secure = cookieJson.getBoolean("secure"); |
| | | Long expiryDate = cookieJson.getLong("expiryDate"); |
| | | Integer version = cookieJson.getInteger("version"); |
| | | |
| | | BasicClientCookie cookie = new BasicClientCookie(name, value); |
| | | cookie.setDomain(domain); |
| | | cookie.setPath(path); |
| | | cookie.setSecure(secure); |
| | | cookie.setExpiryDate(new Date(expiryDate)); |
| | | cookie.setVersion(version); |
| | | |
| | | cookieStore.addCookie(cookie); |
| | | } |
| | | // å¿
é¡»å¨æå»ºclientæ¶å°±æ¾å
¥cookie |
| | | HttpClientManage.getInstance(uniqueKey, cookieStore); |
| | | //è£
è½½coreä¿¡æ¯åå¯å¨çº¿ç¨ |
| | | LoginController login = new LoginController(uniqueKey); |
| | | if (!login.login_3()) { |
| | | // å 载失败éåº |
| | | core.setAlive(false); |
| | | return; |
| | | } |
| | | LOG.info("çç»å½æå: {}", uniqueKey); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (core != null) { |
| | | core.setAlive(false); |
| | | core = null; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * åæ¾æ°ç群,æµç§°emojiå¤ç |
| | | * |
| | | * @param core |
| | | * @param jsonObject |
| | | */ |
| | | public static void addNewGroup(Core core, JSONObject jsonObject) { |
| | | String userName = jsonObject.getString("UserName"); |
| | | |
| | | CommonTools.emojiFormatter2(jsonObject, "NickName"); |
| | | // å é¤éå¤ç |
| | | core.getGroupList().removeIf(group -> userName.equals(group.getString("UserName"))); |
| | | |
| | | core.getGroupList().add(jsonObject); |
| | | core.getGroupInfoMap().put(jsonObject.getString("NickName"), jsonObject); |
| | | core.getGroupInfoMap().put(userName, jsonObject); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * åæ¾æ°çè系人,æµç§°emojiå¤ç |
| | | * |
| | | * @param core |
| | | * @param jsonObject |
| | | */ |
| | | public static void addNewContact(Core core, JSONObject jsonObject) { |
| | | String userName = jsonObject.getString("UserName"); |
| | | |
| | | CommonTools.emojiFormatter2(jsonObject, "NickName"); |
| | | // å é¤éå¤ç |
| | | core.getContactList().removeIf(contact -> userName.equals(contact.getString("UserName"))); |
| | | |
| | | core.getContactList().add(jsonObject); |
| | | core.getUserInfoMap().put(jsonObject.getString("NickName"), jsonObject); |
| | | core.getUserInfoMap().put(userName, jsonObject); |
| | | } |
| | | |
| | | /** |
| | | * æ¶æ¯ç»ä¸å å°éåéå¤ç1 |
| | | * ç¨äºå·²ç¥UserName |
| | | * |
| | | * @param uniqueKey |
| | | * @param toUserName |
| | | * @param data |
| | | * @param type |
| | | */ |
| | | public static void addSendMsg4UserName(String uniqueKey, String toUserName, String data, SendMsgType type) { |
| | | if (StringUtils.isEmpty(uniqueKey) || StringUtils.isEmpty(toUserName) || StringUtils.isEmpty(data) || type == null) { |
| | | LOG.error("æ¶æ¯åæ°ä¸å®æ´ uk:{} un: {} data: {} ", uniqueKey, toUserName, data); |
| | | return; |
| | | } |
| | | |
| | | SendMsg sendMsg = new SendMsg(); |
| | | sendMsg.setUserName(toUserName); |
| | | sendMsg.setMessage(data); |
| | | sendMsg.setMsgType(type); |
| | | boolean isGroup = true; |
| | | if (toUserName != null && !toUserName.startsWith("@@")) { |
| | | isGroup = false; |
| | | } |
| | | sendMsg.setGroup(isGroup); |
| | | CoreManage.getInstance(uniqueKey).getSendList().add(sendMsg); |
| | | } |
| | | |
| | | /** |
| | | * æ¶æ¯ç»ä¸å å°éåéå¤ç2 |
| | | * ç¨äºå·²ç¥NickName |
| | | * |
| | | * @param uniqueKey |
| | | * @param toNickName |
| | | * @param data |
| | | * @param type |
| | | * @param isGroup |
| | | */ |
| | | public static void addSendMsg4NickName(String uniqueKey, String toNickName, String data, SendMsgType type, Boolean isGroup) { |
| | | |
| | | if (StringUtils.isEmpty(uniqueKey) || StringUtils.isEmpty(toNickName) || StringUtils.isEmpty(data) || type == null) { |
| | | LOG.error("æ¶æ¯åæ°ä¸å®æ´ uk:{} nn: {} data: {} ", uniqueKey, toNickName, data); |
| | | return; |
| | | } |
| | | |
| | | SendMsg sendMsg = new SendMsg(); |
| | | sendMsg.setNickName(toNickName); |
| | | sendMsg.setMessage(data); |
| | | sendMsg.setMsgType(type); |
| | | sendMsg.setGroup(isGroup); |
| | | CoreManage.getInstance(uniqueKey).getSendList().add(sendMsg); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.core; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.api.MessageTools; |
| | | import org.ruoyi.common.wechat.itchat4j.api.WechatTools; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.SendMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.face.IMsgHandlerFace; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.MoreConfig; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgCodeEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgTypeEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æ¶æ¯å¤çä¸å¿ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @author WesleyOne ä¿®æ¹ |
| | | * @version 1.0 |
| | | * @date å建æ¶é´ï¼2017å¹´5æ14æ¥ ä¸å12:47:50 |
| | | */ |
| | | public class MsgCenter implements LogInterface { |
| | | |
| | | /** |
| | | * æ¥æ¶æ¶æ¯ï¼æ¾å
¥éå |
| | | * |
| | | * @param msgList |
| | | * @return |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ23æ¥ ä¸å2:30:48 |
| | | */ |
| | | public static JSONArray produceMsg(JSONArray msgList, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | JSONArray result = new JSONArray(); |
| | | // ç¨äºæåæªç¥ç¾¤ID,æåè°ç¨webwxbatchgetcontactè·å |
| | | List<String> unknowGroup = new ArrayList<>(); |
| | | |
| | | for (int i = 0; i < msgList.size(); i++) { |
| | | JSONObject m = msgList.getJSONObject(i); |
| | | // æ¯å¦æ¯ç¾¤æ¶æ¯ |
| | | boolean isGroupMsg = false; |
| | | boolean isAtMe = false; |
| | | if (m.getString("FromUserName").contains("@@") || m.getString("ToUserName").contains("@@")) { |
| | | // ç¾¤èæ¶æ¯ |
| | | isGroupMsg = true; |
| | | if (m.getString("FromUserName").contains("@@") |
| | | && !core.getGroupInfoMap().containsKey(m.getString("FromUserName"))) { |
| | | unknowGroup.add(m.getString("FromUserName")); |
| | | } else if (m.getString("ToUserName").contains("@@") |
| | | && !core.getGroupInfoMap().containsKey(m.getString("ToUserName"))) { |
| | | unknowGroup.add(m.getString("ToUserName")); |
| | | } |
| | | // ç¾¤æ¶æ¯ä¸æ®éæ¶æ¯ä¸åçæ¯å¨å
¶æ¶æ¯ä½ï¼Contentï¼ä¸ä¼å
å«åéè
idå":<br/>"æ¶æ¯ï¼è¿ééè¦å¤çä¸ä¸ï¼å»æå¤ä½ä¿¡æ¯ï¼åªä¿çæ¶æ¯å
容 |
| | | String splitCode = ":<br/>"; |
| | | if (m.getString("Content").contains(splitCode)) { |
| | | String source = m.getString("Content"); |
| | | String content = source.substring(source.indexOf(splitCode) + splitCode.length()); |
| | | String sendMemberId = source.substring(0, source.indexOf(splitCode)); |
| | | |
| | | m.put("Content", content); |
| | | m.put(MoreConfig.SEND_MEMBER_ID, sendMemberId); |
| | | |
| | | if (content.contains("@" + core.getNickName())) { |
| | | isAtMe = true; |
| | | } |
| | | } |
| | | |
| | | } |
| | | m.put("groupMsg", isGroupMsg); |
| | | m.put("atMe", isAtMe); |
| | | // 1.ææ¬æ¶æ¯ |
| | | if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_TEXT.getCode())) { |
| | | if (m.getString("Url").length() != 0) { |
| | | // 1.1å享ä½ç½® ä¸å¤ç |
| | | continue; |
| | | // String[] contents = m.getString("Content").split(":"); |
| | | // String data = "Map"; |
| | | // if (contents.length>0) { |
| | | // data = contents[0]+":"+m.getString("Url"); |
| | | // } |
| | | // m.put("Type", MsgTypeEnum.MAP.getType()); |
| | | // m.put("Text", data); |
| | | // LOG.warn("MAP_CONTENT: {},URL: {}",m.getString("Content"),m.getString("Url")); |
| | | /** |
| | | * MAP_CONTENT: 滨å
´å°åº(ä¸åº):/cgi-bin/mmwebwx-bin/webwxgetpubliclinkimg?url=xxx&msgid=7525662842661720095&pictype=location,URL: http://apis.map.qq.com/uri/v1/geocoder?coord=30.191660,120.200508 |
| | | */ |
| | | |
| | | } else { |
| | | // 1.2 æ®éææ¬ |
| | | m.put("Type", MsgTypeEnum.TEXT.getType()); |
| | | CommonTools.emojiFormatter2(m, "Content"); |
| | | m.put("Text", m.getString("Content")); |
| | | |
| | | } |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_IMAGE.getCode()) |
| | | || m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_EMOTICON.getCode())) { |
| | | // 2.å¾çæ¶æ¯ ä¸å¤ç |
| | | continue; |
| | | // m.put("Type", MsgTypeEnum.PIC.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VOICE.getCode())) { |
| | | // 3.è¯é³æ¶æ¯ ä¸å¤ç |
| | | continue; |
| | | // m.put("Type", MsgTypeEnum.VOICE.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VERIFYMSG.getCode())) { |
| | | // 4.好åç¡®è®¤æ¶æ¯ ä¸å¤ç |
| | | continue; |
| | | // MessageTools.addFriend(core, userName, 3, ticket); // 确认添å 好å |
| | | // m.put("Type", MsgTypeEnum.VERIFYMSG.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_SHARECARD.getCode())) { |
| | | // 5.å
±äº«åç ä¸å¤ç |
| | | // m.put("Type", MsgTypeEnum.NAMECARD.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VIDEO.getCode()) |
| | | || m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MICROVIDEO.getCode())) { |
| | | // 6.è§é¢ ä¸å¤ç |
| | | continue; |
| | | // m.put("Type", MsgTypeEnum.VIEDO.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MEDIA.getCode())) { |
| | | // 7.åäº«é¾æ¥ ä¸å¤ç |
| | | continue; |
| | | // m.put("Type", MsgTypeEnum.MEDIA.getType()); |
| | | } else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_STATUSNOTIFY.getCode())) { |
| | | // 微信åå§åæ¶æ¯ ç³»ç» |
| | | m.put("Type", MsgTypeEnum.SYS.getType()); |
| | | } 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())) { |
| | | // æ¤åæ¶æ¯ ç³»ç» ä¸å¤ç |
| | | continue; |
| | | // m.put("Type", MsgTypeEnum.SYS.getType()); |
| | | } else { |
| | | LOG.error("Useless msg: {} \n {}", m.getInteger("MsgType"), m.getString("Content")); |
| | | } |
| | | |
| | | /** |
| | | * æ¥å¿ |
| | | * æ¾ç¤ºæ¶å°çæ¶æ¯ |
| | | */ |
| | | String nickName; |
| | | String memberName = ""; |
| | | if (m.getBoolean("groupMsg")) { |
| | | nickName = WechatTools.getGroupNickNameByUserName(m.getString("FromUserName"), uniqueKey); |
| | | |
| | | if (m.getString(MoreConfig.SEND_MEMBER_ID) != null) { |
| | | // è·åæåæµç§° |
| | | memberName = WechatTools.getMemberNickName(m.getString("FromUserName"), uniqueKey, m.getString(MoreConfig.SEND_MEMBER_ID)); |
| | | m.put(MoreConfig.SEND_MEMBER_NICKNAMW, memberName); |
| | | } |
| | | } else { |
| | | nickName = WechatTools.getContactNickNameByUserName(m.getString("FromUserName"), uniqueKey); |
| | | } |
| | | m.put("fromNickName", nickName); |
| | | LOG.info("æ¶å°ã{}ã=>ã{}ãæ¶æ¯,æ¥èª: {} å
容:\n{} ", |
| | | MsgCodeEnum.fromCode(m.getInteger("MsgType")) == null ? "æªç¥ç±»å" + m.getInteger("MsgType") : MsgCodeEnum.fromCode(m.getInteger("MsgType")).getType(), |
| | | m.getString("Type"), |
| | | nickName + " : " + memberName, |
| | | StringUtils.isNotEmpty(m.getString("Content")) ? m.getString("Content") : ""); |
| | | result.add(m); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * å¾®ä¿¡æ¥æ¶æ¶æ¯å¤ç |
| | | * |
| | | * @param uniqueKey |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ14æ¥ ä¸å10:52:34 |
| | | */ |
| | | public static void handleMsg(String uniqueKey, IMsgHandlerFace msgHandler) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | while (true) { |
| | | if (!core.isAlive()) { |
| | | LOG.info("åæ¢æ¶æ¯å¤ç"); |
| | | break; |
| | | } |
| | | 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())) { |
| | | msgHandler.textMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.PIC.getType())) { |
| | | msgHandler.picMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.VOICE.getType())) { |
| | | msgHandler.voiceMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.VIEDO.getType())) { |
| | | msgHandler.videoMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.NAMECARD.getType())) { |
| | | msgHandler.nameCardMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.SYS.getType())) { |
| | | msgHandler.sysMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.VERIFYMSG.getType())) { |
| | | msgHandler.verifyAddFriendMsgHandle(msg); |
| | | } else if (msg.getType().equals(MsgTypeEnum.MEDIA.getType())) { |
| | | msgHandler.mediaMsgHandle(msg); |
| | | } else { |
| | | LOG.warn("ææªå¤çä¿¡æ¯ã{}ã", msg.getType()); |
| | | } |
| | | } catch (Exception e) { |
| | | LOG.error(e.getMessage(), e); |
| | | } |
| | | } |
| | | } |
| | | core.getMsgList().remove(0); |
| | | } |
| | | try { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | LOG.error("æ¶æ¯å¤ç䏿"); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç»ä¸åéæ¶æ¯ |
| | | * |
| | | * @param uniqueKey |
| | | */ |
| | | public static void sendMsg(String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | while (true) { |
| | | if (core == null || !core.isAlive()) { |
| | | LOG.info("åæ¢æ¶æ¯åé"); |
| | | break; |
| | | } |
| | | if (CollectionUtil.isNotEmpty(core.getSendList())) { |
| | | SendMsg sendMsg = core.getSendList().get(0); |
| | | try { |
| | | String userName = sendMsg.getUserName(); |
| | | String nickName = sendMsg.getNickName(); |
| | | String message = sendMsg.getMessage(); |
| | | boolean isGroup = sendMsg.isGroup(); |
| | | SendMsgType msgType = sendMsg.getMsgType(); |
| | | if (StringUtils.isNotEmpty(message) && msgType != null) { |
| | | if (StringUtils.isNotEmpty(userName)) { |
| | | MessageTools.send(userName, uniqueKey, message, msgType.toValue()); |
| | | } else if (StringUtils.isNotEmpty(nickName)) { |
| | | MessageTools.sendByNickName(nickName, uniqueKey, message, msgType.toValue(), isGroup); |
| | | } else { |
| | | LOG.error("æ æåéæ¶æ¯: {}", JSONObject.toJSONString(sendMsg)); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | LOG.error(e.getMessage(), e); |
| | | } |
| | | core.getSendList().remove(0); |
| | | } |
| | | try { |
| | | // æ§å¶åéé¢ç |
| | | Thread.sleep(2000); |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | LOG.error("æ¶æ¯åé䏿"); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.face; |
| | | |
| | | import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | |
| | | /** |
| | | * æ¶æ¯å¤çæ¥å£ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´4æ20æ¥ ä¸å12:13:49 |
| | | * @version 1.0 |
| | | * |
| | | * @author WesleyOne ä¿®æ¹ |
| | | */ |
| | | public interface IMsgHandlerFace { |
| | | |
| | | /** |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ20æ¥ ä¸å12:15:00 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void textMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤çå¾çæ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ21æ¥ ä¸å11:07:06 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void picMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤ç声鳿¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ22æ¥ ä¸å12:09:44 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void voiceMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤çå°è§é¢æ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ23æ¥ ä¸å12:19:50 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void videoMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤çåçæ¶æ¯ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ1æ¥ ä¸å12:50:50 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void nameCardMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤çç³»ç»æ¶æ¯ |
| | | * |
| | | * @author Relyn |
| | | * @date 2017å¹´6æ21æ¥17:43:51 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void sysMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤ç确认添å å¥½åæ¶æ¯ |
| | | * |
| | | * @date 2017å¹´6æ28æ¥ ä¸å10:15:30 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void verifyAddFriendMsgHandle(BaseMsg msg); |
| | | |
| | | /** |
| | | * å¤çæ¶å°çæä»¶æ¶æ¯ |
| | | * |
| | | * @date 2017å¹´7æ21æ¥ ä¸å11:59:14 |
| | | * @param msg |
| | | * @return |
| | | */ |
| | | void mediaMsgHandle(BaseMsg msg); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.service; |
| | | |
| | | |
| | | |
| | | /** |
| | | * ç»éæå¡æ¥å£ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´5æ13æ¥ ä¸å12:07:21 |
| | | * @version 1.0 |
| | | * |
| | | * @author WesleyOne ä¿®æ¹ |
| | | */ |
| | | 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 |
| | | * @return |
| | | */ |
| | | String getUuid(); |
| | | |
| | | /** |
| | | * è·åäºç»´ç å¾ç |
| | | * (ç´æ¥è·åå¾ç龿¥,ä¸ä¸è½½æä»¶) |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ13æ¥ ä¸å12:13:51 |
| | | * @param qrPath |
| | | * @return |
| | | */ |
| | | @Deprecated |
| | | 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(); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.service.impl; |
| | | |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.http.Consts; |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.cookie.Cookie; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.Member; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.WebWxInit; |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.core.MsgCenter; |
| | | import org.ruoyi.common.wechat.itchat4j.service.ILoginService; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.SleepUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.*; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.BaseParaEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.LoginParaEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.StatusNotifyParaEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.UUIDParaEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools; |
| | | import org.w3c.dom.Document; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.OutputStream; |
| | | import java.util.*; |
| | | import java.util.Map.Entry; |
| | | import java.util.regex.Matcher; |
| | | |
| | | /** |
| | | * ç»éæå¡å®ç°ç±» |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @author WesleyOne ä¿®æ¹ |
| | | * @version 1.0 |
| | | * @date å建æ¶é´ï¼2017å¹´5æ13æ¥ ä¸å12:09:35 |
| | | */ |
| | | public class LoginServiceImpl implements ILoginService, LogInterface { |
| | | private Core core; |
| | | private String uniqueKey; |
| | | |
| | | public LoginServiceImpl(String uniqueKey) { |
| | | this.uniqueKey = uniqueKey; |
| | | this.core = CoreManage.getInstance(uniqueKey); |
| | | } |
| | | |
| | | @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; |
| | | long startMillis = System.currentTimeMillis(); |
| | | boolean overTime = false; |
| | | |
| | | while (!isLogin && !overTime) { |
| | | // 鲿¢è¯·æ±é夿¶çé®é¢ |
| | | if (core.isAlive()) { |
| | | break; |
| | | } |
| | | |
| | | 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 = core.getMyHttpClient().doGet(URLEnum.LOGIN_URL.getUrl(), params, true, null); |
| | | |
| | | try { |
| | | String result = EntityUtils.toString(entity); |
| | | String status = checklogin(result); |
| | | if (ResultEnum.SUCCESS.getCode().equals(status)) { |
| | | // å¤çç»æ |
| | | if (processLoginInfo(result)) { |
| | | isLogin = true; |
| | | core.setAlive(isLogin); |
| | | break; |
| | | } else { |
| | | isLogin = false; |
| | | core.setAlive(isLogin); |
| | | // ç»å
¥å¼å¸¸ç´æ¥éåºï¼é²æ¢æ»å¾ªç¯ |
| | | break; |
| | | } |
| | | } |
| | | if (ResultEnum.WAIT_CONFIRM.getCode().equals(status)) { |
| | | LOG.info("请ç¹å»å¾®ä¿¡ç¡®è®¤æé®ï¼è¿è¡ç»é"); |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | LOG.error("微信ç»éå¼å¸¸ï¼", e); |
| | | break; |
| | | } |
| | | // 3åéè¶
æ¶ä¸åè¯·æ± |
| | | SleepUtils.sleep(1000); |
| | | overTime = (millis - startMillis) > 1000 * 180; |
| | | } |
| | | 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.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 = core.getMyHttpClient().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); |
| | | LOG.info(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(); |
| | | } |
| | | |
| | | @Deprecated |
| | | @Override |
| | | public boolean getQR(String qrPath) { |
| | | return getQR(qrPath, false); |
| | | } |
| | | |
| | | @Deprecated |
| | | public boolean getQR(String qrPath, boolean open) { |
| | | qrPath = qrPath + File.separator + "QR.jpg"; |
| | | String qrUrl = URLEnum.QRCODE_URL.getUrl() + core.getUuid(); |
| | | HttpEntity entity = core.getMyHttpClient().doGet(qrUrl, null, true, null); |
| | | try { |
| | | // æä»¶å·²åå¨å
å é¤ |
| | | File file = new File(qrPath); |
| | | if (file.exists() && file.isFile()) { |
| | | file.delete(); |
| | | } |
| | | // åå
¥äºç»´ç |
| | | OutputStream out = new FileOutputStream(qrPath); |
| | | byte[] bytes = EntityUtils.toByteArray(entity); |
| | | out.write(bytes); |
| | | out.flush(); |
| | | out.close(); |
| | | if (open) { |
| | | try { |
| | | CommonTools.printQr(qrPath); // æå¼ç»éäºç»´ç å¾ç |
| | | } catch (Exception e) { |
| | | LOG.info(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | LOG.error(e.getMessage(), e); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * è·åèªèº«ç»å½ä¿¡æ¯ç¼å |
| | | * |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean webWxInit() { |
| | | core.setAlive(true); |
| | | core.setLastNormalRetcodeTime(System.currentTimeMillis()); |
| | | |
| | | try { |
| | | // ç»è£
请æ±URLååæ° |
| | | String url = String.format(URLEnum.INIT_URL.getUrl(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()), |
| | | System.currentTimeMillis() / 3158L, |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey())); |
| | | Map<String, Object> paramMap = core.getParamMap(); |
| | | |
| | | // 请æ±åå§åæ¥å£ |
| | | HttpEntity entity = core.getMyHttpClient().doPost(url, JSONObject.toJSONString(paramMap), getPersistentCookieMap()); |
| | | String result = EntityUtils.toString(entity, Consts.UTF_8); |
| | | |
| | | /** |
| | | * ç¸å
³è¿åä¿¡æ¯ï¼æ¬é¡¹ç®æªåå°è£
|
| | | * @see WebWxInit |
| | | */ |
| | | 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)); |
| | | core.setUserName(user.getString("UserName")); |
| | | core.setNickName(user.getString("NickName")); |
| | | core.setUserSelf(obj.getJSONObject("User")); |
| | | |
| | | /** |
| | | * TIP: |
| | | * ContactListæ¤å¤åªæ¯é¨åï¼ä¸åå¤çï¼webwxgetcontactæ¥å£ç»ä¸å¤ç |
| | | * MPSubscribeMsgList å
¬ä¼å·æå¡å·ä¹ä¸å¤ç |
| | | */ |
| | | } catch (Exception e) { |
| | | LOG.error("çç»å½åºç°è¯¥å¼å¸¸è¯·å¿½ç¥" + e.getMessage(), e); |
| | | core.setAlive(false); |
| | | 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 = core.getMyHttpClient().doPost(url, paramStr); |
| | | // String result = EntityUtils.toString(entity, Consts.UTF_8); |
| | | // LOG.info(result); |
| | | } catch (Exception e) { |
| | | LOG.error("å¾®ä¿¡ç¶æéç¥æ¥å£å¤±è´¥ï¼", e); |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void startReceiving() { |
| | | core.setAlive(true); |
| | | Thread thread = new Thread(core.getThreadGroup(), new Runnable() { |
| | | int retryCount = 0; |
| | | |
| | | @Override |
| | | public void run() { |
| | | while (core.isAlive()) { |
| | | try { |
| | | long startTime = System.currentTimeMillis(); |
| | | Map<String, String> resultMap = syncCheck(); |
| | | LOG.info(JSONObject.toJSONString(resultMap)); |
| | | String retcode = resultMap.get("retcode"); |
| | | String selector = resultMap.get("selector"); |
| | | RetCodeEnum retCodeEnum = RetCodeEnum.fromCode(retcode); |
| | | if (retCodeEnum != null) { |
| | | LOG.info(retCodeEnum.getType()); |
| | | if (retcode.equals(RetCodeEnum.UNKOWN.getCode())) { |
| | | // 鲿¢é¢ç¹è¯·æ± |
| | | Thread.sleep(1000); |
| | | continue; |
| | | } else if (retcode.equals(RetCodeEnum.SUCCESS.getCode())) { |
| | | // ä¿®æ¹æåæ¶å°æ£å¸¸æ¥ææ¶é´ |
| | | core.setLastNormalRetcodeTime(System.currentTimeMillis()); |
| | | SelectorEnum selectorEnum = SelectorEnum.fromCode(selector); |
| | | if (selectorEnum != null) { |
| | | if (selector.equals(SelectorEnum.NORMAL.getCode())) { |
| | | continue; |
| | | } else if (selector.equals(SelectorEnum.NEW_MSG.getCode())) { |
| | | // ææ°æ¶æ¯ |
| | | // processWebwxSync(); |
| | | } else if (selector.equals(SelectorEnum.ENTER_OR_LEAVE_CHAT.getCode())) { |
| | | // processWebwxSync(); |
| | | } else if (selector.equals(SelectorEnum.MOD_CONTACT.getCode())) { |
| | | // processWebwxSync(); |
| | | } else if (selector.equals(SelectorEnum.SELECTOR_3.getCode())) { |
| | | // processWebwxSync(); |
| | | // continue; |
| | | } else if (selector.equals(SelectorEnum.ADD_OR_DEL_CONTACT.getCode())) { |
| | | // processWebwxSync(); |
| | | } else { |
| | | LOG.error("UNKNOW SELECTOR CODE {}", selector); |
| | | } |
| | | } else { |
| | | // 鲿¢æ°ç±»åä¸å¤çå 积 |
| | | // processWebwxSync(); |
| | | } |
| | | } else if (retcode.equals(RetCodeEnum.NOT_LOGIN_CHECK.getCode()) || |
| | | retcode.equals(RetCodeEnum.TICKET_ERROR.getCode()) || |
| | | retcode.equals(RetCodeEnum.PARAM_ERROR.getCode()) || |
| | | retcode.equals(RetCodeEnum.NOT_LOGIN_WARN.getCode()) || |
| | | retcode.equals(RetCodeEnum.COOKIE_INVALID_ERROR.getCode()) || |
| | | retcode.equals(RetCodeEnum.LOGIN_ENV_ERROR.getCode())) { |
| | | // ç¶æå¼å¸¸ç´æ¥éåº |
| | | core.setAlive(false); |
| | | break; |
| | | } else { |
| | | // 鲿¢é¢ç¹è¯·æ± |
| | | Thread.sleep(1000); |
| | | break; |
| | | } |
| | | } else { |
| | | LOG.error("ç¹æ®retcodeï¼ {}", retcode); |
| | | } |
| | | // ç»ç»å°è¯è·åæ°æ¶æ¯ |
| | | processWebwxSync(); |
| | | if (System.currentTimeMillis() - startTime < 1000 * 1) { |
| | | Thread.sleep(1000); |
| | | } |
| | | } catch (InterruptedException e0) { |
| | | LOG.error("线ç¨ä¸æ"); |
| | | core.setAlive(false); |
| | | break; |
| | | } catch (Exception e) { |
| | | LOG.error(e.getMessage()); |
| | | retryCount += 1; |
| | | if (core.getReceivingRetryCount() < retryCount) { |
| | | core.setAlive(false); |
| | | } else { |
| | | try { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException e1) { |
| | | LOG.error(e.getMessage()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | }, "REC-" + uniqueKey); |
| | | thread.start(); |
| | | } |
| | | |
| | | |
| | | private void processWebwxSync() { |
| | | JSONObject msgObj = webWxSync(); |
| | | if (msgObj != null) { |
| | | Integer addMsgCount = msgObj.getInteger("AddMsgCount"); |
| | | Integer ModMsgCount = msgObj.getInteger("ModContactCount"); |
| | | Integer DelContactCount = msgObj.getInteger("DelContactCount"); |
| | | Integer ModChatRoomMemberCount = msgObj.getInteger("ModChatRoomMemberCount"); |
| | | |
| | | |
| | | if (addMsgCount > 0 || ModMsgCount > 0 || DelContactCount > 0 || ModChatRoomMemberCount > 0) { |
| | | LOG.info("æ¥æ¶åæ:{}", msgObj.toJSONString()); |
| | | } |
| | | |
| | | // ç¨äºéç¥è·å详ç»è¯¦ç» |
| | | List<String> modUserName = new ArrayList<>(); |
| | | |
| | | // å¤çæ°æ¶æ¯ |
| | | try { |
| | | |
| | | if (addMsgCount > 0) { |
| | | JSONArray msgList = msgObj.getJSONArray("AddMsgList"); |
| | | msgList = MsgCenter.produceMsg(msgList, uniqueKey); |
| | | for (int j = 0; j < msgList.size(); j++) { |
| | | BaseMsg baseMsg = JSON.toJavaObject(msgList.getJSONObject(j), |
| | | BaseMsg.class); |
| | | // TODO æ¥å¿ |
| | | LOG.info("å¤çå对象:{}", JSON.toJSONString(baseMsg)); |
| | | core.getMsgList().add(baseMsg); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | // å¤çä¿®æ¹è系人æç¾¤æå |
| | | try { |
| | | if (ModMsgCount > 0) { |
| | | JSONArray list = msgObj.getJSONArray("ModContactList"); |
| | | int size = list.size(); |
| | | for (int j = 0; j < size; j++) { |
| | | String userName = list.getJSONObject(j).getString("UserName"); |
| | | if (userName.startsWith("@@")) { |
| | | CoreManage.addNewGroup(core, list.getJSONObject(j)); |
| | | } else if (userName.startsWith("@")) { |
| | | CoreManage.addNewContact(core, list.getJSONObject(j)); |
| | | } |
| | | modUserName.add(userName); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | /** |
| | | * 没æè·åè¿æ°æ®ï¼ä¸ç¥éå¹²å¥ç¨ |
| | | * DelContactCount: 0 |
| | | * DelContactList: [] |
| | | * ModChatRoomMemberCount: 0 |
| | | * ModChatRoomMemberList: [] |
| | | */ |
| | | |
| | | // è·å详ç»ä¿¡æ¯ |
| | | WebWxBatchGetContact(modUserName); |
| | | |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void webWxGetContact() { |
| | | String url = String.format(URLEnum.WEB_WX_GET_CONTACT.getUrl(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey())); |
| | | JSONArray member = new JSONArray(); |
| | | try { |
| | | |
| | | // 循ç¯è·åseqç´å°ä¸º0ï¼å³è·åå
¨é¨å¥½åå表 ==0ï¼å¥½åè·å宿¯ >0ï¼å¥½åæªè·å宿¯ï¼æ¤æ¶seq为已è·åçåèæ° |
| | | Long seq = 0L; |
| | | do { |
| | | // 设置seqä¼ å |
| | | List<BasicNameValuePair> params = new ArrayList<>(); |
| | | params.add(new BasicNameValuePair("r", String.valueOf(System.currentTimeMillis()))); |
| | | params.add(new BasicNameValuePair("seq", String.valueOf(seq))); |
| | | params.add(new BasicNameValuePair("skey", core.getLoginInfo().get(BaseParaEnum.Skey.value()).toString())); |
| | | HttpEntity entity = core.getMyHttpClient().doGet(url, params, false, getPersistentCookieMap()); |
| | | |
| | | String result = EntityUtils.toString(entity, Consts.UTF_8); |
| | | JSONObject fullFriendsJsonList = JSON.parseObject(result); |
| | | |
| | | if (fullFriendsJsonList.get("Seq") != null) { |
| | | seq = fullFriendsJsonList.getLong("Seq"); |
| | | } |
| | | |
| | | // ç´¯å 好åå表 |
| | | member.addAll(fullFriendsJsonList.getJSONArray(StorageLoginInfoEnum.MemberList.getKey())); |
| | | } while (seq > 0); |
| | | Iterator<?> iterator = member.iterator(); |
| | | while (iterator.hasNext()) { |
| | | /** |
| | | * @see Member |
| | | */ |
| | | JSONObject o = (JSONObject) iterator.next(); |
| | | |
| | | String userName = o.getString("UserName"); |
| | | |
| | | if (StringUtils.isEmpty(userName)) { |
| | | LOG.error("{} 好åå表åå¨UserName空", core.getUniqueKey()); |
| | | continue; |
| | | } |
| | | /** |
| | | * èªå·±ä¿¡æ¯ä¸æ·»å |
| | | */ |
| | | if (userName.equals(core.getUserName())) { |
| | | continue; |
| | | } |
| | | |
| | | /** |
| | | * å¼å¤´@@ => 群è |
| | | * å¼å¤´@ => VerifyFlag -> == 0 好å |
| | | * -> != 0 å
¬ä¼å·ãæå¡å· |
| | | * ä¸å«@å¼å¤´ï¼å
¶ä»ï¼ => ç¹æ®è´¦å· |
| | | */ |
| | | |
| | | if (userName.startsWith("@@")) { |
| | | // 群è |
| | | CoreManage.addNewGroup(core, o); |
| | | |
| | | } else if (userName.startsWith("@")) { |
| | | Integer verifyFlag = o.getInteger("VerifyFlag"); |
| | | if (verifyFlag != null && verifyFlag == 0) { |
| | | // 好å |
| | | CoreManage.addNewContact(core, o); |
| | | } else { |
| | | // å
¬ä¼å· |
| | | core.getPublicUsersList().add(o); |
| | | } |
| | | } else { |
| | | // ç¹æ®è´¦å· |
| | | core.getSpecialUsersList().add(o); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | LOG.error(e.getMessage(), e); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | /** |
| | | * è·å群å好å详ç»ä¿¡æ¯ |
| | | * 馿¬¡å è½½ç¨ |
| | | */ |
| | | @Override |
| | | public void WebWxBatchGetContact() { |
| | | |
| | | Map<String, Object> paramMap = core.getParamMap(); |
| | | // å¤ç群æåä¿¡æ¯ |
| | | int size = core.getGroupList().size(); |
| | | List<Map<String, String>> list = new ArrayList<>(); |
| | | for (int i = 0; i < size; i++) { |
| | | HashMap<String, String> map = new HashMap<>(4); |
| | | map.put("UserName", core.getGroupList().get(i).getString("UserName")); |
| | | map.put("EncryChatRoomId", ""); |
| | | list.add(map); |
| | | } |
| | | // å¤çç©å®¶ |
| | | int sizeUser = core.getContactList().size(); |
| | | for (int i = 0; i < sizeUser; i++) { |
| | | HashMap<String, String> map = new HashMap<>(4); |
| | | map.put("UserName", core.getContactList().get(i).getString("UserName")); |
| | | map.put("EncryChatRoomId", ""); |
| | | list.add(map); |
| | | } |
| | | |
| | | WebWxBatchGetContactMain(paramMap, list); |
| | | } |
| | | |
| | | /** |
| | | * è·å群å好å详ç»ä¿¡æ¯ |
| | | * è¿ç¨ä¸é¶æ£æ¥è¯¢ |
| | | */ |
| | | public void WebWxBatchGetContact(List<String> userNameList) { |
| | | |
| | | if (CollectionUtil.isEmpty(userNameList)) { |
| | | return; |
| | | } |
| | | |
| | | String url = String.format(URLEnum.WEB_WX_BATCH_GET_CONTACT.getUrl(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()), System.currentTimeMillis(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey())); |
| | | Map<String, Object> paramMap = core.getParamMap(); |
| | | // 为äºè·å群æåä¿¡æ¯ |
| | | List<Map<String, String>> list = new ArrayList<>(); |
| | | int size = userNameList.size(); |
| | | for (int i = 0; i < size; i++) { |
| | | HashMap<String, String> map = new HashMap<>(4); |
| | | map.put("UserName", userNameList.get(i)); |
| | | map.put("EncryChatRoomId", ""); |
| | | list.add(map); |
| | | } |
| | | WebWxBatchGetContactMain(paramMap, list); |
| | | } |
| | | |
| | | private void WebWxBatchGetContactMain(Map<String, Object> paramMap, List<Map<String, String>> list) { |
| | | |
| | | String url = String.format(URLEnum.WEB_WX_BATCH_GET_CONTACT.getUrl(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()), System.currentTimeMillis(), |
| | | core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey())); |
| | | |
| | | int totalSize = list.size(); |
| | | |
| | | int batchSize = 50; |
| | | int num = totalSize / batchSize; |
| | | if (totalSize % batchSize > 0) { |
| | | num += 1; |
| | | } |
| | | |
| | | for (int i = 0; i < num; i++) { |
| | | int startNum = i * batchSize; |
| | | int endNum = (i + 1) * batchSize; |
| | | if (endNum > totalSize) { |
| | | endNum = totalSize; |
| | | } |
| | | paramMap.put("Count", endNum - startNum); |
| | | paramMap.put("List", list.subList(startNum, endNum)); |
| | | HttpEntity entity = core.getMyHttpClient().doPost(url, JSON.toJSONString(paramMap), getPersistentCookieMap()); |
| | | try { |
| | | String text = EntityUtils.toString(entity, Consts.UTF_8); |
| | | JSONObject obj = JSON.parseObject(text); |
| | | JSONArray contactList = obj.getJSONArray("ContactList"); |
| | | int contactSize = contactList.size(); |
| | | if (contactSize > 0) { |
| | | for (int j = 0; j < contactSize; j++) { |
| | | String userName = contactList.getJSONObject(j).getString("UserName"); |
| | | if (userName.startsWith("@@")) { |
| | | CoreManage.addNewGroup(core, contactList.getJSONObject(j)); |
| | | } else if (userName.startsWith("@")) { |
| | | CoreManage.addNewContact(core, contactList.getJSONObject(j)); |
| | | } |
| | | } |
| | | } |
| | | } 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; |
| | | } |
| | | |
| | | /** |
| | | * å¤çç»éä¿¡æ¯ |
| | | * |
| | | * @param loginContent |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ9æ¥ ä¸å12:16:26 |
| | | */ |
| | | private boolean 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('/')); |
| | | core.getLoginInfo().put("url", url); |
| | | Map<String, List<String>> possibleUrlMap = this.getPossibleUrlMap(); |
| | | Iterator<Entry<String, List<String>>> iterator = possibleUrlMap.entrySet().iterator(); |
| | | 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 { |
| | | Map<String, String> header = new HashMap<>(); |
| | | header.put("client-version", "2.0.0"); |
| | | header.put("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=="); |
| | | originalUrl = originalUrl + "&fun=new&version=v2&mod=desktop&lang=zh_CN"; |
| | | HttpEntity entity = core.getMyHttpClient().doGet(originalUrl, null, false, header); |
| | | text = EntityUtils.toString(entity); |
| | | } catch (Exception e) { |
| | | LOG.info(e.getMessage()); |
| | | return false; |
| | | } |
| | | //add by é»éé» 2017-08-01 22:28:09 |
| | | //妿ç»å½è¢«ç¦æ¢æ¶ï¼åç»å½è¿åçmessageå
容ä¸ä¸ºç©ºï¼ä¸é¢ä»£ç å夿ç»å½å
容æ¯å¦ä¸ºç©ºï¼ä¸ä¸ºç©ºåéåºç¨åº |
| | | String msg = getLoginMessage(text); |
| | | if (!"".equals(msg)) { |
| | | LOG.info(msg); |
| | | // System.exit(0); |
| | | return false; |
| | | } |
| | | 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()); |
| | | } |
| | | |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | 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 |
| | | * |
| | | * @return |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´5æ12æ¥ ä¸å12:24:55 |
| | | */ |
| | | 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", -System.currentTimeMillis() / 1000); |
| | | String paramStr = JSON.toJSONString(paramMap); |
| | | try { |
| | | HttpEntity entity = core.getMyHttpClient().doPost(url, paramStr, getPersistentCookieMap()); |
| | | 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(); |
| | | /** |
| | | * éçæ¯æ¬¡è·åææ°æ¶æ¯ï¼åè§9ï¼åçè¿å弿´æ°ï¼å
¶ç®çå¨äºæ¯æ¬¡åæ¥æ¶æ¯åè®°å½ä¸ä¸ªå½å忥çç¶æ |
| | | */ |
| | | 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 |
| | | * |
| | | * @return |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ16æ¥ ä¸å11:11:34 |
| | | */ |
| | | 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(System.currentTimeMillis()))); |
| | | params.add(new BasicNameValuePair("synckey", (String) core.getLoginInfo().get("synckey"))); |
| | | params.add(new BasicNameValuePair("_", String.valueOf(System.currentTimeMillis()))); |
| | | try { |
| | | HttpEntity entity = core.getMyHttpClient().doGet(url, params, true, getPersistentCookieMap()); |
| | | 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; |
| | | } |
| | | |
| | | private Map<String, String> getPersistentCookieMap() { |
| | | /** |
| | | * 以ä¸é¨åç¡®ä¿cookieåå¨headerä¸ï¼é坿¶éè¦å¼ºå¶æå¨æ·»å ï¼ |
| | | * TODO ä¸å¼ºå¶å éå¯ä¼cookie失æ,è¿ä¸ç¡®å®é®é¢ |
| | | */ |
| | | String cookieStr = null; |
| | | if (core != null && core.getMyHttpClient() != null && core.getMyHttpClient().getCookieStore() != null) { |
| | | List<Cookie> cookies = core.getMyHttpClient().getCookieStore().getCookies(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | if (CollectionUtil.isNotEmpty(cookies)) { |
| | | for (Cookie ck : cookies) { |
| | | sb.append(ck.getName()).append('=').append(ck.getValue()).append(';'); |
| | | } |
| | | cookieStr = sb.toString().substring(0, sb.toString().length() - 1); |
| | | } |
| | | |
| | | } |
| | | Map<String, String> headerMap = null; |
| | | if (cookieStr != null) { |
| | | headerMap = new HashMap<>(6); |
| | | headerMap.put("Cookie", cookieStr); |
| | | } |
| | | /* ^-----------------------------------------------^ */ |
| | | return headerMap; |
| | | } |
| | | |
| | | /** |
| | | * è§£æç»å½è¿åçæ¶æ¯ï¼å¦ææåç»å½ï¼å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 ""; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils; |
| | | |
| | | import org.ruoyi.common.wechat.itchat4j.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://org.ruoyi.common.wechat"; |
| | | public static final String VERSION = "1.2.18"; |
| | | public static final String BASE_URL = "https://login.weixin.qq.com"; |
| | | 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"; |
| | | |
| | | /** |
| | | * ä»
ä»
ç¨äºåè |
| | | */ |
| | | @Deprecated |
| | | 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | /** |
| | | * å
Œ
±æ¥å¿æ¥å£ |
| | | * @author WesleyOne |
| | | * @create 2018/12/12 |
| | | */ |
| | | public interface LogInterface { |
| | | public final Logger LOG = LoggerFactory.getLogger("WXROBLOG"); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/19 |
| | | */ |
| | | public class MoreConfig { |
| | | |
| | | //åå¨ç¾¤èæåIDç鮿 è¯ |
| | | public static final String SEND_MEMBER_ID = "sendMemberId"; |
| | | public static final String SEND_MEMBER_NICKNAMW = "memberNickname"; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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(); |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»å |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´4æ23æ¥ ä¸å12:15:00 |
| | | * @version 1.0 |
| | | * |
| | | */ |
| | | public enum MsgCodeEnum { |
| | | |
| | | MSGTYPE_TEXT(1, "ææ¬æ¶æ¯"), |
| | | MSGTYPE_IMAGE(3, "å¾çæ¶æ¯"), |
| | | MSGTYPE_VOICE(34, "è¯é³æ¶æ¯"), |
| | | MSGTYPE_VERIFYMSG(37, "好å请æ±"), |
| | | MSGTYPE_POSSIBLEFRIEND_MSG(40, "POSSIBLEFRIEND_MSG"), |
| | | MSGTYPE_SHARECARD(42, "å享åç"), |
| | | MSGTYPE_VIDEO(43, "è§é¢æ¶æ¯"), |
| | | MSGTYPE_EMOTICON(47, "表æ
æ¶æ¯"), |
| | | MSGTYPE_LOCATION(48, "ä½ç½®æ¶æ¯"), |
| | | MSGTYPE_MEDIA(49, "åäº«é¾æ¥"), |
| | | MSGTYPE_VOIPMSG(50, "VOIPMSG"), |
| | | MSGTYPE_STATUSNOTIFY(51, "ç¶æéç¥"), |
| | | MSGTYPE_VOIPNOTIFY(52, "VOIPNOTIFY"), |
| | | MSGTYPE_VOIPINVITE(53, "VOIPINVITE"), |
| | | MSGTYPE_MICROVIDEO(62, "çè§é¢æ¶æ¯"), |
| | | MSGTYPE_SYSNOTICE(9999, "SYSNOTICE"), |
| | | MSGTYPE_SYS(10000, "ç³»ç»æ¶æ¯"), |
| | | MSGTYPE_RECALLED(10002, "æ¤åæ¶æ¯") |
| | | |
| | | ; |
| | | |
| | | private static final Map<Integer, MsgCodeEnum> lookup = new HashMap<>(); |
| | | static { |
| | | for (MsgCodeEnum s : EnumSet.allOf(MsgCodeEnum.class)){ |
| | | lookup.put(s.getCode(), s); |
| | | } |
| | | } |
| | | public static MsgCodeEnum fromCode(int code) { |
| | | return lookup.get(code); |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | |
| | | /** |
| | | * æ¶æ¯ç±»åæä¸¾ç±» |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´5æ13æ¥ ä¸å11:53:00 |
| | | * @version 1.0 |
| | | * |
| | | */ |
| | | public enum MsgTypeEnum { |
| | | TEXT("Text", "ææ¬æ¶æ¯"), |
| | | MAP("MAP", "å°çä½ç½®"), |
| | | 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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 |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * è¿åç»ææä¸¾ç±» |
| | | * <p> |
| | | * Created by xiaoxiaomo on 2017/5/6. |
| | | */ |
| | | @Getter |
| | | public enum ResultEnum { |
| | | |
| | | SUCCESS("200", "æå"), |
| | | WAIT_CONFIRM("201", "è¯·å¨ææºä¸ç¹å»ç¡®è®¤"), |
| | | WAIT_SCAN("400", "è¯·æ«æäºç»´ç "); |
| | | |
| | | |
| | | private final String code; |
| | | private final String msg; |
| | | |
| | | ResultEnum(String code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | |
| | | public enum RetCodeEnum { |
| | | |
| | | UNKOWN("9999", "æªç¥"), |
| | | SUCCESS("0", "æå"), |
| | | TICKET_ERROR("-14", "ticketé误"), |
| | | PARAM_ERROR("1", "ä¼ å
¥åæ°é误"), |
| | | NOT_LOGIN_WARN("1100", "æªç»å½æç¤º"), |
| | | NOT_LOGIN_CHECK("1101", "æªæ£æµå°ç»å½"), |
| | | COOKIE_INVALID_ERROR("1102", "cookie弿 æ"), |
| | | LOGIN_ENV_ERROR("1203", "å½åç»å½ç¯å¢å¼å¸¸ï¼ä¸ºäºå®å
¨èµ·è§è¯·ä¸è¦å¨web端è¿è¡ç»å½"), |
| | | TOO_OFEN("1205", "æä½é¢ç¹") |
| | | ; |
| | | |
| | | private static final Map<String, RetCodeEnum> lookup = new HashMap<String, RetCodeEnum>(); |
| | | static { |
| | | for (RetCodeEnum s : EnumSet.allOf(RetCodeEnum.class)){ |
| | | lookup.put(s.getCode(), s); |
| | | } |
| | | } |
| | | public static RetCodeEnum fromCode(String code) { |
| | | return lookup.get(code); |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/21 |
| | | */ |
| | | public enum SelectorEnum { |
| | | |
| | | |
| | | UNKOWN("9999", "æªç¥"), |
| | | NORMAL("0", "æ£å¸¸"), |
| | | NEW_MSG("2", "ææ°æ¶æ¯"), |
| | | SELECTOR_3("3", "访é®é¢ç¹#"), |
| | | MOD_CONTACT("4", "æäººä¿®æ¹äºèªå·±çæµç§°æä½ ä¿®æ¹äºå«äººç夿³¨"), |
| | | ADD_OR_DEL_CONTACT("6", "åå¨å 餿è
æ°å¢ç好åä¿¡æ¯"), |
| | | ENTER_OR_LEAVE_CHAT("7", "è¿å
¥æç¦»å¼è天çé¢"); |
| | | |
| | | private static final Map<String, SelectorEnum> lookup = new HashMap<>(); |
| | | static { |
| | | for (SelectorEnum s : EnumSet.allOf(SelectorEnum.class)) { |
| | | lookup.put(s.getCode(), s); |
| | | } |
| | | } |
| | | public static SelectorEnum fromCode(String code) { |
| | | return lookup.get(code); |
| | | } |
| | | |
| | | private String code; |
| | | private String type; |
| | | |
| | | SelectorEnum(String code, String type) { |
| | | this.code = code; |
| | | this.type = type; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | import com.jfinal.plugin.activerecord.Record; |
| | | |
| | | import java.util.*; |
| | | /** |
| | | * åéç±»å |
| | | * @author WesleyOne |
| | | * @create 2018/12/14 |
| | | */ |
| | | public enum SendMsgType { |
| | | |
| | | IMG("IMG","å¾ç"), |
| | | FILE("FILE","æä»¶"), |
| | | TEXT("TEXT","çº¯ææ¬") |
| | | ; |
| | | |
| | | private String value; |
| | | private String name; |
| | | |
| | | SendMsgType(String value, String name) { |
| | | this.value = value; |
| | | this.name = name; |
| | | } |
| | | |
| | | |
| | | private static final Map<String, SendMsgType> lookup = new HashMap<>(); |
| | | public static List<Record> LIST_KV = new ArrayList<>(); |
| | | static { |
| | | for (SendMsgType s : EnumSet.allOf(SendMsgType.class)){ |
| | | lookup.put(s.toValue(), s); |
| | | LIST_KV.add(new Record().set("v",s.toValue()).set("n",s.toName())); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * è·åæä¸¾çå¼ï¼æ´æ°å¼ãå符串å¼çï¼ |
| | | * @return |
| | | */ |
| | | public String toValue() { |
| | | return this.value; |
| | | } |
| | | |
| | | public String toName() { |
| | | return this.name; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®å¼ï¼æ´æ°å¼ãå符串å¼çï¼è·åç¸åºçæä¸¾ç±»å |
| | | * @param value |
| | | * @return |
| | | */ |
| | | public static SendMsgType fromValue(String value) { |
| | | return lookup.get(value); |
| | | } |
| | | |
| | | public boolean equal(SendMsgType type){ |
| | | if (type != null && this.toValue().equals(type.toValue())){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.enums; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | |
| | | /** |
| | | * Created by xiaoxiaomo on 2017/5/7. |
| | | */ |
| | | public enum StorageLoginInfoEnum { |
| | | |
| | | //URL |
| | | url("url",new String()), |
| | | fileUrl("fileUrl",new String()), |
| | | syncUrl("syncUrl",new String()), |
| | | //çæ15ä½éæºæ° |
| | | deviceid("deviceid",new String()), |
| | | |
| | | //baseRequest |
| | | skey("skey",new String()), |
| | | wxsid("wxsid",new String()), |
| | | wxuin("wxuin",new String()), |
| | | pass_ticket("pass_ticket",new String()), |
| | | |
| | | |
| | | InviteStartCount("InviteStartCount",new Integer(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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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&lang=zh_CN","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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.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"), |
| | | _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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.tools; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.vdurmont.emoji.EmojiParser; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.Config; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.OsNameEnum; |
| | | import org.w3c.dom.Document; |
| | | import org.xml.sax.InputSource; |
| | | |
| | | import javax.xml.parsers.DocumentBuilder; |
| | | import javax.xml.parsers.DocumentBuilderFactory; |
| | | import java.io.StringReader; |
| | | import java.util.*; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 常ç¨å·¥å
·ç±» |
| | | * |
| | | * @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)); |
| | | Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></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); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 转åæalias |
| | | * @param d |
| | | * @param k |
| | | */ |
| | | public static void emojiFormatter2(JSONObject d, String k) { |
| | | Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></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.parseToAliases(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))); |
| | | |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | String str2 = "ä¸çä¸ä¸<span class=\"emoji emoji1f46f\"></span>å䏿°´<span class=\"emoji emoji1f440\"></span>"; |
| | | |
| | | Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></span>", str2); |
| | | StringBuilder sb = new StringBuilder(); |
| | | String content = str2; |
| | | 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) { |
| | | System.out.println(EmojiParser.parseToUnicode(sb.toString())); |
| | | System.out.println(EmojiParser.parseToAliases(EmojiParser.parseToUnicode(sb.toString()))); |
| | | System.out.println(EmojiParser.removeAllEmojis(sb.toString())); |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.itchat4j.utils.tools; |
| | | |
| | | import org.apache.http.HttpEntity; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg; |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.LogInterface; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgTypeEnum; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum; |
| | | |
| | | 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; |
| | | |
| | | /** |
| | | * ä¸è½½å·¥å
·ç±» |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date å建æ¶é´ï¼2017å¹´4æ21æ¥ ä¸å11:18:46 |
| | | * @version 1.0 |
| | | * |
| | | */ |
| | | public class DownloadTools implements LogInterface { |
| | | private static Logger logger = Logger.getLogger("UTILLOG"); |
| | | |
| | | /** |
| | | * å¤çä¸è½½ä»»å¡ |
| | | * |
| | | * @author https://github.com/yaphone |
| | | * @date 2017å¹´4æ21æ¥ ä¸å11:00:25 |
| | | * @param msg |
| | | * @param type |
| | | * @param path |
| | | * @return |
| | | */ |
| | | public static Object getDownloadFn(BaseMsg msg, String type, String path, String uniqueKey) { |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | 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 = core.getMyHttpClient().doGet(url, params, true, headerMap); |
| | | try { |
| | | OutputStream out = new FileOutputStream(path); |
| | | byte[] bytes = EntityUtils.toByteArray(entity); |
| | | out.write(bytes); |
| | | out.flush(); |
| | | out.close(); |
| | | } catch (Exception e) { |
| | | logger.info(e.getMessage()); |
| | | return false; |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.annotation; |
| | | |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | |
| | | /** |
| | | * 䏿£æ¥ç»å½ |
| | | */ |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | public @interface UnCheckLogin { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.base; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * é误管ç |
| | | * @author WesleyOne |
| | | * @create 2018/7/28 |
| | | */ |
| | | public enum BaseError { |
| | | |
| | | UNPERMISSION("09","没ææä½æé"), |
| | | UNLOGIN("01","æªç»å½æç»å½è¿æ"), |
| | | OPERATION_ERR("8899","æä½å¤±è´¥!"), |
| | | NORMAL_ERR("8999","åæ°å¼å¸¸"), |
| | | SYSTEM_ERR("9999","ç³»ç»å¼å¸¸"); |
| | | |
| | | |
| | | private String code; |
| | | private String msg; |
| | | BaseError(String code, String msg) { |
| | | this.code = code; |
| | | this.msg = msg; |
| | | } |
| | | |
| | | |
| | | private static final Map<String, BaseError> lookup = new HashMap<String, BaseError>(); |
| | | static { |
| | | for (BaseError s : EnumSet.allOf(BaseError.class)) |
| | | lookup.put(s.getMsg(), s); |
| | | } |
| | | |
| | | /** |
| | | * è·åæä¸¾çå¼ï¼æ´æ°å¼ãå符串å¼çï¼ |
| | | * @return |
| | | */ |
| | | public String getCode() { |
| | | return this.code; |
| | | } |
| | | |
| | | public String getMsg() { |
| | | return this.msg; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ ¹æ®å¼ï¼æ´æ°å¼ãå符串å¼çï¼è·åç¸åºçæä¸¾ç±»å |
| | | * @param code |
| | | * @return |
| | | */ |
| | | public static BaseError fromValue(String code) { |
| | | return lookup.get(code); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.base; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç»ä¸å¼å¸¸å¯¹è±¡ |
| | | * @author WesleyOne |
| | | * @create 2018/7/28 |
| | | */ |
| | | public class BaseException extends Exception implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 2007525058641283836L; |
| | | |
| | | private String code; |
| | | |
| | | public BaseException(String code, String msg) { |
| | | super(msg); |
| | | this.code = code; |
| | | |
| | | } |
| | | |
| | | public BaseException(BaseError baseError) { |
| | | super(baseError.getMsg()); |
| | | this.code = baseError.getCode(); |
| | | } |
| | | |
| | | public BaseException(String msg) { |
| | | super(msg); |
| | | this.code = BaseError.NORMAL_ERR.getCode(); |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.base; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/7/28 |
| | | */ |
| | | public class BaseResponse<T> { |
| | | public static BaseResponse OK = new BaseResponse(); |
| | | |
| | | private String code = "00"; |
| | | private String message = "æä½æå"; |
| | | |
| | | private T data; |
| | | public BaseResponse() { |
| | | } |
| | | |
| | | public BaseResponse(T data) { |
| | | this.data = data; |
| | | } |
| | | |
| | | public BaseResponse(String code, String message) { |
| | | this.code = code; |
| | | this.message = message; |
| | | } |
| | | |
| | | public static BaseResponse success(){ |
| | | return new BaseResponse(); |
| | | } |
| | | |
| | | public static BaseResponse success(Object o){ |
| | | return new BaseResponse(o); |
| | | } |
| | | |
| | | public static BaseResponse error(String code,String msg){ |
| | | BaseResponse r = new BaseResponse(); |
| | | r.setCode(code); |
| | | r.setMessage(msg); |
| | | return r; |
| | | } |
| | | public static BaseResponse error(BaseError baseError){ |
| | | BaseResponse r = new BaseResponse(); |
| | | r.setCode(baseError.getCode()); |
| | | r.setMessage(baseError.getMsg()); |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * æªç»å½è¿å |
| | | * @return |
| | | */ |
| | | public static BaseResponse unLogin(){ |
| | | BaseResponse r = new BaseResponse(); |
| | | r.setCode(BaseError.UNLOGIN.getCode()); |
| | | r.setMessage(BaseError.UNLOGIN.getMsg()); |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * æ æéè¿å |
| | | * @return |
| | | */ |
| | | public static BaseResponse unPermission(){ |
| | | BaseResponse r = new BaseResponse(); |
| | | r.setCode(BaseError.UNPERMISSION.getCode()); |
| | | r.setMessage(BaseError.UNPERMISSION.getMsg()); |
| | | return r; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public void setCode(String code) { |
| | | this.code = code; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public void setMessage(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.cache; |
| | | |
| | | import org.ruoyi.common.wechat.web.utils.LRUCache; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | |
| | | /** |
| | | * ç®åçæ¬å°ä¼è¯åå¨ |
| | | * @author WesleyOne |
| | | * @create 2018/9/25 |
| | | */ |
| | | public class UserSession { |
| | | public static LinkedHashMap<String,String> USERSESSION_CACHE = new LRUCache<String, String>(64); |
| | | |
| | | public static void addUserSession(String username,String userSession){ |
| | | USERSESSION_CACHE.put(username,userSession); |
| | | } |
| | | |
| | | public static void delUserSession(String username){ |
| | | USERSESSION_CACHE.remove(username); |
| | | } |
| | | |
| | | public static boolean checkUserSession(String username,String userSession){ |
| | | String s = USERSESSION_CACHE.get(username); |
| | | if (userSession!=null&&userSession.equals(s)){ |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.common; |
| | | |
| | | import com.alibaba.druid.filter.stat.StatFilter; |
| | | import com.alibaba.druid.wall.WallFilter; |
| | | import com.jfinal.config.*; |
| | | import com.jfinal.json.FastJsonFactory; |
| | | import com.jfinal.kit.PropKit; |
| | | import com.jfinal.plugin.activerecord.ActiveRecordPlugin; |
| | | import com.jfinal.plugin.activerecord.dialect.MysqlDialect; |
| | | import com.jfinal.plugin.druid.DruidPlugin; |
| | | import com.jfinal.server.undertow.UndertowServer; |
| | | import com.jfinal.template.Engine; |
| | | import com.jfinal.template.source.ClassPathSourceFactory; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.web.constant.UploadConstant; |
| | | import org.ruoyi.common.wechat.web.interceptor.ExceptionInterceptor; |
| | | import org.ruoyi.common.wechat.web.model._MappingKit; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.File; |
| | | |
| | | |
| | | /** |
| | | * JFinal项ç®çæ ¸å¿é
ç½® |
| | | * 详æ
æ¥ç宿¹ææ¡£ |
| | | * https://www.jfinal.com/doc |
| | | * |
| | | * @author WesleyOne |
| | | */ |
| | | public class MyConfig extends JFinalConfig { |
| | | |
| | | public final Logger LOG = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | public static void main(String[] args) { |
| | | UndertowServer.start(MyConfig.class, 8180, true); |
| | | } |
| | | |
| | | /** |
| | | * é
置常é |
| | | */ |
| | | @Override |
| | | public void configConstant(Constants me) { |
| | | PropKit.use("appConfig.properties"); |
| | | me.setDevMode(PropKit.getBoolean("devMode", false)); |
| | | //ä¸ä¼ çæä»¶çæå¤§50M |
| | | me.setMaxPostSize(10 * 1024 * 1024); |
| | | me.setEncoding("UTF-8"); |
| | | me.setJsonFactory(new FastJsonFactory()); |
| | | me.setError404View("/WEB-INF/templates/404.html"); |
| | | } |
| | | |
| | | /** |
| | | * é
ç½®è·¯ç± |
| | | */ |
| | | @Override |
| | | public void configRoute(Routes me) { |
| | | me.add(new MyRoute()); |
| | | me.add(new OutRoute()); |
| | | } |
| | | |
| | | @Override |
| | | public void configEngine(Engine me) { |
| | | me.setDevMode(PropKit.use("appConfig.properties").getBoolean("devMode", false)); |
| | | me.addSharedFunction("/WEB-INF/templates/bs4temp/layout.html"); |
| | | me.addSharedObject("imgDomain" , UploadConstant.IMG_URL); |
| | | me.addSharedObject("filedomain" , UploadConstant.FILE_URL); |
| | | } |
| | | |
| | | /** |
| | | * é
ç½®æä»¶ |
| | | */ |
| | | @Override |
| | | public void configPlugin(Plugins me) { |
| | | // é
ç½® druid æ°æ®åºè¿æ¥æ± æä»¶ |
| | | DruidPlugin druidPlugin = createDruidPlugin(); |
| | | druidPlugin.addFilter(new StatFilter()); |
| | | WallFilter wall = new WallFilter(); |
| | | wall.setDbType("mysql"); |
| | | druidPlugin.addFilter(wall); |
| | | druidPlugin.setInitialSize(1); |
| | | me.add(druidPlugin); |
| | | |
| | | // é
ç½®ActiveRecordæä»¶ |
| | | ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); |
| | | _MappingKit.mapping(arp); |
| | | arp.setDialect(new MysqlDialect()); |
| | | arp.setShowSql(PropKit.use("appConfig.properties").getBoolean("devMode", false)); |
| | | arp.getEngine().setSourceFactory(new ClassPathSourceFactory()); |
| | | me.add(arp); |
| | | } |
| | | |
| | | public static DruidPlugin createDruidPlugin() { |
| | | return new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim()); |
| | | } |
| | | /** |
| | | * é
ç½®å
¨å±æ¦æªå¨ |
| | | */ |
| | | @Override |
| | | public void configInterceptor(Interceptors me) { |
| | | me.add(new ExceptionInterceptor()); |
| | | } |
| | | |
| | | /** |
| | | * é
ç½®å¤çå¨ |
| | | */ |
| | | @Override |
| | | public void configHandler(Handlers me) { |
| | | } |
| | | |
| | | @Override |
| | | public void afterJFinalStart() { |
| | | System.setProperty("jsse.enableSNIExtension", "false"); |
| | | // æ£æ¥æä»¶å¤¹(/çç»å½/ä¸è½½æ ¹ç®å½)æ¯å¦åå¨ |
| | | checkFileExist(); |
| | | |
| | | // çç»éæä½ |
| | | CoreManage.reload(); |
| | | } |
| | | |
| | | @Override |
| | | public void beforeJFinalStop() { |
| | | CoreManage.persistence(); |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥æä»¶å¤¹(/çç»å½/ä¸è½½æ ¹ç®å½)æ¯å¦åå¨ |
| | | */ |
| | | private void checkFileExist() { |
| | | String hotReloadDir = PropKit.get("hotReloadDir"); |
| | | String downloadPath = PropKit.get("download_path"); |
| | | String logPath = PropKit.get("log_path"); |
| | | File hotReloadFile = new File(hotReloadDir); |
| | | if (!hotReloadFile.exists()){ |
| | | if (!hotReloadFile.mkdirs()) { |
| | | LOG.error("çå è½½æä»¶å¤¹å建失败[{}]",hotReloadDir); |
| | | } |
| | | } |
| | | File downloadFile = new File(downloadPath); |
| | | if (!downloadFile.exists()){ |
| | | if (!downloadFile.mkdirs()) { |
| | | LOG.error("ä¸è½½æä»¶å¤¹å建失败[{}]",downloadPath); |
| | | } |
| | | } |
| | | File logFile = new File(logPath); |
| | | if (!logFile.exists()){ |
| | | if (!logFile.mkdirs()) { |
| | | LOG.error("æ¥å¿æä»¶å¤¹å建失败[{}]",logPath); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.common; |
| | | |
| | | import com.jfinal.config.Routes; |
| | | import org.ruoyi.common.wechat.web.controller.*; |
| | | import org.ruoyi.common.wechat.web.interceptor.VisitLogInterceptor; |
| | | |
| | | /** |
| | | * 管çåå°è·¯ç±ç»ä¸ç®¡ç |
| | | * @author wesleyOne |
| | | */ |
| | | public class MyRoute extends Routes { |
| | | |
| | | |
| | | @Override |
| | | public void config() { |
| | | //设置è§å¾æ ¹ç®å½ |
| | | setBaseViewPath("/WEB-INF/templates"); |
| | | //è®¾ç½®æ¦æªå¨ï¼åé¢çå
æ§è¡ |
| | | addInterceptor(new VisitLogInterceptor()); |
| | | //æ·»å è·¯ç± |
| | | add("/", IndexController.class); |
| | | add("/rob",RobotController.class); |
| | | add("/robwk",RobotWorkController.class); |
| | | add("/relate",RelateController.class); |
| | | add("/kw",KeyWordController.class); |
| | | |
| | | add("/upload",UploadController.class); |
| | | add("/tool",ToolController.class); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.common; |
| | | |
| | | import com.jfinal.config.Routes; |
| | | import org.ruoyi.common.wechat.web.controller.ExtendController; |
| | | import org.ruoyi.common.wechat.web.interceptor.VisitLogInterceptor4down; |
| | | |
| | | /** |
| | | * 对å¤è·¯ç±ç»ä¸ç®¡ç |
| | | * @author WesleyOne |
| | | * @create 2018/9/25 |
| | | */ |
| | | public class OutRoute extends Routes { |
| | | @Override |
| | | public void config() { |
| | | //设置è§å¾æ ¹ç®å½ |
| | | setBaseViewPath("/WEB-INF/templates"); |
| | | addInterceptor(new VisitLogInterceptor4down()); |
| | | //æ·»å è·¯ç± |
| | | add("/ext", ExtendController.class); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.constant; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/13 |
| | | */ |
| | | public class ConfigKeys { |
| | | |
| | | /** |
| | | * é»è®¤å
¨å±å
³é®ååå¤ç¨æµç§°ï¼è¯¥å段è¶
è¿16åç¬¦é²æ¢ä¸ç¨æ·æµç§°å²çª |
| | | * |
| | | * http://kf.qq.com/touch/wxappfaq/150910F322eY150910eIV32Q.html?platform=14 |
| | | * 微信æµç§°è®¾ç½®è§å |
| | | * æå¤å¯è®¾ç½®16个æ±åï¼å¯è®¾ç½®å«æä¸æãè±æãæ°åã符å·ç»åçæµç§°ï¼ä½ä¸å»ºè®®è®¾ç½®ç¹æ®å符ã |
| | | * 温馨æç¤ºï¼1个符å·ç¸å½äºä¸ä¸ªæ±åï¼2个æ°å/è±æç¸å½äº1个æ±åï¼ |
| | | */ |
| | | public static final String DEAFAULT_KEYWORD = "é»è®¤å
¨å±å
³é®ååå¤ç¨æµç§°-请å¿ä¿®æ¹"; |
| | | public static final String DEAFAULT_WELCOME = "é»è®¤ç¾¤æ¬¢è¿æ°äººç¨-请å¿ä¿®æ¹"; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.constant; |
| | | |
| | | import com.jfinal.kit.PathKit; |
| | | |
| | | import java.io.File; |
| | | |
| | | public class UploadConstant { |
| | | |
| | | public static final String IMG_FOLD = "img"; |
| | | public static final String FILE_FOLD = "file"; |
| | | |
| | | public static final String IMG_URL = "/"+IMG_FOLD+"/"; |
| | | public static final String FILE_URL = "/"+FILE_FOLD+"/"; |
| | | |
| | | public static final String IMG_PATH = PathKit.getWebRootPath()+ File.separator +IMG_FOLD; |
| | | public static final String FILE_PATH = PathKit.getWebRootPath()+ File.separator +FILE_FOLD; |
| | | public static final String IMG_PATH_SEP = IMG_PATH + File.separator; |
| | | public static final String FILE_PATH_SEP = FILE_PATH + File.separator; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | import org.ruoyi.common.wechat.web.model.WxRobRelation; |
| | | import org.ruoyi.common.wechat.web.utils.IpUtil; |
| | | |
| | | /** |
| | | * 坹夿¥å£ |
| | | * @author WesleyOne |
| | | * @create 2018/12/16 |
| | | */ |
| | | public class ExtendController extends _BaseController { |
| | | |
| | | |
| | | /** |
| | | * 对å¤éç¨è§ååæ¶æ¯ |
| | | * åæ°: |
| | | * ok 夿¥å¯ä¸ç |
| | | * msg æ¶æ¯å表 |
| | | * ç±»ååè@see org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType |
| | | * TEXT ææ¬æ¶æ¯ä¸² |
| | | * IMG å¾çå串ï¼éè¦åå°-éç¨å·¥å
·-ä¸ä¼ è·åï¼ |
| | | * FILE æä»¶å串ï¼éè¦åå°-éç¨å·¥å
·-ä¸ä¼ è·åï¼ |
| | | * ä¾å: |
| | | * {"ok":"test123", |
| | | * "msg":[ |
| | | * {"type":"TEXT","body":"ææ¯æ¶æ¯ä½"}, |
| | | * {"type":"IMG","body":"ty6yLk3X_1545142908614.jpg"}, |
| | | * {"type":"FILE","body":"ty6yLk3X_1545142537914.txt"}, |
| | | * ] |
| | | * } |
| | | * |
| | | * 说æ: |
| | | * åéé¡ºåºæç
§å表顺åºä»åå¾åå |
| | | * |
| | | * è¿å: |
| | | * 00 æå |
| | | * 01 夿¥ç ä¸åå¨ |
| | | * 02 夿¥ç 失æ |
| | | * 03 IPæªéè¿å®¡æ ¸ |
| | | * |
| | | */ |
| | | public void sendMsg(){ |
| | | |
| | | JSONObject postParam = getPostParam(); |
| | | String outKey = postParam.getString("ok"); |
| | | String msgStr = postParam.getString("msg"); |
| | | JSONArray msgs = JSONArray.parseArray(msgStr); |
| | | |
| | | if (StringUtils.isEmpty(outKey)){ |
| | | setCode("01"); |
| | | setMsg("夿¥ç ä¸åå¨"); |
| | | renderJson(); |
| | | return; |
| | | } |
| | | |
| | | WxRobRelation relationRecord = WxRobRelation.dao.findFirst("SELECT * FROM wx_rob_relation WHERE out_key = ? LIMIT 1", outKey); |
| | | |
| | | /** |
| | | * æ ¡éªIP |
| | | * 1.é
置空åæç»ææ |
| | | * 2.åå¨0.0.0.0䏿 ¡éª |
| | | */ |
| | | String whiteList = relationRecord.getWhiteList(); |
| | | if (StringUtils.isEmpty(whiteList) || !relationRecord.getEnable()){ |
| | | setCode("02"); |
| | | setMsg("夿¥ç å¤±æææªé
ç½®ç½åå"); |
| | | renderJson(); |
| | | return; |
| | | } |
| | | String allPassIp = "0.0.0.0"; |
| | | // 䏿¯å®å
¨å¼æ¾IPå¹¶ä¸è®¿é®IPä¸åå¨ |
| | | if (!whiteList.contains(allPassIp)){ |
| | | String outRealIp = IpUtil.getRealIp(getRequest()); |
| | | if (!whiteList.contains(outRealIp)){ |
| | | setCode("03"); |
| | | setMsg("IPæªéè¿å®¡æ ¸"); |
| | | renderJson(); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | String uniqueKey = relationRecord.getUniqueKey(); |
| | | // æ¥çæºå¨æ¯å¦å è½½å®æ |
| | | if (!CoreManage.getInstance(uniqueKey).isAlive() || !CoreManage.getInstance(uniqueKey).isFinishInit()){ |
| | | setCode("05"); |
| | | setMsg("æºå¨æªåå¤å®æ"); |
| | | renderJson(); |
| | | return; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ·»å å°æ¶æ¯éå |
| | | */ |
| | | Boolean toGroup = relationRecord.getToGroup(); |
| | | String nickName = relationRecord.getNickName(); |
| | | // 忬¡è¯·æ±æå¤§æ¶æ¯æ° |
| | | int maxMessages = 10; |
| | | int msgLength = msgs.size(); |
| | | if (msgLength<maxMessages){ |
| | | maxMessages = msgLength; |
| | | } |
| | | // å°è¿ä¸æ¥é»è®¤è¿åæå |
| | | boolean result = true; |
| | | for (int i=0;i<maxMessages;i++){ |
| | | JSONObject message = msgs.getJSONObject(i); |
| | | String type = message.getString("type"); |
| | | String body = message.getString("body"); |
| | | |
| | | CoreManage.addSendMsg4NickName(uniqueKey,nickName,body,SendMsgType.fromValue(type),toGroup); |
| | | } |
| | | |
| | | if (!result){ |
| | | setOperateErr(); |
| | | } |
| | | |
| | | renderJson(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.jfinal.kit.PropKit; |
| | | import org.apache.commons.lang3.RandomStringUtils; |
| | | import org.ruoyi.common.wechat.web.annotation.UnCheckLogin; |
| | | import org.ruoyi.common.wechat.web.cache.UserSession; |
| | | |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/7/27 |
| | | */ |
| | | public class IndexController extends _BaseController { |
| | | |
| | | public static final String WX_ROB_LOGIN_ = "WX_ROB_LOGIN_"; |
| | | |
| | | public void index(){ |
| | | |
| | | setAttr("username",getCookie("uid")); |
| | | setAttr("imgdomain",PropKit.get("imgDomain")); |
| | | |
| | | |
| | | renderTemplate("index.html"); |
| | | } |
| | | |
| | | @UnCheckLogin |
| | | public void login(){ |
| | | redirect("/",false); |
| | | // æµè¯å
ç»å½ |
| | | if (PropKit.getBoolean("devMode")){ |
| | | redirect("/loginPost?username=wxwobot&password=wxwobot",true); |
| | | return; |
| | | } |
| | | renderTemplate("login.html"); |
| | | } |
| | | |
| | | /** |
| | | * ç»å
¥ |
| | | */ |
| | | @UnCheckLogin |
| | | public void loginPost(){ |
| | | String sid = UUID.randomUUID().toString(); |
| | | UserSession.addUserSession("wxwobot",sid); |
| | | addCookie("uid","wxwobot",-1); |
| | | addCookie("sid",sid,-1); |
| | | redirect("/",false); |
| | | //return; |
| | | |
| | | |
| | | // String username = getPara("username"); |
| | | // String password = getPara("password"); |
| | | // if (vldParamNull(username,"ç¨æ·åä¸è½ä¸ºç©º")|| |
| | | // vldParamNull(password,"å¯ç ä¸è½ä¸ºç©º")){ |
| | | // return; |
| | | // } |
| | | // |
| | | // // è·åçå®å¯ç ãæ¤å¤ä¸ºäºæ¹ä¾¿ç´æ¥ä»é
ç½®æä»¶éè·å |
| | | // String pass = PropKit.use("passport.properties").get(username); |
| | | // // æ¸
æ¥ç¼å,å¯ä»¥ä¿®æ¹é
ç½®æä»¶ç´æ¥ä¿®æ¹ |
| | | // PropKit.useless("passport.properties"); |
| | | // |
| | | // if (StringUtils.isNotEmpty(password) && pass != null && pass.equals(MD5Util.MD5Encrypt(password))){ |
| | | // |
| | | // //String sid = UUID.randomUUID().toString(); |
| | | // UserSession.addUserSession(username,sid); |
| | | // addCookie("uid",username,-1); |
| | | // addCookie("sid",sid,-1); |
| | | // redirect("/",false); |
| | | // return; |
| | | // }else { |
| | | // setAttr("error","è´¦å·å¯ç 䏿£ç¡®"); |
| | | // renderTemplate("login.html"); |
| | | // } |
| | | } |
| | | |
| | | @UnCheckLogin |
| | | public void logout(){ |
| | | String uid = getUid(); |
| | | if (uid!=null){ |
| | | UserSession.delUserSession(uid); |
| | | } |
| | | redirect("/login",false); |
| | | } |
| | | |
| | | /** |
| | | * 游客ç»å½ |
| | | */ |
| | | @UnCheckLogin |
| | | public void visitLogin() { |
| | | String visitName = RandomStringUtils.randomAlphabetic(5); |
| | | String sid = UUID.randomUUID().toString(); |
| | | UserSession.addUserSession(visitName,sid); |
| | | addCookie("uid",visitName,-1); |
| | | addCookie("sid",sid,-1); |
| | | redirect("/",false); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.jfinal.plugin.activerecord.Page; |
| | | import com.jfinal.render.JsonRender; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.api.WechatTools; |
| | | import org.ruoyi.common.wechat.web.enums.KeyMsgValueType; |
| | | import org.ruoyi.common.wechat.web.model.WxRobKeyword; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * TODO å
³é®è¯æä½ |
| | | * @author WesleyOne |
| | | * @create 2018/12/16 |
| | | */ |
| | | public class KeyWordController extends _BaseController{ |
| | | |
| | | public void index(){ |
| | | |
| | | String uniqueKey = getPara("uk"); |
| | | if (StringUtils.isNotEmpty(uniqueKey)){ |
| | | setAttr("search_uk",uniqueKey); |
| | | } |
| | | setAttr("keys",KeyMsgValueType.LIST_KV); |
| | | renderTemplate("index.html"); |
| | | } |
| | | |
| | | |
| | | public void list(){ |
| | | int rows = getParaToInt("limit", 10); |
| | | int pageNum = getPageNum(getParaToInt("offset", 1), rows); |
| | | String uniqueKey = getPara("uniqueKey"); |
| | | String keyData = getPara("keyData"); |
| | | String nickName = getPara("nickName"); |
| | | String typeData = getPara("typeData"); |
| | | Boolean enable = getParaToBoolean("enable"); |
| | | Boolean togrp = getParaToBoolean("togrp"); |
| | | |
| | | String where = " where 1=1 "; |
| | | if (StringUtils.isNotEmpty(uniqueKey)){ |
| | | where += " and unique_key = '"+uniqueKey + "' "; |
| | | } |
| | | if (StringUtils.isNotEmpty(keyData)) { |
| | | where += " and key_data LIKE '" + keyData + "%' "; |
| | | } |
| | | if (StringUtils.isNotEmpty(nickName)) { |
| | | where += " and nick_name LIKE '" + nickName + "%' "; |
| | | } |
| | | if (KeyMsgValueType.fromValue(typeData) != null){ |
| | | where += " and type_data = '" + typeData + "' "; |
| | | } |
| | | if (enable != null){ |
| | | |
| | | where += " and enable = " + (enable?1:0); |
| | | } |
| | | if (togrp != null){ |
| | | where += " and to_group = " + (togrp?1:0); |
| | | } |
| | | |
| | | Page<WxRobKeyword> page = WxRobKeyword.dao.paginate(pageNum, rows, "select * ", |
| | | " from wx_rob_keyword "+where); |
| | | |
| | | setAttrs(buildPagination(page.getList(), page.getTotalRow())); |
| | | render(new JsonRender().forIE()); |
| | | } |
| | | |
| | | public void editIndex(){ |
| | | Integer kid = getParaToInt("kid"); |
| | | WxRobKeyword kwRecord; |
| | | boolean isEdit = true; |
| | | List<String> groupNickNames = new ArrayList<>(); |
| | | if (kid != null){ |
| | | kwRecord = WxRobKeyword.dao.findById(kid); |
| | | }else{ |
| | | isEdit = false; |
| | | kwRecord = new WxRobKeyword(); |
| | | String uniqueKey = getPara("uk"); |
| | | if (StringUtils.isNotEmpty(uniqueKey)){ |
| | | kwRecord.setUniqueKey(uniqueKey); |
| | | groupNickNames.addAll(WechatTools.getGroupNickNameList(uniqueKey)); |
| | | } |
| | | // é»è®¤æ¾ç¤ºææ¬ |
| | | kwRecord.setTypeData(KeyMsgValueType.TEXT.toValue()); |
| | | } |
| | | setAttr("isEdit",isEdit); |
| | | setAttr("form",kwRecord); |
| | | |
| | | setAttr("keys",KeyMsgValueType.LIST_KV); |
| | | setAttr("groupNickNames",groupNickNames); |
| | | renderTemplate("editIndex.html"); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ä¿®æ¹ |
| | | */ |
| | | public void editKeyWord(){ |
| | | JSONObject postParam = getPostParam(); |
| | | Long id = postParam.getLong("kid"); |
| | | String uniqueKey = postParam.getString("uniqueKey"); |
| | | String keyData = postParam.getString("keyData"); |
| | | String valueData = postParam.getString("valueData"); |
| | | String nickName = postParam.getString("nickName"); |
| | | String typeData = postParam.getString("typeData"); |
| | | Boolean enable = postParam.getBoolean("enable"); |
| | | Boolean toGroup = postParam.getBoolean("toGroup"); |
| | | |
| | | WxRobKeyword editRecord = new WxRobKeyword(); |
| | | |
| | | if (StringUtils.isNotEmpty(keyData)){ |
| | | editRecord.setKeyData(keyData); |
| | | } |
| | | if (StringUtils.isNotEmpty(valueData)){ |
| | | editRecord.setValueData(valueData); |
| | | } |
| | | if (StringUtils.isNotEmpty(nickName)){ |
| | | editRecord.setNickName(nickName); |
| | | } |
| | | if (KeyMsgValueType.fromValue(typeData) != null){ |
| | | editRecord.setTypeData(typeData); |
| | | }else { |
| | | editRecord.setTypeData(KeyMsgValueType.TEXT.toValue()); |
| | | } |
| | | if (enable != null){ |
| | | editRecord.setEnable(enable); |
| | | } |
| | | if (toGroup != null){ |
| | | editRecord.setToGroup(toGroup); |
| | | } |
| | | |
| | | if (id != null){ |
| | | editRecord.setId(id); |
| | | boolean update = editRecord.update(); |
| | | if (update){ |
| | | setMsg("ä¿®æ¹æå"); |
| | | }else{ |
| | | setOperateErr("ä¿®æ¹å¤±è´¥"); |
| | | } |
| | | }else{ |
| | | // æ ¡éª |
| | | editRecord.setUniqueKey(uniqueKey); |
| | | editRecord.setCreateTime(new Date()); |
| | | editRecord.setEnable(true); |
| | | if (vldParamNull(editRecord.getUniqueKey(),"å¯ä¸ç ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getKeyData(),"å
³é®åä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getValueData(),"å
容ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getTypeData(),"å
容类åä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getNickName(),"æµç§°ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getToGroup(),"群èå¥½åæªéæ©")){ |
| | | return; |
| | | } |
| | | boolean save = editRecord.save(); |
| | | if (save){ |
| | | setMsg("æ°å¢æå"); |
| | | }else{ |
| | | setOperateErr("æ°å¢å¤±è´¥"); |
| | | } |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å
³é®å |
| | | */ |
| | | public void delKeyWord(){ |
| | | |
| | | String kid = getPara("kid"); |
| | | boolean delete = WxRobKeyword.dao.deleteById(kid); |
| | | if (delete){ |
| | | setMsg("å 餿å"); |
| | | }else{ |
| | | setOperateErr("å é¤å¤±è´¥"); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.jfinal.plugin.activerecord.Page; |
| | | import com.jfinal.render.JsonRender; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.api.WechatTools; |
| | | import org.ruoyi.common.wechat.web.model.WxRobRelation; |
| | | import org.ruoyi.common.wechat.web.utils.UUIDShortUtil; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * TODO å
³èé
ç½® |
| | | * @author WesleyOne |
| | | * @create 2018/12/16 |
| | | */ |
| | | public class RelateController extends _BaseController { |
| | | |
| | | public void index(){ |
| | | String outKey = getPara("ok"); |
| | | if (StringUtils.isNotEmpty(outKey)){ |
| | | setAttr("search_ok",outKey); |
| | | } |
| | | String searchUk = getPara("uk"); |
| | | if (StringUtils.isNotEmpty(searchUk)){ |
| | | setAttr("search_uk",searchUk); |
| | | } |
| | | renderTemplate("index.html"); |
| | | } |
| | | |
| | | public void list(){ |
| | | int rows = getParaToInt("limit", 10); |
| | | int pageNum = getPageNum(getParaToInt("offset", 1), rows); |
| | | String outKey = getPara("outKey"); |
| | | String uniqueKey = getPara("uniqueKey"); |
| | | String nickName = getPara("nickName"); |
| | | Boolean enable = getParaToBoolean("enable"); |
| | | Boolean togrp = getParaToBoolean("togrp"); |
| | | |
| | | String where = " where 1=1 "; |
| | | if (StringUtils.isNotEmpty(outKey)) { |
| | | where += " and out_key = '" + outKey + "' "; |
| | | } |
| | | if (StringUtils.isNotEmpty(uniqueKey)){ |
| | | where += " and unique_key = '"+uniqueKey + "' "; |
| | | } |
| | | if (StringUtils.isNotEmpty(nickName)) { |
| | | where += " and nick_name LIKE '" + nickName + "%' "; |
| | | } |
| | | if (enable != null){ |
| | | where += " and enable = " + (enable?1:0); |
| | | } |
| | | if (togrp != null){ |
| | | where += " and to_group = " + (togrp?1:0); |
| | | } |
| | | |
| | | Page<WxRobRelation> page = WxRobRelation.dao.paginate(pageNum, rows, "select * ", |
| | | " from wx_rob_relation "+where); |
| | | |
| | | setAttrs(buildPagination(page.getList(), page.getTotalRow())); |
| | | render(new JsonRender().forIE()); |
| | | } |
| | | |
| | | public void editIndex(){ |
| | | Integer kid = getParaToInt("kid"); |
| | | WxRobRelation wxRobRelation; |
| | | boolean isEdit = true; |
| | | List<String> groupNickNames = new ArrayList<>(); |
| | | if (kid != null){ |
| | | wxRobRelation = WxRobRelation.dao.findById(kid); |
| | | }else{ |
| | | isEdit = false; |
| | | wxRobRelation = new WxRobRelation(); |
| | | String uniqueKey = getPara("uk"); |
| | | String nickName = getPara("nk"); |
| | | Boolean toGroup = getParaToBoolean("tgb"); |
| | | if (StringUtils.isNotEmpty(uniqueKey)){ |
| | | wxRobRelation.setUniqueKey(uniqueKey); |
| | | groupNickNames.addAll(WechatTools.getGroupNickNameList(uniqueKey)); |
| | | } |
| | | if (StringUtils.isNotEmpty(nickName)){ |
| | | wxRobRelation.setNickName(nickName); |
| | | } |
| | | if (toGroup != null){ |
| | | wxRobRelation.setToGroup(toGroup); |
| | | }else{ |
| | | wxRobRelation.setToGroup(true); |
| | | } |
| | | } |
| | | setAttr("isEdit",isEdit); |
| | | setAttr("form",wxRobRelation); |
| | | setAttr("groupNickNames",groupNickNames); |
| | | renderTemplate("editIndex.html"); |
| | | } |
| | | |
| | | /** |
| | | * ç¼è¾å¤é¨idå
³è |
| | | */ |
| | | public void editRelate(){ |
| | | JSONObject postParam = getPostParam(); |
| | | Long id = postParam.getLong("kid"); |
| | | String uniqueKey = postParam.getString("uniqueKey"); |
| | | String nickName = postParam.getString("nickName"); |
| | | String whiteList = postParam.getString("whiteList"); |
| | | Boolean enable = postParam.getBoolean("enable"); |
| | | Boolean toGroup = postParam.getBoolean("toGroup"); |
| | | |
| | | WxRobRelation editRecord = new WxRobRelation(); |
| | | |
| | | if (StringUtils.isNotEmpty(nickName)){ |
| | | editRecord.setNickName(nickName); |
| | | } |
| | | if (enable != null){ |
| | | editRecord.setEnable(enable); |
| | | } |
| | | if (toGroup != null){ |
| | | editRecord.setToGroup(toGroup); |
| | | } |
| | | if (StringUtils.isNotEmpty(whiteList)){ |
| | | editRecord.setWhiteList(whiteList); |
| | | } |
| | | |
| | | if (id != null){ |
| | | editRecord.setId(id); |
| | | boolean update = editRecord.update(); |
| | | if (update){ |
| | | setMsg("ä¿®æ¹æå"); |
| | | }else{ |
| | | setOperateErr("ä¿®æ¹å¤±è´¥"); |
| | | } |
| | | }else{ |
| | | // æ ¡éª |
| | | editRecord.setUniqueKey(uniqueKey); |
| | | editRecord.setCreateTime(new Date()); |
| | | editRecord.setEnable(true); |
| | | if (vldParamNull(editRecord.getUniqueKey(),"å¯ä¸ç ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getNickName(),"æµç§°ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(editRecord.getToGroup(),"群èå¥½åæªéæ©")){ |
| | | return; |
| | | } |
| | | |
| | | boolean isSuccess = false; |
| | | int maxTime = 5; |
| | | while (!isSuccess && maxTime >0){ |
| | | String outKey = UUIDShortUtil.generateShortUuid(); |
| | | editRecord.setOutKey(outKey); |
| | | isSuccess = editRecord.save(); |
| | | maxTime--; |
| | | } |
| | | if (isSuccess){ |
| | | setMsg("æ°å¢æå"); |
| | | }else{ |
| | | setOperateErr("æ°å¢å¤±è´¥"); |
| | | } |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤å¤é¨idå
³è |
| | | */ |
| | | public void delRelate(){ |
| | | String kid = getPara("kid"); |
| | | boolean delete = WxRobRelation.dao.deleteById(kid); |
| | | if (delete){ |
| | | setMsg("å 餿å"); |
| | | }else{ |
| | | setOperateErr("å é¤å¤±è´¥"); |
| | | } |
| | | renderJson(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.jfinal.plugin.activerecord.Db; |
| | | import com.jfinal.plugin.activerecord.Page; |
| | | import com.jfinal.plugin.activerecord.Record; |
| | | import com.jfinal.render.JsonRender; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.itchat4j.core.Core; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.web.base.BaseException; |
| | | import org.ruoyi.common.wechat.web.model.WxRobConfig; |
| | | import org.ruoyi.common.wechat.web.utils.UUIDShortUtil; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æºå¨äººç¸å
³ç®¡çæ¥å£ |
| | | * @author WesleyOne |
| | | * @create 2018/12/16 |
| | | */ |
| | | public class RobotController extends _BaseController { |
| | | |
| | | /** |
| | | * æºå¨äººé¡µé¢ |
| | | */ |
| | | public void index(){ |
| | | renderTemplate("index.html"); |
| | | } |
| | | |
| | | /** |
| | | * æºå¨äººå表 |
| | | * åé¡µï¼æç´¢æ¡ä»¶ |
| | | */ |
| | | public void list(){ |
| | | int rows = getParaToInt("limit", 10); |
| | | int pageNum = getPageNum(getParaToInt("offset", 1), rows); |
| | | String searchUniqueKey = getPara("uniqueKey"); |
| | | String remark = getPara("remark"); |
| | | Boolean enable = getParaToBoolean("enable"); |
| | | String where = " where 1=1 "; |
| | | if (StringUtils.isNotEmpty(searchUniqueKey)){ |
| | | where += " and unique_key = '"+searchUniqueKey + "' "; |
| | | } |
| | | if (StringUtils.isNotEmpty(remark)) { |
| | | where += " and remark like '" + remark + "%' "; |
| | | } |
| | | if (enable != null){ |
| | | where += " and enable = " + (enable?1:0); |
| | | } |
| | | |
| | | Page<WxRobConfig> page = WxRobConfig.dao.paginate(pageNum, rows, "select * ", |
| | | " from wx_rob_config "+where); |
| | | //å
¶ä»å¤ç |
| | | List<WxRobConfig> dataList = page.getList(); |
| | | if (CollectionUtil.isNotEmpty(dataList)){ |
| | | for (WxRobConfig conf: dataList){ |
| | | // è·åæºå¨äººç¶æ |
| | | String uniqueKey = conf.getUniqueKey(); |
| | | conf.setActive(CoreManage.isActive(uniqueKey)); |
| | | } |
| | | } |
| | | |
| | | setAttrs(buildPagination(dataList, page.getTotalRow())); |
| | | render(new JsonRender().forIE()); |
| | | } |
| | | |
| | | /** |
| | | * æºå¨äººé¡µé¢ |
| | | */ |
| | | public void addIndex(){ |
| | | renderTemplate("addIndex.html"); |
| | | } |
| | | |
| | | /** |
| | | * æ·»å æºå¨äºº |
| | | */ |
| | | public void addRob(){ |
| | | JSONObject postParam = getPostParam(); |
| | | String remark = postParam.getString("remark"); |
| | | |
| | | if (vldParamNull(remark,"微信å·ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | |
| | | Record remarkRecord = Db.findFirst("SELECT remark FROM wx_rob_config WHERE remark = ? LIMIT 1", remark); |
| | | if (vldParamNull(remarkRecord != null,"夿³¨å·²åå¨")){ |
| | | return; |
| | | } |
| | | WxRobConfig bean = new WxRobConfig(); |
| | | bean.setRemark(remark) |
| | | .setCreateTime(new Date()) |
| | | .setUpdateTime(new Date()) |
| | | .setToFriend(false) |
| | | .setToGroup(true) |
| | | .setFromOut(false) |
| | | .setDefaultFriend(false) |
| | | .setDefaultGroup(false); |
| | | |
| | | boolean isSuccess = false; |
| | | int maxTime = 5; |
| | | while (!isSuccess && maxTime >0){ |
| | | String uniKey = UUIDShortUtil.generateShortUuid(); |
| | | bean.setUniqueKey(uniKey); |
| | | isSuccess = bean.save(); |
| | | maxTime--; |
| | | } |
| | | |
| | | if (!isSuccess){ |
| | | setOperateErr(); |
| | | }else{ |
| | | setData(bean); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * æºå¨äººå¯å¨ç¦æ¢å¼å
³ï¼åé群èå¼å
³ï¼åé好åå¼å
³,坹夿¥å£æ¶æ¯å¼å
³ |
| | | */ |
| | | public void change(){ |
| | | JSONObject postParam = getPostParam(); |
| | | Long id = postParam.getLong("rid"); |
| | | String type = postParam.getString("type"); |
| | | Boolean state = postParam.getBoolean("state"); |
| | | |
| | | if (id == null || StringUtils.isEmpty(type) || state == null){ |
| | | setOperateErr(); |
| | | renderJson(); |
| | | return; |
| | | } |
| | | |
| | | WxRobConfig config = new WxRobConfig(); |
| | | config.setId(id); |
| | | if ("enable".equals(type)){ |
| | | config.setEnable(state); |
| | | }else if ("tofrd".equals(type)){ |
| | | config.setToFriend(state); |
| | | }else if ("togrp".equals(type)){ |
| | | config.setToGroup(state); |
| | | }else if ("fromout".equals(type)) { |
| | | config.setFromOut(state); |
| | | }else if ("default_group".equals(type)){ |
| | | config.setDefaultGroup(state); |
| | | }else if ("default_friend".equals(type)){ |
| | | config.setDefaultFriend(state); |
| | | }else { |
| | | setOperateErr("éæ³æä½"); |
| | | render(new JsonRender().forIE()); |
| | | return; |
| | | } |
| | | |
| | | config.setUpdateTime(new Date()); |
| | | boolean update = config.update(); |
| | | if (!update){ |
| | | setOperateErr(); |
| | | }else{ |
| | | setData(update); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹å¤æ³¨ |
| | | */ |
| | | public void changeRemark(){ |
| | | JSONObject postParam = getPostParam(); |
| | | Long id = postParam.getLong("rid"); |
| | | String remark = postParam.getString("remark"); |
| | | if (vldParamNull(id,"IDä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | if (vldParamNull(remark,"夿³¨ä¸è½ä¸ºç©º")){ |
| | | return; |
| | | } |
| | | |
| | | Record remarkRecord = Db.findFirst("SELECT remark FROM wx_rob_config WHERE remark = ? LIMIT 1", remark); |
| | | if (vldParamNull(remarkRecord != null,"夿³¨å·²åå¨")){ |
| | | return; |
| | | } |
| | | WxRobConfig config = new WxRobConfig(); |
| | | config.setId(id); |
| | | config.setRemark(remark); |
| | | boolean update = config.update(); |
| | | if (!update){ |
| | | setOperateErr(); |
| | | }else{ |
| | | setData(update); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * åéé¡µé¢ |
| | | */ |
| | | public void sendIndex() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | Core core = CoreManage.getInstance(uniqueKey); |
| | | List<JSONObject> sourceSendList = new ArrayList<>(); |
| | | sourceSendList.addAll( core.getGroupList()); |
| | | sourceSendList.addAll( core.getContactList()); |
| | | List<JSONObject> targetList = new ArrayList<>(); |
| | | JSONObject filehelper = new JSONObject(); |
| | | filehelper.put("UserName","filehelper"); |
| | | filehelper.put("NickName","æä»¶ä¼ è¾å©æ"); |
| | | targetList.add(filehelper); |
| | | for (JSONObject jsonObject : sourceSendList) { |
| | | JSONObject newObject = new JSONObject(); |
| | | if (StringUtils.isEmpty(jsonObject.getString("NickName"))){ |
| | | continue; |
| | | } |
| | | newObject.put("NickName",jsonObject.getString("NickName")); |
| | | newObject.put("UserName",jsonObject.getString("UserName")); |
| | | targetList.add(newObject); |
| | | } |
| | | setAttr("uniqueKey",uniqueKey); |
| | | setAttr("targetList",targetList); |
| | | renderTemplate("sendIndex.html"); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.ruoyi.common.wechat.itchat4j.api.WechatTools; |
| | | import org.ruoyi.common.wechat.itchat4j.controller.LoginController; |
| | | import org.ruoyi.common.wechat.itchat4j.core.CoreManage; |
| | | import org.ruoyi.common.wechat.itchat4j.service.impl.LoginServiceImpl; |
| | | import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType; |
| | | import org.ruoyi.common.wechat.web.base.BaseException; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/16 |
| | | */ |
| | | public class RobotWorkController extends _BaseController { |
| | | |
| | | /** |
| | | * è·åç¶æ |
| | | * @throws BaseException |
| | | */ |
| | | public void getStatus() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | boolean wechatStatus = WechatTools.getWechatStatus(uniqueKey); |
| | | setData(wechatStatus); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * ç»å½ç¬¬ä¸æ¥ï¼è·åäºç»´ç 龿¥ |
| | | * @throws BaseException |
| | | */ |
| | | public void getQr() throws BaseException, IOException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginController login = new LoginController(uniqueKey); |
| | | String qrSrc = login.login_1(); |
| | | setData(qrSrc); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * ç»å½ç¬¬äºæ¥,确认ç»å½ç¶æ |
| | | * @throws BaseException |
| | | */ |
| | | public void login() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginController login = new LoginController(uniqueKey); |
| | | boolean result = login.login_2(); |
| | | if (result){ |
| | | |
| | | }else{ |
| | | setOperateErr(); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * ç»å½ç¬¬ä¸æ¥ï¼ç¡®è®¤ç»å½ååå§åä¿¡æ¯ |
| | | * @throws BaseException |
| | | */ |
| | | public void init() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginController login = new LoginController(uniqueKey); |
| | | boolean loginResult = login.login_3(); |
| | | if (loginResult){ |
| | | setMsg("ç»å½æå"); |
| | | }else{ |
| | | setMsg("ç»å½å¤±è´¥ï¼å
³éäºç»´ç åéæ°æå¼"); |
| | | } |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * éåº |
| | | * @throws BaseException |
| | | */ |
| | | public void logout() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | WechatTools.logout(uniqueKey); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * è·å群æµç§° |
| | | */ |
| | | public void getGroupNickNames() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | List<String> groupNickNameList = WechatTools.getGroupNickNameList(uniqueKey); |
| | | setData(groupNickNameList); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¥½åæµç§° |
| | | */ |
| | | public void getContactNickNames() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | List<String> contactNickNameList = WechatTools.getContactNickNameList(uniqueKey); |
| | | setData(contactNickNameList); |
| | | renderJson(); |
| | | } |
| | | |
| | | public void getGroups() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | List<JSONObject> groupList = WechatTools.getGroupList(uniqueKey); |
| | | setData(groupList); |
| | | renderJson(); |
| | | } |
| | | |
| | | public void getContacts() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | List<JSONObject> contactList = WechatTools.getContactList(uniqueKey); |
| | | setData(contactList); |
| | | renderJson(); |
| | | } |
| | | |
| | | public void getCore() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | setData(CoreManage.getInstance(uniqueKey)); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * 强å¶å·æ°éè®¯å½ |
| | | */ |
| | | public void gct() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginServiceImpl loginService = new LoginServiceImpl(uniqueKey); |
| | | loginService.webWxGetContact(); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * å·æ°é讯å½è¯¦æ
|
| | | * @throws BaseException |
| | | */ |
| | | public void ggp() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginServiceImpl loginService = new LoginServiceImpl(uniqueKey); |
| | | loginService.WebWxBatchGetContact(); |
| | | renderJson(); |
| | | } |
| | | |
| | | /** |
| | | * éå¯ |
| | | * @throws BaseException |
| | | */ |
| | | public void reboot() throws BaseException { |
| | | String uniqueKey = getUniqueKey(); |
| | | LoginController login = new LoginController(uniqueKey); |
| | | boolean loginResult = login.reboot(); |
| | | setData(loginResult); |
| | | renderJson(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æå¨å¤ä»½çç»å½ä¿¡æ¯ |
| | | */ |
| | | public void manualCopy(){ |
| | | CoreManage.persistence(); |
| | | renderJson(); |
| | | } |
| | | |
| | | public void testSend() throws BaseException { |
| | | |
| | | JSONObject postParam = getPostParam(); |
| | | String uniqueKey = postParam.getString("uniqueKey"); |
| | | String data = postParam.getString("valueData"); |
| | | String userName = postParam.getString("userName"); |
| | | String typeData = postParam.getString("typeData"); |
| | | |
| | | CoreManage.addSendMsg4UserName(uniqueKey,userName,data, SendMsgType.fromValue(typeData)); |
| | | renderJson(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | /** |
| | | * éç¨å·¥å
· |
| | | * @author WesleyOne |
| | | * @create 2018/12/24 |
| | | */ |
| | | public class ToolController extends _BaseController { |
| | | |
| | | public void index(){ |
| | | renderTemplate("index.html"); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.jfinal.upload.UploadFile; |
| | | import org.ruoyi.common.wechat.web.constant.UploadConstant; |
| | | |
| | | import java.io.File; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/14 |
| | | */ |
| | | public class UploadController extends _BaseController { |
| | | |
| | | |
| | | public void img2local(){ |
| | | UploadFile file = getFile(); |
| | | |
| | | String fn = getPara("fn", ""); |
| | | String originalFileName = file.getOriginalFileName(); |
| | | int i = file.getOriginalFileName().lastIndexOf(".")+1; |
| | | String fileType = originalFileName.substring(i); |
| | | String fileName = fn + "_" + System.currentTimeMillis() + "." + fileType; |
| | | String newFilePath = UploadConstant.IMG_PATH+File.separator+fileName; |
| | | file.getFile().renameTo(new File(newFilePath)); |
| | | |
| | | setAttr("name",fileName); |
| | | |
| | | renderJson(); |
| | | } |
| | | |
| | | public void file2local(){ |
| | | UploadFile file = getFile(); |
| | | |
| | | String fn = getPara("fn", ""); |
| | | String originalFileName = file.getOriginalFileName(); |
| | | int i = file.getOriginalFileName().lastIndexOf(".")+1; |
| | | String fileType = originalFileName.substring(i); |
| | | String fileName = fn + "_" + System.currentTimeMillis() + "." + fileType; |
| | | String newFilePath = UploadConstant.FILE_PATH+File.separator+fileName; |
| | | file.getFile().renameTo(new File(newFilePath)); |
| | | |
| | | setAttr("name",fileName); |
| | | |
| | | renderJson(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.jfinal.core.Controller; |
| | | import com.jfinal.core.NotAction; |
| | | import com.jfinal.kit.HttpKit; |
| | | import com.jfinal.kit.StrKit; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.wechat.web.base.BaseError; |
| | | import org.ruoyi.common.wechat.web.base.BaseException; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import javax.servlet.http.Cookie; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/7/27 |
| | | */ |
| | | public class _BaseController extends Controller { |
| | | |
| | | public final Logger LOG = LoggerFactory.getLogger(this.getClass()); |
| | | |
| | | |
| | | /** |
| | | * éç¨éªè¯ |
| | | * @param result true说æéªè¯ä¸éè¿ |
| | | * @param code |
| | | * @param errorMsg |
| | | */ |
| | | @NotAction |
| | | public boolean vldParam(boolean result, String code, String errorMsg){ |
| | | if (result){ |
| | | setAttr("code",code); |
| | | setAttr("message",errorMsg); |
| | | this.renderJson(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @NotAction |
| | | public boolean vldParam(boolean result, BaseError baseError){ |
| | | if (result){ |
| | | return vldParam(true,baseError.getCode(),baseError.getMsg()); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @NotAction |
| | | public boolean vldParam(boolean result, String errMsg){ |
| | | if (result){ |
| | | return vldParam(true,BaseError.NORMAL_ERR.getCode(),errMsg); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * åæ°éç©ºå¤æ |
| | | * @param paramValue |
| | | * @param baseError |
| | | * @return |
| | | */ |
| | | @NotAction |
| | | public boolean vldParamNull(String paramValue, BaseError baseError){ |
| | | if (StrKit.isBlank(paramValue)) { |
| | | return vldParam(true,baseError.getCode(),baseError.getMsg()); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @NotAction |
| | | public boolean vldParamNull(String paramValue, String errMsg){ |
| | | if (StrKit.isBlank(paramValue)) { |
| | | return vldParam(true,BaseError.NORMAL_ERR.getCode(),errMsg); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * åæ°éç©ºå¤æ |
| | | * @param paramValue |
| | | * @param baseError |
| | | * @return |
| | | */ |
| | | @NotAction |
| | | public boolean vldParamNull(Object paramValue, BaseError baseError){ |
| | | if (paramValue == null) { |
| | | return vldParam(true,baseError.getCode(),baseError.getMsg()); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @NotAction |
| | | public boolean vldParamNull(Object paramValue, String errMsg){ |
| | | if (paramValue == null) { |
| | | return vldParam(true,BaseError.NORMAL_ERR.getCode(),errMsg); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @NotAction |
| | | public void setData(Object o){ |
| | | this.setAttr("data",o); |
| | | } |
| | | @NotAction |
| | | public void setCount(Object o){ |
| | | this.setAttr("_count",o); |
| | | } |
| | | @NotAction |
| | | public void setCode(String code){ |
| | | this.setAttr("code",code); |
| | | } |
| | | @NotAction |
| | | public void setMsg(String msg){ |
| | | this.setAttr("message",msg); |
| | | } |
| | | @NotAction |
| | | public void setOperateErr(String msg){ |
| | | this.setAttr("code",BaseError.OPERATION_ERR.getCode()); |
| | | this.setAttr("message",msg); |
| | | } |
| | | @NotAction |
| | | public void setOperateErr(){ |
| | | this.setAttr("code",BaseError.OPERATION_ERR.getCode()); |
| | | this.setAttr("message",BaseError.OPERATION_ERR.getMsg()); |
| | | } |
| | | @NotAction |
| | | public void setDeleteErr(){ |
| | | this.setAttr("code",BaseError.OPERATION_ERR.getCode()); |
| | | this.setAttr("message",BaseError.OPERATION_ERR.getMsg()); |
| | | } |
| | | |
| | | @NotAction |
| | | public void addCookie(String key,String value,int second) { |
| | | Cookie cookie = new Cookie(key,value); |
| | | cookie.setMaxAge(second); |
| | | cookie.setPath("/"); |
| | | setCookie(cookie); |
| | | } |
| | | |
| | | @NotAction |
| | | public JSONObject getPostParam(){ |
| | | String jsonString= HttpKit.readData(getRequest()); |
| | | return JSONObject.parseObject(jsonString); |
| | | } |
| | | @NotAction |
| | | public String getUid(){ |
| | | return this.getCookie("uid"); |
| | | } |
| | | |
| | | /** |
| | | * å页å¤ç |
| | | * @param list |
| | | * @param count |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | @NotAction |
| | | protected Map<String, Object> buildPagination(List list, Integer count) { |
| | | return buildPagination(list, count, null); |
| | | } |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @NotAction |
| | | protected Map<String, Object> buildPagination(List list, Integer count, |
| | | List<Map<String, Object>> footer) { |
| | | Map<String, Object> map = new HashMap<String, Object>(4); |
| | | map.put("total", count); |
| | | map.put("rows", list); |
| | | if (footer != null){ |
| | | map.put("footer", footer); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | @NotAction |
| | | protected static int getPageNum(int pageNum,int rows){ |
| | | int pageNumber = pageNum / rows + 1; |
| | | return pageNumber; |
| | | } |
| | | |
| | | /** |
| | | * è·åUniqueKey |
| | | * @return |
| | | */ |
| | | @NotAction |
| | | public String getUniqueKey() throws BaseException { |
| | | String uniqueKey = getPara("_ck", ""); |
| | | if (StringUtils.isEmpty(uniqueKey)){ |
| | | throw new BaseException("æºå¨å¯ä¸ç 为空"); |
| | | } |
| | | return uniqueKey; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.enums; |
| | | |
| | | import com.jfinal.plugin.activerecord.Record; |
| | | |
| | | import java.util.*; |
| | | public enum KeyMsgValueType { |
| | | |
| | | IMG("IMG", "å¾ç"), |
| | | FILE("FILE", "æä»¶"), |
| | | TEXT("TEXT", "çº¯ææ¬"); |
| | | |
| | | private String value; |
| | | private String name; |
| | | |
| | | KeyMsgValueType(String value, String name) { |
| | | this.value = value; |
| | | this.name = name; |
| | | } |
| | | |
| | | private static final Map<String, KeyMsgValueType> lookup = new HashMap<>(); |
| | | public static List<Record> LIST_KV = new ArrayList<>(); |
| | | |
| | | static { |
| | | for (KeyMsgValueType s : EnumSet.allOf(KeyMsgValueType.class)) { |
| | | lookup.put(s.toValue(), s); |
| | | LIST_KV.add(new Record().set("v", s.toValue()).set("n", s.toName())); |
| | | } |
| | | } |
| | | |
| | | public String toValue() { |
| | | return this.value; |
| | | } |
| | | |
| | | public String toName() { |
| | | return this.name; |
| | | } |
| | | |
| | | public static KeyMsgValueType fromValue(String value) { |
| | | return lookup.get(value); |
| | | } |
| | | |
| | | public boolean equal(KeyMsgValueType type) { |
| | | return type != null && this.toValue().equals(type.toValue()); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.interceptor; |
| | | |
| | | import com.jfinal.aop.Interceptor; |
| | | import com.jfinal.aop.Invocation; |
| | | import org.ruoyi.common.wechat.web.base.BaseError; |
| | | import org.ruoyi.common.wechat.web.base.BaseException; |
| | | import org.ruoyi.common.wechat.web.base.BaseResponse; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | |
| | | /** |
| | | * å
¨å±å¼å¸¸æ¦æª |
| | | * @author WesleyOne |
| | | * @create 2018/7/28 |
| | | */ |
| | | public class ExceptionInterceptor implements Interceptor { |
| | | |
| | | private static final Logger LOG = LoggerFactory.getLogger(ExceptionInterceptor.class); |
| | | |
| | | @Override |
| | | public void intercept(Invocation me) { |
| | | try { |
| | | me.getController().setAttr("code","00"); |
| | | me.getController().setAttr("message","æä½æå"); |
| | | me.invoke(); |
| | | } |
| | | catch (Exception e) { |
| | | LOG.error(e.getMessage(),e); |
| | | BaseResponse resp = new BaseResponse(); |
| | | Throwable cause = e.getCause(); |
| | | String ajax = me.getController().getRequest().getHeader("X-Requested-With"); |
| | | //夿ajax请æ±è¿æ¯é¡µé¢è¯·æ± |
| | | if ("XMLHttpRequest".equals(ajax)){ |
| | | if (cause instanceof BaseException) { |
| | | resp.setCode(((BaseException) cause).getCode()); |
| | | resp.setMessage(cause.getMessage()); |
| | | } else{ |
| | | resp.setCode(BaseError.SYSTEM_ERR.getCode()); |
| | | resp.setMessage(BaseError.SYSTEM_ERR.getMsg()); |
| | | } |
| | | me.getController().renderJson(resp); |
| | | return; |
| | | }else{ |
| | | //é»è®¤ç³»ç»500页é¢ï¼æ·»å 第äºä¸ªåæ°å¯èªè¡æ·»å 500é¡µé¢ |
| | | me.getController().renderError(500); |
| | | return; |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.interceptor; |
| | | |
| | | |
| | | import com.jfinal.aop.Interceptor; |
| | | import com.jfinal.aop.Invocation; |
| | | import org.ruoyi.common.wechat.web.annotation.UnCheckLogin; |
| | | import org.ruoyi.common.wechat.web.cache.UserSession; |
| | | import org.ruoyi.common.wechat.web.utils.IpUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Method; |
| | | |
| | | |
| | | /** |
| | | * 管çå尿使¥å¿ |
| | | * @author admin |
| | | */ |
| | | public class VisitLogInterceptor implements Interceptor { |
| | | public static final Logger LOG = LoggerFactory.getLogger(VisitLogInterceptor.class); |
| | | |
| | | @Override |
| | | public void intercept(Invocation inv) { |
| | | String requestUrl = inv.getActionKey(); |
| | | String uid = inv.getController().getCookie("uid"); |
| | | String sid = inv.getController().getCookie("sid"); |
| | | String ip = IpUtil.getRealIp(inv.getController().getRequest()); |
| | | LOG.info("{} - {} - {} æä½äº {}",ip,uid,sid,requestUrl); |
| | | |
| | | inv.getController().setAttr("active",inv.getController().getControllerKey()); |
| | | |
| | | //æ¾å°ä¸éè¦ç»å½çaction |
| | | Class controllerClass = inv.getController().getClass(); |
| | | UnCheckLogin methodOwn = getControllerMethodUnLoginOwn(controllerClass, inv.getMethodName()); |
| | | if (methodOwn != null) { |
| | | LOG.info("ä¸éè¦ç»å½,requestUrl=" + requestUrl); |
| | | inv.invoke(); |
| | | return; |
| | | } |
| | | |
| | | boolean isLogin = UserSession.checkUserSession(uid,sid); |
| | | if (!isLogin){ |
| | | //æªç»å
¥ |
| | | inv.getController().redirect("/login",false); |
| | | return; |
| | | } |
| | | |
| | | long start = System.currentTimeMillis(); |
| | | inv.invoke(); |
| | | long l = System.currentTimeMillis() - start; |
| | | if (l > 1000*2){ |
| | | LOG.warn("è¯·æ± {} ,è¿æ¥æ¶é¿ {} ms",requestUrl,l); |
| | | } |
| | | } |
| | | |
| | | //--------------以䏿¯å
鍿¹æ³----------- |
| | | |
| | | private UnCheckLogin getControllerMethodUnLoginOwn(Class controllerClass, String methodName) { |
| | | for (Method method : controllerClass.getMethods()) { |
| | | if (methodName.equals(method.getName())) { |
| | | return getUnLogin(method); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private UnCheckLogin getUnLogin(Method method) { |
| | | Annotation[] annotations = method.getAnnotations(); |
| | | for (Annotation annt : annotations) { |
| | | if (annt instanceof UnCheckLogin) { |
| | | UnCheckLogin own = (UnCheckLogin) annt; |
| | | return own; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.interceptor; |
| | | |
| | | import com.jfinal.aop.Interceptor; |
| | | import com.jfinal.aop.Invocation; |
| | | import org.ruoyi.common.wechat.web.utils.IpUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | /** |
| | | * 坹夿¥å£è®¿é®æ¥å¿ |
| | | * @author WesleyOne |
| | | * @create 2018/9/25 |
| | | */ |
| | | public class VisitLogInterceptor4down implements Interceptor { |
| | | |
| | | public static final Logger LOG = LoggerFactory.getLogger(VisitLogInterceptor4down.class); |
| | | |
| | | @Override |
| | | public void intercept(Invocation inv) { |
| | | String ip = IpUtil.getRealIp(inv.getController().getRequest()); |
| | | StringBuffer requestURL = inv.getController().getRequest().getRequestURL(); |
| | | String queryString = inv.getController().getRequest().getQueryString(); |
| | | LOG.info("{} æä½äº {} {}",ip,requestURL,queryString); |
| | | inv.invoke(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model; |
| | | |
| | | import org.ruoyi.common.wechat.web.model.base.BaseWxRobConfig; |
| | | |
| | | /** |
| | | * Generated by JFinal. |
| | | */ |
| | | @SuppressWarnings("serial") |
| | | public class WxRobConfig extends BaseWxRobConfig<WxRobConfig> { |
| | | public static final WxRobConfig dao = new WxRobConfig().dao(); |
| | | |
| | | private boolean isActive; |
| | | |
| | | public boolean isActive() { |
| | | return isActive; |
| | | } |
| | | |
| | | public void setActive(boolean active) { |
| | | isActive = active; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model; |
| | | |
| | | import org.ruoyi.common.wechat.web.model.base.BaseWxRobKeyword; |
| | | |
| | | /** |
| | | * Generated by JFinal. |
| | | */ |
| | | @SuppressWarnings("serial") |
| | | public class WxRobKeyword extends BaseWxRobKeyword<WxRobKeyword> { |
| | | public static final WxRobKeyword dao = new WxRobKeyword().dao(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model; |
| | | |
| | | import org.ruoyi.common.wechat.web.model.base.BaseWxRobRelation; |
| | | |
| | | /** |
| | | * Generated by JFinal. |
| | | */ |
| | | @SuppressWarnings("serial") |
| | | public class WxRobRelation extends BaseWxRobRelation<WxRobRelation> { |
| | | public static final WxRobRelation dao = new WxRobRelation().dao(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model; |
| | | |
| | | import com.jfinal.kit.PathKit; |
| | | import com.jfinal.kit.PropKit; |
| | | import com.jfinal.plugin.activerecord.dialect.MysqlDialect; |
| | | import com.jfinal.plugin.activerecord.generator.Generator; |
| | | import com.jfinal.plugin.druid.DruidPlugin; |
| | | import org.ruoyi.common.wechat.web.common.MyConfig; |
| | | |
| | | import javax.sql.DataSource; |
| | | |
| | | /** |
| | | * æ¬ demo ä»
表达æä¸ºç²æµ
ç jfinal ç¨æ³ï¼æ´ä¸ºæä»·å¼çå®ç¨çä¼ä¸çº§ç¨æ³ |
| | | * è¯¦è§ JFinal 俱ä¹é¨: http://jfinal.com/club |
| | | * |
| | | * 卿°æ®åºè¡¨æä»»ä½å卿¶ï¼è¿è¡ä¸ä¸ main æ¹æ³ï¼æéååºååè¿è¡ä»£ç éæ |
| | | */ |
| | | public class _JFinalDemoGenerator { |
| | | |
| | | // public static DataSource getDataSource() { |
| | | //// PropKit.use("appConfig.properties"); |
| | | //// DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim(),PropKit.get("jdbcDriverSqlServe")); |
| | | //// DruidPlugin druidPlugin = new DruidPlugin("jdbc:mysql://127.0.0.1:3306/wxwobot?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull","root", "root"); |
| | | // DruidPlugin druidPlugin = new DruidPlugin("jdbc:mysql://localhost:3306/wxwobot?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull", |
| | | // "root", "root"); |
| | | // druidPlugin.start(); |
| | | // return druidPlugin.getDataSource(); |
| | | // } |
| | | public static DataSource getDataSource() { |
| | | DruidPlugin druidPlugin = MyConfig.createDruidPlugin(); |
| | | druidPlugin.start(); |
| | | return druidPlugin.getDataSource(); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | PropKit.use("appConfig.properties"); |
| | | // base model æä½¿ç¨çå
å |
| | | String baseModelPackageName = "org.ruoyi.common.wechat.web.model.base"; |
| | | // base model æä»¶ä¿åè·¯å¾ |
| | | String baseModelOutputDir = PathKit.getWebRootPath() + "/src/main/java/org.ruoyi.common.wechat/web/model/base"; |
| | | |
| | | // model æä½¿ç¨çå
å (MappingKit é»è®¤ä½¿ç¨çå
å) |
| | | String modelPackageName = "org.ruoyi.common.wechat.web.model"; |
| | | // model æä»¶ä¿åè·¯å¾ (MappingKit ä¸ DataDictionary æä»¶é»è®¤ä¿åè·¯å¾) |
| | | String modelOutputDir = baseModelOutputDir + "/.."; |
| | | |
| | | // å建çæå¨ |
| | | Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir); |
| | | // 设置æ¯å¦çæé¾å¼ setter æ¹æ³ |
| | | generator.setGenerateChainSetter(false); |
| | | // æ·»å ä¸éè¦çæç表å |
| | | generator.addExcludedTable(); |
| | | // 设置æ¯å¦å¨ Model ä¸çæ dao 对象 |
| | | generator.setGenerateDaoInModel(false); |
| | | // 设置æ¯å¦çæé¾å¼ setter æ¹æ³ |
| | | generator.setGenerateChainSetter(true); |
| | | // 设置æ¯å¦çæåå
¸æä»¶ |
| | | generator.setGenerateDataDictionary(false); |
| | | // 设置éè¦è¢«ç§»é¤ç表ååç¼ç¨äºçæmodelNameãä¾å¦è¡¨å "osc_user"ï¼ç§»é¤åç¼ "osc_"åçæçmodelå为 "User"èé OscUser |
| | | // generator.setRemovedTableNamePrefixes("t_"); |
| | | |
| | | generator.setDialect(new MysqlDialect()); |
| | | // çæ |
| | | generator.generate(); |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model; |
| | | |
| | | import com.jfinal.plugin.activerecord.ActiveRecordPlugin; |
| | | |
| | | /** |
| | | * Generated by JFinal, do not modify this file. |
| | | * <pre> |
| | | * Example: |
| | | * public void configPlugin(Plugins me) { |
| | | * ActiveRecordPlugin arp = new ActiveRecordPlugin(...); |
| | | * _MappingKit.mapping(arp); |
| | | * me.add(arp); |
| | | * } |
| | | * </pre> |
| | | */ |
| | | public class _MappingKit { |
| | | |
| | | public static void mapping(ActiveRecordPlugin arp) { |
| | | arp.addMapping("wx_rob_config", "id", WxRobConfig.class); |
| | | arp.addMapping("wx_rob_keyword", "id", WxRobKeyword.class); |
| | | arp.addMapping("wx_rob_relation", "id", WxRobRelation.class); |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model.base; |
| | | |
| | | import com.jfinal.plugin.activerecord.IBean; |
| | | import com.jfinal.plugin.activerecord.Model; |
| | | |
| | | /** |
| | | * Generated by JFinal, do not modify this file. |
| | | */ |
| | | @SuppressWarnings({"serial", "unchecked"}) |
| | | public abstract class BaseWxRobConfig<M extends BaseWxRobConfig<M>> extends Model<M> implements IBean { |
| | | |
| | | public M setId(Long id) { |
| | | set("id", id); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return getLong("id"); |
| | | } |
| | | |
| | | public M setUniqueKey(String uniqueKey) { |
| | | set("unique_key", uniqueKey); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getUniqueKey() { |
| | | return getStr("unique_key"); |
| | | } |
| | | |
| | | public M setRemark(String remark) { |
| | | set("remark", remark); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getRemark() { |
| | | return getStr("remark"); |
| | | } |
| | | |
| | | public M setCreateTime(java.util.Date createTime) { |
| | | set("create_time", createTime); |
| | | return (M)this; |
| | | } |
| | | |
| | | public java.util.Date getCreateTime() { |
| | | return get("create_time"); |
| | | } |
| | | |
| | | public M setUpdateTime(java.util.Date updateTime) { |
| | | set("update_time", updateTime); |
| | | return (M)this; |
| | | } |
| | | |
| | | public java.util.Date getUpdateTime() { |
| | | return get("update_time"); |
| | | } |
| | | |
| | | public M setToFriend(Boolean toFriend) { |
| | | set("to_friend", toFriend); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getToFriend() { |
| | | return get("to_friend"); |
| | | } |
| | | |
| | | public M setToGroup(Boolean toGroup) { |
| | | set("to_group", toGroup); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getToGroup() { |
| | | return get("to_group"); |
| | | } |
| | | |
| | | public M setDefaultFriend(Boolean defaultFriend) { |
| | | set("default_friend", defaultFriend); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getDefaultFriend() { |
| | | return get("default_friend"); |
| | | } |
| | | |
| | | public M setDefaultGroup(Boolean defaultGroup) { |
| | | set("default_group", defaultGroup); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getDefaultGroup() { |
| | | return get("default_group"); |
| | | } |
| | | |
| | | public M setFromOut(Boolean fromOut) { |
| | | set("from_out", fromOut); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getFromOut() { |
| | | return get("from_out"); |
| | | } |
| | | |
| | | public M setEnable(Boolean enable) { |
| | | set("enable", enable); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getEnable() { |
| | | return get("enable"); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model.base; |
| | | |
| | | import com.jfinal.plugin.activerecord.IBean; |
| | | import com.jfinal.plugin.activerecord.Model; |
| | | |
| | | /** |
| | | * Generated by JFinal, do not modify this file. |
| | | */ |
| | | @SuppressWarnings({"serial", "unchecked"}) |
| | | public abstract class BaseWxRobKeyword<M extends BaseWxRobKeyword<M>> extends Model<M> implements IBean { |
| | | |
| | | public M setId(Long id) { |
| | | set("id", id); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return getLong("id"); |
| | | } |
| | | |
| | | public M setUniqueKey(String uniqueKey) { |
| | | set("unique_key", uniqueKey); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getUniqueKey() { |
| | | return getStr("unique_key"); |
| | | } |
| | | |
| | | public M setKeyData(String keyData) { |
| | | set("key_data", keyData); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getKeyData() { |
| | | return getStr("key_data"); |
| | | } |
| | | |
| | | public M setValueData(String valueData) { |
| | | set("value_data", valueData); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getValueData() { |
| | | return getStr("value_data"); |
| | | } |
| | | |
| | | public M setTypeData(String typeData) { |
| | | set("type_data", typeData); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getTypeData() { |
| | | return getStr("type_data"); |
| | | } |
| | | |
| | | public M setNickName(String nickName) { |
| | | set("nick_name", nickName); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getNickName() { |
| | | return getStr("nick_name"); |
| | | } |
| | | |
| | | public M setToGroup(Boolean toGroup) { |
| | | set("to_group", toGroup); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getToGroup() { |
| | | return get("to_group"); |
| | | } |
| | | |
| | | public M setEnable(Boolean enable) { |
| | | set("enable", enable); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getEnable() { |
| | | return get("enable"); |
| | | } |
| | | |
| | | public M setCreateTime(java.util.Date createTime) { |
| | | set("create_time", createTime); |
| | | return (M)this; |
| | | } |
| | | |
| | | public java.util.Date getCreateTime() { |
| | | return get("create_time"); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.model.base; |
| | | |
| | | import com.jfinal.plugin.activerecord.IBean; |
| | | import com.jfinal.plugin.activerecord.Model; |
| | | |
| | | /** |
| | | * Generated by JFinal, do not modify this file. |
| | | */ |
| | | @SuppressWarnings({"serial", "unchecked"}) |
| | | public abstract class BaseWxRobRelation<M extends BaseWxRobRelation<M>> extends Model<M> implements IBean { |
| | | |
| | | public M setId(Long id) { |
| | | set("id", id); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Long getId() { |
| | | return getLong("id"); |
| | | } |
| | | |
| | | public M setOutKey(String outKey) { |
| | | set("out_key", outKey); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getOutKey() { |
| | | return getStr("out_key"); |
| | | } |
| | | |
| | | public M setUniqueKey(String uniqueKey) { |
| | | set("unique_key", uniqueKey); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getUniqueKey() { |
| | | return getStr("unique_key"); |
| | | } |
| | | |
| | | public M setNickName(String nickName) { |
| | | set("nick_name", nickName); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getNickName() { |
| | | return getStr("nick_name"); |
| | | } |
| | | |
| | | public M setToGroup(Boolean toGroup) { |
| | | set("to_group", toGroup); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getToGroup() { |
| | | return get("to_group"); |
| | | } |
| | | |
| | | public M setEnable(Boolean enable) { |
| | | set("enable", enable); |
| | | return (M)this; |
| | | } |
| | | |
| | | public Boolean getEnable() { |
| | | return get("enable"); |
| | | } |
| | | |
| | | public M setWhiteList(String whiteList) { |
| | | set("white_list", whiteList); |
| | | return (M)this; |
| | | } |
| | | |
| | | public String getWhiteList() { |
| | | return getStr("white_list"); |
| | | } |
| | | |
| | | public M setCreateTime(java.util.Date createTime) { |
| | | set("create_time", createTime); |
| | | return (M)this; |
| | | } |
| | | |
| | | public java.util.Date getCreateTime() { |
| | | return get("create_time"); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.utils; |
| | | |
| | | import org.apache.commons.codec.binary.Base64; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/19 |
| | | */ |
| | | public class Base64Util { |
| | | |
| | | /** |
| | | * ç¼ç |
| | | * @param source |
| | | * @return |
| | | */ |
| | | public static String encode(String source){ |
| | | byte[] result = Base64.encodeBase64(source.getBytes()); |
| | | return result.toString(); |
| | | } |
| | | |
| | | /** |
| | | * è§£ç |
| | | * @param source |
| | | * @return |
| | | */ |
| | | public static String decode(String source){ |
| | | byte[] result = Base64.decodeBase64(source); |
| | | return result.toString(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.utils; |
| | | |
| | | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/11/5 |
| | | */ |
| | | public class IpUtil { |
| | | |
| | | /** |
| | | * è·åç¨æ·çå®IP(å¨å®é²æå¤å±ä»£çåºæ¯ä¸) |
| | | * @param request |
| | | * @return |
| | | */ |
| | | public static String getRealIp(HttpServletRequest request) { |
| | | String ip = request.getHeader("x-forwarded-for"); |
| | | if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){ |
| | | //夿¬¡åå代çå伿å¤ä¸ªipå¼ï¼ç¬¬ä¸ä¸ªipææ¯çå®ip |
| | | int index = ip.indexOf(","); |
| | | if(index != -1){ |
| | | return ip.substring(0,index); |
| | | } |
| | | } |
| | | ip = request.getHeader("X-Real-IP"); |
| | | if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){ |
| | | return ip; |
| | | } |
| | | return request.getRemoteAddr(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.utils; |
| | | |
| | | import java.util.LinkedHashMap; |
| | | |
| | | /** |
| | | * @author WesleyOne |
| | | * @create 2018/12/12 |
| | | */ |
| | | public class LRUCache<K,V> extends LinkedHashMap<K,V> { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | protected int maxElements; |
| | | |
| | | public LRUCache(int maxSize) |
| | | { |
| | | super(maxSize * 4 / 3 , 0.75F, true); |
| | | maxElements = maxSize; |
| | | } |
| | | |
| | | @Override |
| | | protected boolean removeEldestEntry(java.util.Map.Entry eldest) |
| | | { |
| | | return size() > maxElements; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.utils; |
| | | |
| | | |
| | | |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | |
| | | public class MD5Util { |
| | | |
| | | |
| | | private static String byteArrayToHexString(byte b[]) { |
| | | StringBuffer resultSb = new StringBuffer(); |
| | | for (int i = 0; i < b.length; i++){ |
| | | resultSb.append(byteToHexString(b[i])); |
| | | } |
| | | |
| | | return resultSb.toString(); |
| | | } |
| | | |
| | | private static String byteToHexString(byte b) { |
| | | int n = b; |
| | | if (n < 0){ |
| | | n += 256; |
| | | } |
| | | int d1 = n / 16; |
| | | int d2 = n % 16; |
| | | return hexDigits[d1] + hexDigits[d2]; |
| | | } |
| | | |
| | | public static String MD5Encode(String origin, String charsetname) { |
| | | String resultString = null; |
| | | try { |
| | | resultString = new String(origin); |
| | | MessageDigest md = MessageDigest.getInstance("MD5"); |
| | | if (charsetname == null || "".equals(charsetname)){ |
| | | resultString = byteArrayToHexString(md.digest(resultString.getBytes())); |
| | | } else{ |
| | | resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); |
| | | } |
| | | } catch (Exception exception) { |
| | | } |
| | | return resultString; |
| | | } |
| | | |
| | | private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; |
| | | |
| | | public static String MD5Encrypt(String str) { |
| | | String s = str; |
| | | if (s == null) { |
| | | return null; |
| | | } |
| | | String value = null; |
| | | MessageDigest md5 = null; |
| | | try { |
| | | md5 = MessageDigest.getInstance("MD5"); |
| | | } catch (NoSuchAlgorithmException ex) { |
| | | } |
| | | //sun.misc.BASE64Encoder baseEncoder = new sun.misc.BASE64Encoder(); |
| | | |
| | | return value; |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | System.out.println(MD5Encrypt("wxwobot")); |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.common.wechat.web.utils; |
| | | |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * |
| | | * @author internet |
| | | * @create 2018/12/17 |
| | | */ |
| | | public class UUIDShortUtil { |
| | | |
| | | private static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", |
| | | "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", |
| | | "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", |
| | | "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", |
| | | "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", |
| | | "W", "X", "Y", "Z" }; |
| | | |
| | | /** |
| | | * ç8ä½ |
| | | * @return |
| | | */ |
| | | public static String generateShortUuid() { |
| | | StringBuffer shortBuffer = new StringBuffer(); |
| | | String uuid = UUID.randomUUID().toString().replace("-", ""); |
| | | for (int i = 0; i < 8; i++) { |
| | | String str = uuid.substring(i * 4, i * 4 + 4); |
| | | int x = Integer.parseInt(str, 16); |
| | | shortBuffer.append(chars[x % 0x3E]); |
| | | } |
| | | return shortBuffer.toString(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | jdbcUrl = ${pro.jdbc.agent.url} |
| | | user = ${pro.jdbc.agent.username} |
| | | password = ${pro.jdbc.agent.password} |
| | | devMode = ${pro.devMode} |
| | | hotReloadDir = ${pro.hotreload.realpath} |
| | | download_path = ${pro.download.path} |
| | | log_path = ${log.file.path} |
¶Ô±ÈÐÂÎļþ |
| | |
| | | wxwobot = C9ah2BEPliU2EzPV/VAn9Q== |
¶Ô±ÈÐÂÎļþ |
| | |
| | | # é
ç½® undertow |
| | | |
| | | undertow.devMode=${pro.undertow.devMode} |
| | | undertow.host=${pro.domain.host} |
| | | undertow.port=${pro.domain.port} |
| | | undertow.contextPath=/ |
| | | |
| | | undertow.resourcePath=webapp, io.wxwobot.admin/src/main/webapp, src/main/webapp |
| | | |
| | | # å¼å¯ gzip å缩 |
| | | undertow.gzip.enable=true |
| | | # é
ç½®å缩级å«ï¼é»è®¤å¼ -1ã å¯é
ç½® 1 å° 9ã 1 æ¥ææå¿«å缩é度ï¼9 æ¥ææé«å缩ç |
| | | undertow.gzip.level=-1 |
| | | # 触åå缩çæå°å
容é¿åº¦ |
| | | undertow.gzip.minLength=1024 |
| | | |
| | | # session è¿ææ¶é´ï¼æ³¨æå使¯ç§ |
| | | undertow.session.timeout=1800 |
| | | # æ¯æ session çå è½½ï¼é¿å
ä¾èµäº session çç»å½å项ç®åå¤ç»å½ï¼é»è®¤å¼ä¸º trueãä»
ç¨äº devModeï¼ç产ç¯å¢æ å½±å |
| | | undertow.session.hotSwap=true |
| | | |
| | | # ä¸é¢ä¸¤è¡å½ä»¤çæå¯é¥åº |
| | | # keytool -genkeypair -validity 3650 -alias club -keyalg RSA -keystore club.jks |
| | | # keytool -importkeystore -srckeystore club.jks -destkeystore club.pfx -deststoretype PKCS12 |
| | | # çæè¿ç¨ä¸æç¤ºè¾å
¥ "ååä¸å§æ°" æ¶è¾å
¥ localhostãç产ç¯å¢ä»é¿éäºä¸è½½ tomcat ç±»åçå¯é¥åº |
| | | # |
| | | # æ´è¯¦ç»ç https/ssl é
ç½®è§ jfinal 宿¹ææ¡£ ï¼http://www.jfinal.com/doc/1-4 |
| | | # |
| | | # æ¯å¦å¼å¯ ssl |
| | | undertow.ssl.enable=false |
| | | # ssl çå¬ç«¯å£å·ï¼é¨ç½²ç¯å¢è®¾ç½®ä¸º 443 |
| | | undertow.ssl.port=443 |
| | | # å¯é¥åºç±»åï¼å»ºè®®ä½¿ç¨ PKCS12 |
| | | undertow.ssl.keyStoreType=PKCS12 |
| | | # å¯é¥åºæä»¶ |
| | | undertow.ssl.keyStore=demo.pfx |
| | | # å¯é¥åºå¯ç |
| | | undertow.ssl.keyStorePassword=111111 |
| | | |
| | | |
| | | # ssl å¼å¯æ¶ï¼æ¯å¦å¼å¯ http2ãæ£æµè¯¥é
ç½®æ¯å¦çæå¨ chrome å°åæ ä¸è¾å
¥: chrome://net-internals/#http2 |
| | | undertow.http2.enable=true |
| | | |
| | | |
| | | # ssl å¼å¯æ¶ï¼http è¯·æ±æ¯å¦éå®åå° https |
| | | # undertow.http.toHttps=false |
| | | # ssl å¼å¯æ¶ï¼æ¯å¦å
³é http |
| | | # undertow.http.disable=false |
| | | |
| | | |
| | | |
| | |
| | | <module>ruoyi-demo</module> |
| | | <module>ruoyi-fusion</module> |
| | | <module>ruoyi-system</module> |
| | | <module>ruoyi-live</module> |
| | | <module>ruoyi-knowledge</module> |
| | | </modules> |
| | | |
| | | </project> |
| | |
| | | <artifactId>ruoyi-fusion</artifactId> |
| | | |
| | | <description> |
| | | AIç»ç» |
| | | 䏿¹APIæ¥å
¥ |
| | | </description> |
| | | |
| | | <properties> |
| | |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-knowledge</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.knowledge.service.EmbeddingService; |
| | | import org.ruoyi.system.domain.bo.ChatMessageBo; |
| | | import org.ruoyi.system.domain.request.translation.TranslationRequest; |
| | | import org.ruoyi.system.domain.vo.ChatMessageVo; |
| | | import org.ruoyi.system.service.IChatMessageService; |
| | | import org.ruoyi.system.service.ISseService; |
| | |
| | | |
| | | private final IChatMessageService chatMessageService; |
| | | |
| | | private final EmbeddingService embeddingService; |
| | | /** |
| | | * è天æ¥å£ |
| | | */ |
| | | @PostMapping("/send") |
| | | @ResponseBody |
| | | public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) { |
| | | if (chatRequest.getModel().startsWith("ollama")) { |
| | | return ISseService.ollamaChat(chatRequest); |
| | | } |
| | | return ISseService.sseChat(chatRequest,request); |
| | | } |
| | | |
| | |
| | | return ISseService.textToSpeed(textToSpeech); |
| | | } |
| | | |
| | | /** |
| | | * ææ¬ç¿»è¯ |
| | | * |
| | | * @param |
| | | */ |
| | | @PostMapping("/translation") |
| | | @ResponseBody |
| | | public String translation(@RequestBody TranslationRequest translationRequest) { |
| | | return ISseService.translation(translationRequest); |
| | | } |
| | | |
| | | @PostMapping("/dall3") |
| | | @ResponseBody |
| | | public R<List<Item>> dall3(@RequestBody @Valid Dall3Request request) { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.fusion.controller; |
| | | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.system.domain.vo.cover.CoverParamVo; |
| | | import org.ruoyi.system.domain.vo.cover.CoverVo; |
| | | import org.ruoyi.system.domain.vo.cover.CoverCallbackVo; |
| | | import org.ruoyi.system.domain.vo.cover.MusicVo; |
| | | import org.ruoyi.system.service.ICoverService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç»å£°ç¾é³-ç¿»å± |
| | | * |
| | | * @author NSL |
| | | * @since 2024-12-25 |
| | | */ |
| | | @Api(tags = "ææ²ç¿»å±") |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/cover") |
| | | public class CoverController extends BaseController { |
| | | |
| | | private final ICoverService coverService; |
| | | |
| | | @ApiOperation(value = "æ¥æ¾ææ²") |
| | | @GetMapping("/searchMusic") |
| | | public R<List<MusicVo>> searchMusic(String musicName) { |
| | | return R.ok(coverService.searchMusic(musicName)); |
| | | } |
| | | |
| | | @ApiOperation(value = "ç¿»å±ææ²") |
| | | @PostMapping("/saveCoverTask") |
| | | public R<Void> saveCoverTask(@RequestBody CoverParamVo coverParamVo) { |
| | | coverService.saveCoverTask(coverParamVo); |
| | | return R.ok("ç¿»å±ææ²å¤çä¸è¯·çå¾
10åé-30åéï¼ç¿»å±ç»æè¯·å°ç¿»å±è®°å½ä¸æ¥è¯¢ï¼"); |
| | | } |
| | | |
| | | @ApiOperation(value = "æ¥è¯¢ç¿»å±è®°å½") |
| | | @PostMapping("/searchCoverRecord") |
| | | public R<TableDataInfo<CoverVo>> searchCoverRecord(@RequestBody PageQuery pageQuery) { |
| | | return R.ok(coverService.searchCoverRecord(pageQuery)); |
| | | } |
| | | |
| | | @ApiOperation(value = "ç¿»å±åè°æ¥å£") |
| | | @PostMapping("/callback") |
| | | public R<Void> callback(@RequestBody CoverCallbackVo coverCallbackVo) { |
| | | coverService.callback(coverCallbackVo); |
| | | return R.ok(); |
| | | } |
| | | } |
| | |
| | | @PostMapping("/generations/") |
| | | public String generateVideo(@RequestBody GenerateLuma generateLuma) { |
| | | OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("luma"); |
| | | |
| | | chatCostService.taskDeduct("luma", "æçè§é¢", NumberUtils.toDouble(okHttpConfig.getGenerate(), 0.3)); |
| | | String generateJson = JSONUtil.toJsonStr(generateLuma); |
| | | String url = "luma/generations"; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.fusion.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.system.domain.vo.ppt.*; |
| | | import org.ruoyi.system.service.IPptService; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; |
| | | |
| | | /** |
| | | * AI_PPT |
| | | * |
| | | * @author NSL |
| | | * @since 2024-12-30 |
| | | */ |
| | | @Api(tags = "AI-PPT") |
| | | @RequiredArgsConstructor |
| | | @RestController |
| | | @RequestMapping("/ppt") |
| | | public class PptController extends BaseController { |
| | | |
| | | private final IPptService pptService; |
| | | |
| | | @ApiOperation(value = "è·åAPI Token") |
| | | @GetMapping("/getApiToken") |
| | | public R<String> getApiToken() { |
| | | return R.ok(pptService.getApiToken()); |
| | | } |
| | | |
| | | @ApiOperation(value = "忥æµå¼çæ PPT") |
| | | @PostMapping("/syncStreamGeneratePpt") |
| | | public R<Void> syncStreamGeneratePpt(String title) { |
| | | pptService.syncStreamGeneratePpt(title); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ApiOperation(value = "æ¥è¯¢ææPPTå表") |
| | | @PostMapping("/selectPptList") |
| | | public R<Void> selectPptList(@RequestBody PptAllQueryDto pptQueryVo) { |
| | | pptService.selectPptList(pptQueryVo); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ApiOperation(value = "çæå¤§çº²") |
| | | @PostMapping(value = "/generateOutline", produces = {MediaType.TEXT_EVENT_STREAM_VALUE}) |
| | | public SseEmitter generateOutline(@RequestBody PptGenerateOutlineDto generateOutlineDto) { |
| | | return pptService.generateOutline(generateOutlineDto); |
| | | } |
| | | |
| | | @ApiOperation(value = "çæå¤§çº²å
容") |
| | | @PostMapping(value = "/generateContent", produces = {MediaType.TEXT_EVENT_STREAM_VALUE}) |
| | | public SseEmitter generateOutline(@RequestBody PptGenerateContentDto generateContentDto) { |
| | | return pptService.generateContent(generateContentDto); |
| | | } |
| | | |
| | | @ApiOperation(value = "å页æ¥è¯¢ PPT 模æ¿") |
| | | @PostMapping("/getTemplates") |
| | | public R<JSONObject> getPptTemplates(@RequestBody PptTemplateQueryDto pptQueryVo) { |
| | | return R.ok(pptService.getPptTemplates(pptQueryVo)); |
| | | } |
| | | |
| | | @ApiOperation(value = "çæ PPT") |
| | | @PostMapping("/generatePptx") |
| | | public R<JSONObject> generatePptx(@RequestBody PptGeneratePptxDto pptQueryVo) { |
| | | return R.ok(pptService.generatePptx(pptQueryVo)); |
| | | } |
| | | |
| | | @ApiOperation(value = "çæPPTæååè°æ¥å£") |
| | | @PostMapping("/successCallback") |
| | | public R<Void> successCallback() { |
| | | pptService.successCallback(); |
| | | return R.ok(); |
| | | } |
| | | } |
| | |
| | | package org.ruoyi.fusion.controller; |
| | | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.domain.R; |
| | | import org.ruoyi.common.core.validate.EditGroup; |
| | | import org.ruoyi.common.log.annotation.Log; |
| | | import org.ruoyi.common.log.enums.BusinessType; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.common.web.core.BaseController; |
| | | import org.ruoyi.system.domain.bo.VoiceRoleBo; |
| | | import org.ruoyi.system.domain.vo.VoiceRoleVo; |
| | | import org.ruoyi.system.request.RoleListDto; |
| | | import org.ruoyi.system.request.RoleRequest; |
| | | import org.ruoyi.system.request.SimpleGenerateRequest; |
| | | import org.ruoyi.system.response.SimpleGenerateDataResponse; |
| | | import org.ruoyi.system.response.rolelist.RoleListVO; |
| | | import org.ruoyi.system.service.IVoiceRoleService; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.ruoyi.system.response.rolelist.ChatAppStoreVO; |
| | | import org.ruoyi.system.service.IChatAppStoreService; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * é
é³è§è² |
| | | * åºç¨å¸åº |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-03-19 |
| | |
| | | @RequestMapping("/system/voice") |
| | | public class VoiceController extends BaseController { |
| | | |
| | | private final IVoiceRoleService voiceRoleService; |
| | | |
| | | /** |
| | | * æ¥è¯¢é
é³è§è²å表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public List<VoiceRoleVo> list(VoiceRoleBo bo) { |
| | | if(LoginHelper.getUserId() == null){ |
| | | return new ArrayList<>(); |
| | | } |
| | | bo.setCreateBy(LoginHelper.getUserId()); |
| | | return voiceRoleService.queryList(bo); |
| | | } |
| | | |
| | | /** |
| | | * è·åé
é³è§è²è¯¦ç»ä¿¡æ¯ |
| | | * |
| | | * @param id ä¸»é® |
| | | */ |
| | | @SaCheckPermission("system:role:query") |
| | | @GetMapping("/{id}") |
| | | public R<VoiceRoleVo> getInfo(@NotNull(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long id) { |
| | | return R.ok(voiceRoleService.queryById(id)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * æ°å¢é
é³è§è² |
| | | */ |
| | | @Log(title = "é
é³è§è²", businessType = BusinessType.INSERT) |
| | | @PostMapping("/add") |
| | | public R<Void> add(@RequestBody RoleRequest roleRequest) { |
| | | return toAjax(voiceRoleService.insertByBo(roleRequest)); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹é
é³è§è² |
| | | */ |
| | | @SaCheckPermission("system:role:edit") |
| | | @Log(title = "é
é³è§è²", businessType = BusinessType.UPDATE) |
| | | @PutMapping() |
| | | public R<Void> edit(@Validated(EditGroup.class) @RequestBody VoiceRoleBo bo) { |
| | | return toAjax(voiceRoleService.updateByBo(bo)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤é
é³è§è² |
| | | * |
| | | * @param ids 主é®ä¸² |
| | | */ |
| | | @Log(title = "é
é³è§è²", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public R<Void> remove(@NotEmpty(message = "主é®ä¸è½ä¸ºç©º") |
| | | @PathVariable Long[] ids) { |
| | | return toAjax(voiceRoleService.deleteWithValidByIds(List.of(ids), true)); |
| | | } |
| | | private final IChatAppStoreService voiceRoleService; |
| | | |
| | | /** |
| | | * 宿¶è¯é³çæ |
| | |
| | | * è§è²å¸åº |
| | | */ |
| | | @GetMapping("/roleList") |
| | | public R<List<RoleListVO>> roleList() { |
| | | public R<List<ChatAppStoreVO>> roleList() { |
| | | return R.ok(voiceRoleService.roleList()); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <artifactId>ruoyi-knowledge</artifactId> |
| | | |
| | | <properties> |
| | | <maven.compiler.source>17</maven.compiler.source> |
| | | <maven.compiler.target>17</maven.compiler.target> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-freemarker</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-validation</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-aop</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.webjars</groupId> |
| | | <artifactId>webjars-locator-core</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.webjars</groupId> |
| | | <artifactId>sockjs-client</artifactId> |
| | | <version>1.0.2</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.webjars</groupId> |
| | | <artifactId>bootstrap</artifactId> |
| | | <version>3.3.7</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.webjars</groupId> |
| | | <artifactId>jquery</artifactId> |
| | | <version>3.1.1-1</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | <version>3.0.2</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | <version>3.5.3</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>5.8.10</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.xiaoymin</groupId> |
| | | <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-devtools</artifactId> |
| | | <scope>runtime</scope> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.mysql</groupId> |
| | | <artifactId>mysql-connector-j</artifactId> |
| | | <scope>runtime</scope> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.projectreactor.netty</groupId> |
| | | <artifactId>reactor-netty-core</artifactId> |
| | | <version>1.1.16</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.projectreactor.netty</groupId> |
| | | <artifactId>reactor-netty-http</artifactId> |
| | | <version>1.1.16</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-configuration-processor</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.theokanning.openai-gpt3-java</groupId> |
| | | <artifactId>api</artifactId> |
| | | <version>0.18.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.theokanning.openai-gpt3-java</groupId> |
| | | <artifactId>client</artifactId> |
| | | <version>0.18.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.theokanning.openai-gpt3-java</groupId> |
| | | <artifactId>service</artifactId> |
| | | <version>0.18.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-test</artifactId> |
| | | <scope>test</scope> |
| | | </dependency> |
| | | |
| | | <!-- é¿éJSONè§£æå¨ --> |
| | | <dependency> |
| | | <groupId>com.alibaba.fastjson2</groupId> |
| | | <artifactId>fastjson2</artifactId> |
| | | <version>2.0.24</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.knuddels</groupId> |
| | | <artifactId>jtokkit</artifactId> |
| | | <version>0.5.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.weaviate</groupId> |
| | | <artifactId>client</artifactId> |
| | | <version>4.0.0</version> <!-- Check latest version --> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi</artifactId> |
| | | <version>3.8</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi-ooxml</artifactId> |
| | | <version>3.8</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.poi</groupId> |
| | | <artifactId>poi-ooxml-schemas</artifactId> |
| | | <version>3.8</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.apache.pdfbox</groupId> |
| | | <artifactId>pdfbox</artifactId> |
| | | <version>2.0.27</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.squareup.retrofit2</groupId> |
| | | <artifactId>converter-jackson</artifactId> |
| | | <version>2.9.0</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.milvus</groupId> |
| | | <artifactId>milvus-sdk-java</artifactId> |
| | | <version>2.3.2</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.pagehelper</groupId> |
| | | <artifactId>pagehelper-spring-boot-starter</artifactId> |
| | | <version>1.4.6</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.belerweb</groupId> |
| | | <artifactId>pinyin4j</artifactId> |
| | | <version>2.5.1</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-system</artifactId> |
| | | </dependency> |
| | | |
| | | |
| | | </dependencies> |
| | | |
| | | |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.knowledge.chain.split.TextSplitter; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class CodeFileLoader implements ResourceLoader{ |
| | | private final TextSplitter textSplitter; |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | StringBuffer stringBuffer = new StringBuffer(); |
| | | try (InputStreamReader reader = new InputStreamReader(inputStream); |
| | | BufferedReader bufferedReader = new BufferedReader(reader)){ |
| | | String line; |
| | | while ((line = bufferedReader.readLine()) != null) { |
| | | stringBuffer.append(line).append("\n"); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return stringBuffer.toString(); |
| | | } |
| | | @Override |
| | | public List<String> getChunkList(String content){ |
| | | return textSplitter.split(content); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | public class CsvFileLoader implements ResourceLoader{ |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | public class FolderLoader implements ResourceLoader{ |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | public class GithubLoader implements ResourceLoader{ |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | public class JsonFileLoader implements ResourceLoader{ |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.knowledge.chain.split.TextSplitter; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class MarkDownFileLoader implements ResourceLoader{ |
| | | private final TextSplitter textSplitter; |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | StringBuffer stringBuffer = new StringBuffer(); |
| | | try (InputStreamReader reader = new InputStreamReader(inputStream); |
| | | BufferedReader bufferedReader = new BufferedReader(reader)){ |
| | | String line; |
| | | while ((line = bufferedReader.readLine()) != null) { |
| | | stringBuffer.append(line).append("\n"); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return stringBuffer.toString(); |
| | | } |
| | | @Override |
| | | public List<String> getChunkList(String content){ |
| | | return textSplitter.split(content); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.pdfbox.pdmodel.PDDocument; |
| | | import org.apache.pdfbox.text.PDFTextStripper; |
| | | import org.ruoyi.knowledge.chain.split.TextSplitter; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | public class PdfFileLoader implements ResourceLoader{ |
| | | private final TextSplitter characterTextSplitter; |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | PDDocument document = null; |
| | | try { |
| | | document = PDDocument.load(inputStream); |
| | | PDFTextStripper textStripper = new PDFTextStripper(); |
| | | String content = textStripper.getText(document); |
| | | return content; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return characterTextSplitter.split(content); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * èµæºè½½å
¥ |
| | | */ |
| | | public interface ResourceLoader { |
| | | String getContent(InputStream inputStream); |
| | | List<String> getChunkList(String content); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.ruoyi.knowledge.chain.split.CharacterTextSplitter; |
| | | import org.ruoyi.knowledge.chain.split.CodeTextSplitter; |
| | | import org.ruoyi.knowledge.chain.split.MarkdownTextSplitter; |
| | | import org.ruoyi.knowledge.chain.split.TokenTextSplitter; |
| | | import org.ruoyi.knowledge.constant.FileType; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @AllArgsConstructor |
| | | @Component |
| | | public class ResourceLoaderFactory { |
| | | private final CharacterTextSplitter characterTextSplitter; |
| | | private final CodeTextSplitter codeTextSplitter; |
| | | private final MarkdownTextSplitter markdownTextSplitter; |
| | | private final TokenTextSplitter tokenTextSplitter; |
| | | public ResourceLoader getLoaderByFileType(String fileType){ |
| | | if (FileType.isTextFile(fileType)){ |
| | | return new TextFileLoader(characterTextSplitter); |
| | | } else if (FileType.isWord(fileType)) { |
| | | return new WordLoader(characterTextSplitter); |
| | | } else if (FileType.isPdf(fileType)) { |
| | | return new PdfFileLoader(characterTextSplitter); |
| | | } else if (FileType.isMdFile(fileType)) { |
| | | return new MarkDownFileLoader(markdownTextSplitter); |
| | | }else if (FileType.isCodeFile(fileType)) { |
| | | return new CodeFileLoader(codeTextSplitter); |
| | | }else { |
| | | return new TextFileLoader(characterTextSplitter); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.knowledge.chain.split.TextSplitter; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class TextFileLoader implements ResourceLoader{ |
| | | private final TextSplitter textSplitter; |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | StringBuffer stringBuffer = new StringBuffer(); |
| | | try (InputStreamReader reader = new InputStreamReader(inputStream, "UTF-8"); |
| | | BufferedReader bufferedReader = new BufferedReader(reader)){ |
| | | String line; |
| | | while ((line = bufferedReader.readLine()) != null) { |
| | | stringBuffer.append(line).append("\n"); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return stringBuffer.toString(); |
| | | } |
| | | @Override |
| | | public List<String> getChunkList(String content){ |
| | | return textSplitter.split(content); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.loader; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.poi.xwpf.extractor.XWPFWordExtractor; |
| | | import org.apache.poi.xwpf.usermodel.XWPFDocument; |
| | | import org.ruoyi.knowledge.chain.split.TextSplitter; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class WordLoader implements ResourceLoader{ |
| | | private final TextSplitter textSplitter; |
| | | @Override |
| | | public String getContent(InputStream inputStream) { |
| | | XWPFDocument document = null; |
| | | try { |
| | | document = new XWPFDocument(inputStream); |
| | | XWPFWordExtractor extractor = new XWPFWordExtractor(document); |
| | | String content = extractor.getText(); |
| | | return content; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<String> getChunkList(String content) { |
| | | return textSplitter.split(content); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.retrieve; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Data |
| | | @Component |
| | | public class PromptRetrieverProperties { |
| | | /** |
| | | * ä»ç¥è¯åºä¸æ£ç´¢çæ¡æ°ï¼limits åºå¤§äº num |
| | | */ |
| | | @Value("${chain.limits}") |
| | | private int limits; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.annotation.Primary; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | @Primary |
| | | public class CharacterTextSplitter implements TextSplitter{ |
| | | private final SplitterProperties splitterProperties; |
| | | @Override |
| | | public List<String> split(String content) { |
| | | List<String> chunkList = new ArrayList<>(); |
| | | if (content.contains(splitterProperties.getEndspliter())){ |
| | | // æèªå®ä¹åé符åå |
| | | String[] chunks = content.split(splitterProperties.getEndspliter()); |
| | | chunkList.addAll(Arrays.asList(chunks)); |
| | | }else { |
| | | int indexMin = 0; |
| | | int len = content.length(); |
| | | int i = 0; |
| | | int right = 0; |
| | | while (true) { |
| | | if (len > right ){ |
| | | int begin = i*splitterProperties.getSize() - splitterProperties.getOverlay(); |
| | | if (begin < indexMin){ |
| | | begin = indexMin; |
| | | } |
| | | int end = splitterProperties.getSize()*(i+1) + splitterProperties.getOverlay(); |
| | | if (end > len){ |
| | | end = len; |
| | | } |
| | | String chunk = content.substring(begin,end); |
| | | chunkList.add(chunk); |
| | | i++; |
| | | right = right + splitterProperties.getSize(); |
| | | }else { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return chunkList; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class CodeTextSplitter implements TextSplitter{ |
| | | @Override |
| | | public List<String> split(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class MarkdownTextSplitter implements TextSplitter{ |
| | | @Override |
| | | public List<String> split(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Data |
| | | @Component |
| | | @ConfigurationProperties(prefix = "chain.split.chunk") |
| | | public class SplitterProperties { |
| | | /** |
| | | * åæ®µæ è¯ç¬¦ |
| | | */ |
| | | private String endspliter; |
| | | |
| | | /** |
| | | * æé®å段æ è¯ç¬¦ |
| | | */ |
| | | private String qaspliter; |
| | | |
| | | /** |
| | | * ååææ¬å¤§å° |
| | | */ |
| | | private int size; |
| | | |
| | | /** |
| | | * ç¸é»åä¹é´éå çå符æ°(é¿å
è¾¹çä¿¡æ¯ä¸¢å¤±) |
| | | */ |
| | | private int overlay; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ææ¬åå |
| | | */ |
| | | public interface TextSplitter { |
| | | |
| | | List<String> split(String content); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.split; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @AllArgsConstructor |
| | | @Slf4j |
| | | public class TokenTextSplitter implements TextSplitter{ |
| | | @Override |
| | | public List<String> split(String content) { |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorizer; |
| | | |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.chat.config.ChatConfig; |
| | | import org.ruoyi.common.chat.entity.embeddings.Embedding; |
| | | |
| | | import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse; |
| | | import org.ruoyi.common.chat.openai.OpenAiStreamClient; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class OpenAiVectorization implements Vectorization { |
| | | |
| | | @Value("${chain.vector.model}") |
| | | private String embeddingModel; |
| | | |
| | | @Getter |
| | | private OpenAiStreamClient openAiStreamClient; |
| | | |
| | | private final ChatConfig chatConfig; |
| | | |
| | | @Override |
| | | public List<List<Double>> batchVectorization(List<String> chunkList) { |
| | | openAiStreamClient = chatConfig.getOpenAiStreamClient(); |
| | | |
| | | Embedding embedding = Embedding.builder() |
| | | .input(chunkList) |
| | | .model(embeddingModel) |
| | | .build(); |
| | | EmbeddingResponse embeddings = openAiStreamClient.embeddings(embedding); |
| | | List<List<Double>> vectorList = new ArrayList<>(); |
| | | embeddings.getData().forEach(data -> { |
| | | List<BigDecimal> vector = data.getEmbedding(); |
| | | List<Double> doubleVector = new ArrayList<>(); |
| | | for (BigDecimal bd : vector) { |
| | | doubleVector.add(bd.doubleValue()); |
| | | } |
| | | vectorList.add(doubleVector); |
| | | }); |
| | | return vectorList; |
| | | } |
| | | |
| | | @Override |
| | | public List<Double> singleVectorization(String chunk) { |
| | | List<String> chunkList = new ArrayList<>(); |
| | | chunkList.add(chunk); |
| | | List<List<Double>> vectorList = batchVectorization(chunkList); |
| | | return vectorList.get(0); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorizer; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åéå |
| | | */ |
| | | public interface Vectorization { |
| | | List<List<Double>> batchVectorization(List<String> chunkList); |
| | | List<Double> singleVectorization(String chunk); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorizer; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * ææ¬åéå |
| | | * @author huangkh |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class VectorizationFactory { |
| | | |
| | | private final OpenAiVectorization openAiVectorization; |
| | | |
| | | public VectorizationFactory(OpenAiVectorization openAiVectorization) { |
| | | this.openAiVectorization = openAiVectorization; |
| | | } |
| | | |
| | | public Vectorization getEmbedding(){ |
| | | return openAiVectorization; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorizer; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.annotation.Primary; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Component |
| | | @Slf4j |
| | | @Primary |
| | | @AllArgsConstructor |
| | | public class VectorizationWrapper implements Vectorization{ |
| | | |
| | | private final VectorizationFactory vectorizationFactory; |
| | | @Override |
| | | public List<List<Double>> batchVectorization(List<String> chunkList) { |
| | | Vectorization embedding = vectorizationFactory.getEmbedding(); |
| | | return embedding.batchVectorization(chunkList); |
| | | } |
| | | |
| | | @Override |
| | | public List<Double> singleVectorization(String chunk) { |
| | | Vectorization embedding = vectorizationFactory.getEmbedding(); |
| | | return embedding.singleVectorization(chunk); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorstore; |
| | | |
| | | import io.milvus.client.MilvusServiceClient; |
| | | import io.milvus.grpc.DataType; |
| | | import io.milvus.grpc.SearchResults; |
| | | import io.milvus.param.ConnectParam; |
| | | import io.milvus.param.IndexType; |
| | | import io.milvus.param.MetricType; |
| | | import io.milvus.param.R; |
| | | import io.milvus.param.collection.CreateCollectionParam; |
| | | import io.milvus.param.collection.DropCollectionParam; |
| | | import io.milvus.param.collection.FieldType; |
| | | import io.milvus.param.collection.LoadCollectionParam; |
| | | import io.milvus.param.dml.DeleteParam; |
| | | import io.milvus.param.dml.InsertParam; |
| | | import io.milvus.param.dml.SearchParam; |
| | | import io.milvus.param.index.CreateIndexParam; |
| | | import io.milvus.param.partition.CreatePartitionParam; |
| | | import io.milvus.response.QueryResultsWrapper; |
| | | import io.milvus.response.SearchResultsWrapper; |
| | | import jakarta.annotation.PostConstruct; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | public class MilvusVectorStore implements VectorStore{ |
| | | |
| | | |
| | | @Value("${chain.vector.store.milvus.host}") |
| | | private String milvusHost; |
| | | @Value("${chain.vector.store.milvus.port}") |
| | | private Integer milvausPort; |
| | | |
| | | @Value("${chain.vector.store.milvus.dimension}") |
| | | private Integer dimension; |
| | | |
| | | @Value("${chain.vector.store.milvus.collection}") |
| | | private String collectionName; |
| | | |
| | | private MilvusServiceClient milvusServiceClient; |
| | | |
| | | @PostConstruct |
| | | public void init(){ |
| | | milvusServiceClient = new MilvusServiceClient( |
| | | ConnectParam.newBuilder() |
| | | .withHost(milvusHost) |
| | | .withPort(milvausPort) |
| | | .withDatabaseName("default") |
| | | .build() |
| | | ); |
| | | } |
| | | |
| | | private void createSchema(String kid) { |
| | | FieldType primaryField = FieldType.newBuilder() |
| | | .withName("row_id") |
| | | .withDataType(DataType.Int64) |
| | | .withPrimaryKey(true) |
| | | .withAutoID(true) |
| | | .build(); |
| | | FieldType contentField = FieldType.newBuilder() |
| | | .withName("content") |
| | | .withDataType(DataType.VarChar) |
| | | .withMaxLength(1000) |
| | | .build(); |
| | | FieldType kidField = FieldType.newBuilder() |
| | | .withName("kid") |
| | | .withDataType(DataType.VarChar) |
| | | .withMaxLength(20) |
| | | .build(); |
| | | FieldType docIdField = FieldType.newBuilder() |
| | | .withName("docId") |
| | | .withDataType(DataType.VarChar) |
| | | .withMaxLength(20) |
| | | .build(); |
| | | FieldType fidField = FieldType.newBuilder() |
| | | .withName("fid") |
| | | .withDataType(DataType.VarChar) |
| | | .withMaxLength(20) |
| | | .build(); |
| | | FieldType vectorField = FieldType.newBuilder() |
| | | .withName("fv") |
| | | .withDataType(DataType.FloatVector) |
| | | .withDimension(dimension) |
| | | .build(); |
| | | CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withDescription("local knowledge") |
| | | .addFieldType(primaryField) |
| | | .addFieldType(contentField) |
| | | .addFieldType(kidField) |
| | | .addFieldType(docIdField) |
| | | .addFieldType(fidField) |
| | | .addFieldType(vectorField) |
| | | .build(); |
| | | milvusServiceClient.createCollection(createCollectionReq); |
| | | |
| | | // å建åéçç´¢å¼ |
| | | IndexType INDEX_TYPE = IndexType.IVF_FLAT; |
| | | String INDEX_PARAM = "{\"nlist\":1024}"; |
| | | milvusServiceClient.createIndex( |
| | | CreateIndexParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withFieldName("fv") |
| | | .withIndexType(INDEX_TYPE) |
| | | .withMetricType(MetricType.IP) |
| | | .withExtraParam(INDEX_PARAM) |
| | | .withSyncMode(Boolean.FALSE) |
| | | .build() |
| | | ); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void newSchema(String kid) { |
| | | createSchema(kid); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKidAndFid(String kid, String fid) { |
| | | milvusServiceClient.delete( |
| | | DeleteParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withExpr("fid == " + fid) |
| | | .build() |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList) { |
| | | |
| | | if (StringUtils.isNotBlank(docId)){ |
| | | milvusServiceClient.createPartition( |
| | | CreatePartitionParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withPartitionName(docId) |
| | | .build() |
| | | ); |
| | | } |
| | | |
| | | List<List<Float>> vectorFloatList = new ArrayList<>(); |
| | | List<String> kidList = new ArrayList<>(); |
| | | List<String> docIdList = new ArrayList<>(); |
| | | for (int i = 0; i < chunkList.size(); i++) { |
| | | List<Double> vector = vectorList.get(i); |
| | | List<Float> vfList = new ArrayList<>(); |
| | | for (int j = 0; j < vector.size(); j++) { |
| | | Double value = vector.get(j); |
| | | vfList.add(value.floatValue()); |
| | | } |
| | | vectorFloatList.add(vfList); |
| | | kidList.add(kid); |
| | | docIdList.add(docId); |
| | | } |
| | | List<InsertParam.Field> fields = new ArrayList<>(); |
| | | fields.add(new InsertParam.Field("content", chunkList)); |
| | | fields.add(new InsertParam.Field("kid", kidList)); |
| | | fields.add(new InsertParam.Field("docId", docIdList)); |
| | | fields.add(new InsertParam.Field("fid", fidList)); |
| | | fields.add(new InsertParam.Field("fv", vectorFloatList)); |
| | | |
| | | InsertParam insertParam = InsertParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withPartitionName(docId) |
| | | .withFields(fields) |
| | | .build(); |
| | | milvusServiceClient.insert(insertParam); |
| | | // milvuså¨å°æ°æ®è£
è½½å°å
ååæè½è¿è¡åéè®¡ç® |
| | | milvusServiceClient.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(collectionName + kid).build()); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void removeByDocId(String kid, String docId) { |
| | | milvusServiceClient.delete( |
| | | DeleteParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withExpr("1 == 1") |
| | | .withPartitionName(docId) |
| | | .build() |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKid(String kid) { |
| | | milvusServiceClient.dropCollection( |
| | | DropCollectionParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .build() |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public List<String> nearest(List<Double> queryVector, String kid) { |
| | | List<String> search_output_fields = Arrays.asList("content","fv"); |
| | | List<Float> fv = new ArrayList<>(); |
| | | for (int i = 0; i < queryVector.size(); i++) { |
| | | fv.add(queryVector.get(i).floatValue()); |
| | | } |
| | | List<List<Float>> vectors = new ArrayList<>(); |
| | | vectors.add(fv); |
| | | String search_param = "{\"nprobe\":10, \"offset\":0}"; |
| | | SearchParam searchParam = SearchParam.newBuilder() |
| | | .withCollectionName(collectionName + kid) |
| | | .withMetricType(MetricType.IP) |
| | | .withOutFields(search_output_fields) |
| | | .withTopK(10) |
| | | .withVectors(vectors) |
| | | .withVectorFieldName("fv") |
| | | .withParams(search_param) |
| | | .build(); |
| | | R<SearchResults> respSearch = milvusServiceClient.search(searchParam); |
| | | SearchResultsWrapper wrapperSearch = new SearchResultsWrapper(respSearch.getData().getResults()); |
| | | List<QueryResultsWrapper.RowRecord> rowRecords = wrapperSearch.getRowRecords(); |
| | | |
| | | List<String> resultList = new ArrayList<>(); |
| | | if (resultList!=null && resultList.size() > 0){ |
| | | for (int i = 0; i < rowRecords.size(); i++) { |
| | | String content = rowRecords.get(i).get("content").toString(); |
| | | resultList.add(content); |
| | | } |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | /** |
| | | * milvus 䏿¯æéè¿ææ¬æ£ç´¢ç¸ä¼¼æ§ |
| | | * @param query |
| | | * @param kid |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<String> nearest(String query, String kid) { |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorstore; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åéåå¨ |
| | | */ |
| | | public interface VectorStore { |
| | | void storeEmbeddings(List<String> chunkList,List<List<Double>> vectorList, String kid, String docId,List<String> fidList); |
| | | void removeByDocId(String kid,String docId); |
| | | void removeByKid(String kid); |
| | | List<String> nearest(List<Double> queryVector,String kid); |
| | | List<String> nearest(String query,String kid); |
| | | |
| | | void newSchema(String kid); |
| | | |
| | | void removeByKidAndFid(String kid, String fid); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorstore; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | @Slf4j |
| | | public class VectorStoreFactory { |
| | | |
| | | @Value("${chain.vector.store.type}") |
| | | private String type; |
| | | |
| | | private final WeaviateVectorStore weaviateVectorStore; |
| | | |
| | | private final MilvusVectorStore milvusVectorStore; |
| | | |
| | | public VectorStoreFactory(WeaviateVectorStore weaviateVectorStore, MilvusVectorStore milvusVectorStore) { |
| | | this.weaviateVectorStore = weaviateVectorStore; |
| | | this.milvusVectorStore = milvusVectorStore; |
| | | } |
| | | |
| | | public VectorStore getVectorStore(){ |
| | | if ("weaviate".equals(type)){ |
| | | return weaviateVectorStore; |
| | | }else if ("milvus".equals(type)){ |
| | | return milvusVectorStore; |
| | | } |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorstore; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.annotation.Primary; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | @Primary |
| | | @AllArgsConstructor |
| | | public class VectorStoreWrapper implements VectorStore{ |
| | | |
| | | private final VectorStoreFactory vectorStoreFactory; |
| | | @Override |
| | | public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | vectorStore.storeEmbeddings(chunkList, vectorList, kid, docId, fidList); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByDocId(String kid, String docId) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | vectorStore.removeByDocId(kid,docId); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKid(String kid) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | vectorStore.removeByKid(kid); |
| | | } |
| | | |
| | | @Override |
| | | public List<String> nearest(List<Double> queryVector, String kid) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | return vectorStore.nearest(queryVector,kid); |
| | | } |
| | | |
| | | @Override |
| | | public List<String> nearest(String query, String kid) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | return vectorStore.nearest(query, kid); |
| | | } |
| | | |
| | | @Override |
| | | public void newSchema(String kid) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | vectorStore.newSchema(kid); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKidAndFid(String kid, String fid) { |
| | | VectorStore vectorStore = vectorStoreFactory.getVectorStore(); |
| | | vectorStore.removeByKidAndFid(kid, fid); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.chain.vectorstore; |
| | | |
| | | import cn.hutool.core.lang.UUID; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.google.gson.internal.LinkedTreeMap; |
| | | import io.weaviate.client.Config; |
| | | import io.weaviate.client.WeaviateClient; |
| | | import io.weaviate.client.base.Result; |
| | | import io.weaviate.client.v1.data.model.WeaviateObject; |
| | | import io.weaviate.client.v1.data.replication.model.ConsistencyLevel; |
| | | import io.weaviate.client.v1.filters.Operator; |
| | | import io.weaviate.client.v1.filters.WhereFilter; |
| | | import io.weaviate.client.v1.graphql.model.GraphQLResponse; |
| | | import io.weaviate.client.v1.graphql.query.argument.NearTextArgument; |
| | | import io.weaviate.client.v1.graphql.query.argument.NearVectorArgument; |
| | | import io.weaviate.client.v1.graphql.query.fields.Field; |
| | | import io.weaviate.client.v1.misc.model.Meta; |
| | | import io.weaviate.client.v1.misc.model.ReplicationConfig; |
| | | import io.weaviate.client.v1.misc.model.ShardingConfig; |
| | | import io.weaviate.client.v1.misc.model.VectorIndexConfig; |
| | | import io.weaviate.client.v1.schema.model.DataType; |
| | | import io.weaviate.client.v1.schema.model.Property; |
| | | import io.weaviate.client.v1.schema.model.Schema; |
| | | import io.weaviate.client.v1.schema.model.WeaviateClass; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.knowledge.chain.retrieve.PromptRetrieverProperties; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | public class WeaviateVectorStore implements VectorStore{ |
| | | |
| | | @Value("${chain.vector.store.weaviate.protocol}") |
| | | private String protocol; |
| | | @Value("${chain.vector.store.weaviate.host}") |
| | | private String host; |
| | | |
| | | @Value("${chain.vector.store.weaviate.classname}") |
| | | private String className; |
| | | |
| | | private final PromptRetrieverProperties promptRetrieverProperties; |
| | | |
| | | public WeaviateVectorStore(PromptRetrieverProperties promptRetrieverProperties) { |
| | | this.promptRetrieverProperties = promptRetrieverProperties; |
| | | } |
| | | |
| | | public WeaviateClient getClient(){ |
| | | Config config = new Config(protocol, host); |
| | | WeaviateClient client = new WeaviateClient(config); |
| | | return client; |
| | | } |
| | | |
| | | public Result<Meta> getMeta(){ |
| | | WeaviateClient client = getClient(); |
| | | Result<Meta> meta = client.misc().metaGetter().run(); |
| | | if (meta.getError() == null) { |
| | | System.out.printf("meta.hostname: %s\n", meta.getResult().getHostname()); |
| | | System.out.printf("meta.version: %s\n", meta.getResult().getVersion()); |
| | | System.out.printf("meta.modules: %s\n", meta.getResult().getModules()); |
| | | } else { |
| | | System.out.printf("Error: %s\n", meta.getError().getMessages()); |
| | | } |
| | | return meta; |
| | | } |
| | | |
| | | public Result<Schema> getSchemas(){ |
| | | WeaviateClient client = getClient(); |
| | | Result<Schema> result = client.schema().getter().run(); |
| | | if (result.hasErrors()) { |
| | | System.out.println(result.getError()); |
| | | }else { |
| | | System.out.println(result.getResult()); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | public Result<Boolean> createSchema(String kid){ |
| | | WeaviateClient client = getClient(); |
| | | |
| | | VectorIndexConfig vectorIndexConfig = VectorIndexConfig.builder() |
| | | .distance("cosine") |
| | | .cleanupIntervalSeconds(300) |
| | | .efConstruction(128) |
| | | .maxConnections(64) |
| | | .vectorCacheMaxObjects(500000L) |
| | | .ef(-1) |
| | | .skip(false) |
| | | .dynamicEfFactor(8) |
| | | .dynamicEfMax(500) |
| | | .dynamicEfMin(100) |
| | | .flatSearchCutoff(40000) |
| | | .build(); |
| | | |
| | | ShardingConfig shardingConfig = ShardingConfig.builder() |
| | | .desiredCount(3) |
| | | .desiredVirtualCount(128) |
| | | .function("murmur3") |
| | | .key("_id") |
| | | .strategy("hash") |
| | | .virtualPerPhysical(128) |
| | | .build(); |
| | | |
| | | ReplicationConfig replicationConfig = ReplicationConfig.builder() |
| | | .factor(1) |
| | | .build(); |
| | | |
| | | JSONObject classModuleConfigValue = new JSONObject(); |
| | | classModuleConfigValue.put("vectorizeClassName",false); |
| | | JSONObject classModuleConfig = new JSONObject(); |
| | | classModuleConfig.put("text2vec-transformers",classModuleConfigValue); |
| | | |
| | | JSONObject propertyModuleConfigValueSkipTrue = new JSONObject(); |
| | | propertyModuleConfigValueSkipTrue.put("vectorizePropertyName",false); |
| | | propertyModuleConfigValueSkipTrue.put("skip",true); |
| | | JSONObject propertyModuleConfigSkipTrue = new JSONObject(); |
| | | propertyModuleConfigSkipTrue.put("text2vec-transformers",propertyModuleConfigValueSkipTrue); |
| | | |
| | | JSONObject propertyModuleConfigValueSkipFalse = new JSONObject(); |
| | | propertyModuleConfigValueSkipFalse.put("vectorizePropertyName",false); |
| | | propertyModuleConfigValueSkipFalse.put("skip",false); |
| | | JSONObject propertyModuleConfigSkipFalse = new JSONObject(); |
| | | propertyModuleConfigSkipFalse.put("text2vec-transformers",propertyModuleConfigValueSkipFalse); |
| | | |
| | | WeaviateClass clazz = WeaviateClass.builder() |
| | | .className(className + kid) |
| | | .description("local knowledge") |
| | | .vectorIndexType("hnsw") |
| | | .vectorizer("text2vec-transformers") |
| | | .shardingConfig(shardingConfig) |
| | | .vectorIndexConfig(vectorIndexConfig) |
| | | .replicationConfig(replicationConfig) |
| | | .moduleConfig(classModuleConfig) |
| | | .properties(new ArrayList() {{ |
| | | add(Property.builder() |
| | | .dataType(new ArrayList(){ { add(DataType.TEXT); } }) |
| | | .name("content") |
| | | .description("The content of the local knowledge,for search") |
| | | .moduleConfig(propertyModuleConfigSkipFalse) |
| | | .build()); |
| | | add(Property.builder() |
| | | .dataType(new ArrayList(){ { add(DataType.TEXT); } }) |
| | | .name("kid") |
| | | .description("The knowledge id of the local knowledge,for search") |
| | | .moduleConfig(propertyModuleConfigSkipTrue) |
| | | .build()); |
| | | add(Property.builder() |
| | | .dataType(new ArrayList(){ { add(DataType.TEXT); } }) |
| | | .name("docId") |
| | | .description("The doc id of the local knowledge,for search") |
| | | .moduleConfig(propertyModuleConfigSkipTrue) |
| | | .build()); |
| | | add(Property.builder() |
| | | .dataType(new ArrayList(){ { add(DataType.TEXT); } }) |
| | | .name("fid") |
| | | .description("The fragment id of the local knowledge,for search") |
| | | .moduleConfig(propertyModuleConfigSkipTrue) |
| | | .build()); |
| | | add(Property.builder() |
| | | .dataType(new ArrayList(){ { add(DataType.TEXT); } }) |
| | | .name("uuid") |
| | | .description("The uuid id of the local knowledge fragment(same with id properties),for search") |
| | | .moduleConfig(propertyModuleConfigSkipTrue) |
| | | .build()); |
| | | } }) |
| | | .build(); |
| | | |
| | | Result<Boolean> result = client.schema().classCreator().withClass(clazz).run(); |
| | | if (result.hasErrors()) { |
| | | System.out.println(result.getError()); |
| | | } |
| | | System.out.println(result.getResult()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public void newSchema(String kid) { |
| | | createSchema(kid); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKidAndFid(String kid, String fid) { |
| | | List<String> resultList = new ArrayList<>(); |
| | | WeaviateClient client = getClient(); |
| | | Field fieldId = Field.builder().name("uuid").build(); |
| | | WhereFilter where = WhereFilter.builder() |
| | | .path(new String[]{ "fid" }) |
| | | .operator(Operator.Equal) |
| | | .valueString(fid) |
| | | .build(); |
| | | Result<GraphQLResponse> result = client.graphQL().get() |
| | | .withClassName(className + kid) |
| | | .withFields(fieldId) |
| | | .withWhere(where) |
| | | .run(); |
| | | LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); |
| | | LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); |
| | | ArrayList<LinkedTreeMap> m = l.get(className + kid); |
| | | for (LinkedTreeMap linkedTreeMap : m){ |
| | | String uuid = linkedTreeMap.get("uuid").toString(); |
| | | resultList.add(uuid); |
| | | } |
| | | for (String uuid : resultList) { |
| | | Result<Boolean> deleteResult = client.data().deleter() |
| | | .withID(uuid) |
| | | .withClassName(className + kid) |
| | | .withConsistencyLevel(ConsistencyLevel.ALL) // default QUORUM |
| | | .run(); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList,String kid, String docId,List<String> fidList) { |
| | | WeaviateClient client = getClient(); |
| | | for (int i = 0; i < chunkList.size(); i++) { |
| | | if (vectorList != null) { |
| | | List<Double> vector = vectorList.get(i); |
| | | Float[] vf = new Float[vector.size()]; |
| | | for (int j = 0; j < vector.size(); j++) { |
| | | Double value = vector.get(j); |
| | | vf[j] = value.floatValue(); |
| | | } |
| | | Map<String, Object> dataSchema = new HashMap<>(); |
| | | dataSchema.put("content", chunkList.get(i)); |
| | | dataSchema.put("kid", kid); |
| | | dataSchema.put("docId", docId); |
| | | dataSchema.put("fid", fidList.get(i)); |
| | | String uuid = UUID.randomUUID(true).toString(); |
| | | dataSchema.put("uuid", uuid); |
| | | Result<WeaviateObject> result = client.data().creator() |
| | | .withClassName(className + kid) |
| | | .withID(uuid) |
| | | .withVector(vf) |
| | | .withProperties(dataSchema) |
| | | .run(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void removeByDocId(String kid,String docId) { |
| | | List<String> resultList = new ArrayList<>(); |
| | | WeaviateClient client = getClient(); |
| | | Field fieldId = Field.builder().name("uuid").build(); |
| | | WhereFilter where = WhereFilter.builder() |
| | | .path(new String[]{ "docId" }) |
| | | .operator(Operator.Equal) |
| | | .valueString(docId) |
| | | .build(); |
| | | Result<GraphQLResponse> result = client.graphQL().get() |
| | | .withClassName(className + kid) |
| | | .withFields(fieldId) |
| | | .withWhere(where) |
| | | .run(); |
| | | LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); |
| | | LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); |
| | | ArrayList<LinkedTreeMap> m = l.get(className + kid); |
| | | for (LinkedTreeMap linkedTreeMap : m){ |
| | | String uuid = linkedTreeMap.get("uuid").toString(); |
| | | resultList.add(uuid); |
| | | } |
| | | for (String uuid : resultList) { |
| | | Result<Boolean> deleteResult = client.data().deleter() |
| | | .withID(uuid) |
| | | .withClassName(className + kid) |
| | | .withConsistencyLevel(ConsistencyLevel.ALL) // default QUORUM |
| | | .run(); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKid(String kid) { |
| | | WeaviateClient client = getClient(); |
| | | Result<Boolean> result = client.schema().classDeleter().withClassName(className + kid).run(); |
| | | if (result.hasErrors()) { |
| | | System.out.println("å é¤schema失败" + result.getError()); |
| | | }else { |
| | | System.out.println("å é¤schemaæå" + result.getResult()); |
| | | } |
| | | log.info("drop schema by kid, result = {}",result); |
| | | } |
| | | |
| | | @Override |
| | | public List<String> nearest(List<Double> queryVector,String kid) { |
| | | if (StringUtils.isBlank(kid)){ |
| | | return new ArrayList<String>(); |
| | | } |
| | | List<String> resultList = new ArrayList<>(); |
| | | Float[] vf = new Float[queryVector.size()]; |
| | | for (int j = 0; j < queryVector.size(); j++) { |
| | | Double value = queryVector.get(j); |
| | | vf[j] = value.floatValue(); |
| | | } |
| | | WeaviateClient client = getClient(); |
| | | Field contentField = Field.builder().name("content").build(); |
| | | Field _additional = Field.builder() |
| | | .name("_additional") |
| | | .fields(new Field[]{ |
| | | Field.builder().name("distance").build() |
| | | }).build(); |
| | | NearVectorArgument nearVector = NearVectorArgument.builder() |
| | | .vector(vf) |
| | | .distance(1.6f) // certainty = 1f - distance /2f |
| | | .build(); |
| | | Result<GraphQLResponse> result = client.graphQL().get() |
| | | .withClassName(className + kid) |
| | | .withFields(contentField,_additional) |
| | | .withNearVector(nearVector) |
| | | .withLimit(promptRetrieverProperties.getLimits()) |
| | | .run(); |
| | | LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); |
| | | LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); |
| | | ArrayList<LinkedTreeMap> m = l.get(className + kid); |
| | | for (LinkedTreeMap linkedTreeMap : m){ |
| | | String content = linkedTreeMap.get("content").toString(); |
| | | resultList.add(content); |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> nearest(String query,String kid) { |
| | | if (StringUtils.isBlank(kid)){ |
| | | return new ArrayList<String>(); |
| | | } |
| | | List<String> resultList = new ArrayList<>(); |
| | | WeaviateClient client = getClient(); |
| | | Field contentField = Field.builder().name("content").build(); |
| | | Field _additional = Field.builder() |
| | | .name("_additional") |
| | | .fields(new Field[]{ |
| | | Field.builder().name("distance").build() |
| | | }).build(); |
| | | NearTextArgument nearText = client.graphQL().arguments().nearTextArgBuilder() |
| | | .concepts(new String[]{ query }) |
| | | .distance(1.6f) // certainty = 1f - distance /2f |
| | | .build(); |
| | | |
| | | Result<GraphQLResponse> result = client.graphQL().get() |
| | | .withClassName(className + kid) |
| | | .withFields(contentField,_additional) |
| | | .withNearText(nearText) |
| | | .withLimit(promptRetrieverProperties.getLimits()) |
| | | .run(); |
| | | LinkedTreeMap<String,Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData(); |
| | | LinkedTreeMap<String,ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get"); |
| | | ArrayList<LinkedTreeMap> m = l.get(className + kid); |
| | | for (LinkedTreeMap linkedTreeMap : m){ |
| | | String content = linkedTreeMap.get("content").toString(); |
| | | resultList.add(content); |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | public Result<Boolean> deleteSchema(String kid) { |
| | | WeaviateClient client = getClient(); |
| | | Result<Boolean> result = client.schema().classDeleter().withClassName(className+ kid).run(); |
| | | if (result.hasErrors()) { |
| | | System.out.println(result.getError()); |
| | | }else { |
| | | System.out.println(result.getResult()); |
| | | } |
| | | return result; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.constant; |
| | | |
| | | public class FileType { |
| | | public static final String TXT = "txt"; |
| | | public static final String CSV = "csv"; |
| | | public static final String MD = "md"; |
| | | public static final String DOC = "doc"; |
| | | public static final String DOCX = "docx"; |
| | | public static final String PDF = "pdf"; |
| | | |
| | | public static final String LOG = "log"; |
| | | public static final String XML = "xml"; |
| | | |
| | | public static final String JAVA = "java"; |
| | | public static final String HTML = "html"; |
| | | public static final String HTM = "htm"; |
| | | public static final String CSS = "css"; |
| | | public static final String JS = "js"; |
| | | public static final String PY = "py"; |
| | | public static final String CPP = "cpp"; |
| | | public static final String SQL = "sql"; |
| | | public static final String PHP = "php"; |
| | | public static final String RUBY = "ruby"; |
| | | public static final String C = "c"; |
| | | public static final String H = "h"; |
| | | public static final String HPP = "hpp"; |
| | | public static final String SWIFT = "swift"; |
| | | public static final String TS = "ts"; |
| | | public static final String RUST = "rs"; |
| | | public static final String PERL = "perl"; |
| | | public static final String SHELL = "shell"; |
| | | public static final String BAT = "bat"; |
| | | public static final String CMD = "cmd"; |
| | | |
| | | public static final String PROPERTIES = "properties"; |
| | | public static final String INI = "ini"; |
| | | public static final String YAML = "yaml"; |
| | | public static final String YML = "yml"; |
| | | |
| | | public static boolean isTextFile(String type){ |
| | | if (type.equalsIgnoreCase(TXT) || type.equalsIgnoreCase(CSV) || type.equalsIgnoreCase(PROPERTIES) |
| | | || type.equalsIgnoreCase(INI) || type.equalsIgnoreCase(YAML) || type.equalsIgnoreCase(YML) |
| | | || type.equalsIgnoreCase(LOG) || type.equalsIgnoreCase(XML)){ |
| | | return true; |
| | | } |
| | | else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static boolean isCodeFile(String type){ |
| | | if (type.equalsIgnoreCase(JAVA) || type.equalsIgnoreCase(HTML) || type.equalsIgnoreCase(HTM) || type.equalsIgnoreCase(JS) || type.equalsIgnoreCase(PY) |
| | | || type.equalsIgnoreCase(CPP) || type.equalsIgnoreCase(SQL) || type.equalsIgnoreCase(PHP) || type.equalsIgnoreCase(RUBY) |
| | | || type.equalsIgnoreCase(C) || type.equalsIgnoreCase(H) || type.equalsIgnoreCase(HPP) || type.equalsIgnoreCase(SWIFT) |
| | | || type.equalsIgnoreCase(TS) || type.equalsIgnoreCase(RUST) || type.equalsIgnoreCase(PERL) || type.equalsIgnoreCase(SHELL) |
| | | || type.equalsIgnoreCase(BAT) || type.equalsIgnoreCase(CMD) || type.equalsIgnoreCase(CSS)){ |
| | | return true; |
| | | } |
| | | else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static boolean isMdFile(String type){ |
| | | if (type.equalsIgnoreCase(MD)){ |
| | | return true; |
| | | } |
| | | else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static boolean isWord(String type){ |
| | | if (type.equalsIgnoreCase(DOC) || type.equalsIgnoreCase(DOCX)){ |
| | | return true; |
| | | } |
| | | else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public static boolean isPdf(String type){ |
| | | if (type.equalsIgnoreCase(PDF)){ |
| | | return true; |
| | | } |
| | | else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * ç¥è¯åºé件对象 knowledge_attach |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | |
| | | @TableName("knowledge_attach") |
| | | public class KnowledgeAttach implements Serializable { |
| | | |
| | | |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | private String docId; |
| | | |
| | | /** |
| | | * ææ¡£åç§° |
| | | */ |
| | | private String docName; |
| | | |
| | | /** |
| | | * ææ¡£ç±»å |
| | | */ |
| | | private String docType; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | private String content; |
| | | |
| | | /** |
| | | * å建è
|
| | | */ |
| | | private String createBy; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * ç¥è¯ç段对象 knowledge_fragment |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @TableName("knowledge_fragment") |
| | | public class KnowledgeFragment implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | private String docId; |
| | | |
| | | /** |
| | | * ç¥è¯ç段ID |
| | | */ |
| | | private String fid; |
| | | |
| | | /** |
| | | * çæ®µç´¢å¼ä¸æ |
| | | */ |
| | | private Integer idx; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | private String content; |
| | | |
| | | /** |
| | | * å建è
|
| | | */ |
| | | private String createBy; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | |
| | | /** |
| | | * ç¥è¯åºå¯¹è±¡ knowledge_info |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @TableName("knowledge_info") |
| | | public class KnowledgeInfo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @TableId(value = "id") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | private String kid; |
| | | |
| | | /** |
| | | * ç¨æ·ID |
| | | */ |
| | | private Long uid; |
| | | |
| | | /** |
| | | * ç¥è¯åºåç§° |
| | | */ |
| | | private String kname; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | private String description; |
| | | |
| | | |
| | | /** |
| | | * å建è
|
| | | */ |
| | | private String createBy; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | private Date createTime; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.bo; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.common.mybatis.core.domain.BaseEntity; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | |
| | | /** |
| | | * ç¥è¯åºéä»¶ä¸å¡å¯¹è±¡ knowledge_attach |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = KnowledgeAttach.class, reverseConvertGenerate = false) |
| | | public class KnowledgeAttachBo extends BaseEntity { |
| | | |
| | | @NotNull(message = "ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @NotBlank(message = "ç¥è¯åºIDä¸è½ä¸ºç©º") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | @NotBlank(message = "ææ¡£IDä¸è½ä¸ºç©º") |
| | | private String docId; |
| | | |
| | | /** |
| | | * ææ¡£åç§° |
| | | */ |
| | | @NotBlank(message = "ææ¡£åç§°ä¸è½ä¸ºç©º") |
| | | private String docName; |
| | | |
| | | /** |
| | | * ææ¡£ç±»å |
| | | */ |
| | | @NotBlank(message = "ææ¡£ç±»åä¸è½ä¸ºç©º") |
| | | private String docType; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | @NotBlank(message = "ææ¡£å
容ä¸è½ä¸ºç©º") |
| | | private String content; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.bo; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.common.mybatis.core.domain.BaseEntity; |
| | | import org.ruoyi.knowledge.domain.KnowledgeFragment; |
| | | |
| | | /** |
| | | * ç¥è¯ç段ä¸å¡å¯¹è±¡ knowledge_fragment |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = KnowledgeFragment.class, reverseConvertGenerate = false) |
| | | public class KnowledgeFragmentBo extends BaseEntity { |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @NotNull(message = "ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @NotBlank(message = "ç¥è¯åºIDä¸è½ä¸ºç©º") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | @NotBlank(message = "ææ¡£IDä¸è½ä¸ºç©º") |
| | | private String docId; |
| | | |
| | | /** |
| | | * ç¥è¯ç段ID |
| | | */ |
| | | @NotBlank(message = "ç¥è¯ç段IDä¸è½ä¸ºç©º") |
| | | private String fid; |
| | | |
| | | /** |
| | | * çæ®µç´¢å¼ä¸æ |
| | | */ |
| | | @NotNull(message = "çæ®µç´¢å¼ä¸æ ä¸è½ä¸ºç©º") |
| | | private Long idx; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | @NotBlank(message = "ææ¡£å
容ä¸è½ä¸ºç©º") |
| | | private String content; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.bo; |
| | | |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import jakarta.validation.constraints.NotBlank; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.ruoyi.common.mybatis.core.domain.BaseEntity; |
| | | import org.ruoyi.knowledge.domain.KnowledgeInfo; |
| | | |
| | | /** |
| | | * ç¥è¯åºä¸å¡å¯¹è±¡ knowledge_info |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @AutoMapper(target = KnowledgeInfo.class, reverseConvertGenerate = false) |
| | | public class KnowledgeInfoBo extends BaseEntity { |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @NotNull(message = "ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @NotBlank(message = "ç¥è¯åºIDä¸è½ä¸ºç©º") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ç¨æ·ID |
| | | */ |
| | | @NotNull(message = "ç¨æ·IDä¸è½ä¸ºç©º") |
| | | private Long uid; |
| | | |
| | | /** |
| | | * ç¥è¯åºåç§° |
| | | */ |
| | | @NotBlank(message = "ç¥è¯åºåç§°ä¸è½ä¸ºç©º") |
| | | private String kname; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | @NotBlank(message = "æè¿°ä¸è½ä¸ºç©º") |
| | | private String description; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.req; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | @Data |
| | | public class KnowledgeInfoUploadRequest { |
| | | |
| | | private String kid; |
| | | |
| | | private MultipartFile file; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain; |
| | | |
| | | public class request { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç¥è¯åºéä»¶è§å¾å¯¹è±¡ knowledge_attach |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = KnowledgeAttach.class) |
| | | public class KnowledgeAttachVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @ExcelProperty(value = "") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @ExcelProperty(value = "ç¥è¯åºID") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£ID") |
| | | private String docId; |
| | | |
| | | /** |
| | | * ææ¡£åç§° |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£åç§°") |
| | | private String docName; |
| | | |
| | | /** |
| | | * ææ¡£ç±»å |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£ç±»å") |
| | | private String docType; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£å
容") |
| | | private String content; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.ruoyi.knowledge.domain.KnowledgeFragment; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç¥è¯ç段è§å¾å¯¹è±¡ knowledge_fragment |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = KnowledgeFragment.class) |
| | | public class KnowledgeFragmentVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @ExcelProperty(value = "") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @ExcelProperty(value = "ç¥è¯åºID") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ææ¡£ID |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£ID") |
| | | private String docId; |
| | | |
| | | /** |
| | | * ç¥è¯ç段ID |
| | | */ |
| | | @ExcelProperty(value = "ç¥è¯ç段ID") |
| | | private String fid; |
| | | |
| | | /** |
| | | * çæ®µç´¢å¼ä¸æ |
| | | */ |
| | | @ExcelProperty(value = "çæ®µç´¢å¼ä¸æ ") |
| | | private Long idx; |
| | | |
| | | /** |
| | | * ææ¡£å
容 |
| | | */ |
| | | @ExcelProperty(value = "ææ¡£å
容") |
| | | private String content; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.domain.vo; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import io.github.linpeilie.annotations.AutoMapper; |
| | | import lombok.Data; |
| | | import org.ruoyi.knowledge.domain.KnowledgeInfo; |
| | | |
| | | import java.io.Serial; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç¥è¯åºè§å¾å¯¹è±¡ knowledge_info |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | @AutoMapper(target = KnowledgeInfo.class) |
| | | public class KnowledgeInfoVo implements Serializable { |
| | | |
| | | @Serial |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | @ExcelProperty(value = "") |
| | | private Long id; |
| | | |
| | | /** |
| | | * ç¥è¯åºID |
| | | */ |
| | | @ExcelProperty(value = "ç¥è¯åºID") |
| | | private String kid; |
| | | |
| | | /** |
| | | * ç¨æ·ID |
| | | */ |
| | | @ExcelProperty(value = "ç¨æ·ID") |
| | | private Long uid; |
| | | |
| | | /** |
| | | * ç¥è¯åºåç§° |
| | | */ |
| | | @ExcelProperty(value = "ç¥è¯åºåç§°") |
| | | private String kname; |
| | | |
| | | /** |
| | | * æè¿° |
| | | */ |
| | | @ExcelProperty(value = "æè¿°") |
| | | private String description; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.mapper; |
| | | |
| | | import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeAttachVo; |
| | | |
| | | /** |
| | | * ç¥è¯åºéä»¶Mapperæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface KnowledgeAttachMapper extends BaseMapperPlus<KnowledgeAttach, KnowledgeAttachVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.mapper; |
| | | |
| | | import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.knowledge.domain.KnowledgeFragment; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeFragmentVo; |
| | | |
| | | /** |
| | | * ç¥è¯ç段Mapperæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface KnowledgeFragmentMapper extends BaseMapperPlus<KnowledgeFragment, KnowledgeFragmentVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.mapper; |
| | | |
| | | import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; |
| | | import org.ruoyi.knowledge.domain.KnowledgeInfo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; |
| | | |
| | | /** |
| | | * ç¥è¯åºMapperæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface KnowledgeInfoMapper extends BaseMapperPlus<KnowledgeInfo, KnowledgeInfoVo> { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface EmbeddingService { |
| | | |
| | | void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList); |
| | | |
| | | void removeByDocId(String kid,String docId); |
| | | |
| | | void removeByKid(String kid); |
| | | |
| | | List<Double> getQueryVector(String query); |
| | | |
| | | void createSchema(String kid); |
| | | |
| | | void removeByKidAndFid(String kid, String fid); |
| | | |
| | | void saveFragment(String kid, String docId, String fid, String content); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service; |
| | | |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeAttachVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç¥è¯åºéä»¶Serviceæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface IKnowledgeAttachService { |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶ |
| | | */ |
| | | KnowledgeAttachVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶å表 |
| | | */ |
| | | TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶å表 |
| | | */ |
| | | List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo); |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯åºéä»¶ |
| | | */ |
| | | Boolean insertByBo(KnowledgeAttachBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯åºéä»¶ |
| | | */ |
| | | Boolean updateByBo(KnowledgeAttachBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤ç¥è¯åºéä»¶ä¿¡æ¯ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | |
| | | |
| | | /** |
| | | * å é¤ç¥è¯éä»¶ |
| | | * |
| | | * @return |
| | | */ |
| | | void removeKnowledgeAttach(String kid); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service; |
| | | |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeFragmentBo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeFragmentVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç¥è¯ç段Serviceæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface IKnowledgeFragmentService { |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段 |
| | | */ |
| | | KnowledgeFragmentVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段å表 |
| | | */ |
| | | TableDataInfo<KnowledgeFragmentVo> queryPageList(KnowledgeFragmentBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段å表 |
| | | */ |
| | | List<KnowledgeFragmentVo> queryList(KnowledgeFragmentBo bo); |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯ç段 |
| | | */ |
| | | Boolean insertByBo(KnowledgeFragmentBo bo); |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯ç段 |
| | | */ |
| | | Boolean updateByBo(KnowledgeFragmentBo bo); |
| | | |
| | | /** |
| | | * æ ¡éªå¹¶æ¹éå é¤ç¥è¯çæ®µä¿¡æ¯ |
| | | */ |
| | | Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service; |
| | | |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeInfoBo; |
| | | import org.ruoyi.knowledge.domain.req.KnowledgeInfoUploadRequest; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç¥è¯åºServiceæ¥å£ |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | public interface IKnowledgeInfoService { |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åº |
| | | */ |
| | | KnowledgeInfoVo queryById(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºå表 |
| | | */ |
| | | TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery); |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºå表 |
| | | */ |
| | | List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo); |
| | | |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯åº |
| | | */ |
| | | Boolean updateByBo(KnowledgeInfoBo bo); |
| | | |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯åº |
| | | */ |
| | | void saveOne(KnowledgeInfoBo bo); |
| | | |
| | | /** |
| | | * ä¸ä¼ éä»¶ |
| | | */ |
| | | void upload(KnowledgeInfoUploadRequest request); |
| | | |
| | | /** |
| | | * å é¤ç¥è¯åº |
| | | */ |
| | | void removeKnowledge(String id); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service.impl; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import org.ruoyi.knowledge.chain.vectorizer.Vectorization; |
| | | import org.ruoyi.knowledge.chain.vectorstore.VectorStore; |
| | | import org.ruoyi.knowledge.service.EmbeddingService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class EmbeddingServiceImpl implements EmbeddingService { |
| | | |
| | | private final VectorStore vectorStore; |
| | | private final Vectorization vectorization; |
| | | |
| | | /** |
| | | * ä¿ååéæ°æ®åº |
| | | * @param chunkList ææ¡£æè¡ååççæ®µ |
| | | * @param kid ç¥è¯åºID |
| | | * @param docId ææ¡£ID |
| | | */ |
| | | @Override |
| | | public void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList) { |
| | | List<List<Double>> vectorList = vectorization.batchVectorization(chunkList); |
| | | vectorStore.storeEmbeddings(chunkList,vectorList,kid,docId,fidList); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByDocId(String kid,String docId) { |
| | | vectorStore.removeByDocId(kid,docId); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKid(String kid) { |
| | | vectorStore.removeByKid(kid); |
| | | } |
| | | |
| | | @Override |
| | | public List<Double> getQueryVector(String query) { |
| | | List<Double> queryVector = vectorization.singleVectorization(query); |
| | | return queryVector; |
| | | } |
| | | |
| | | @Override |
| | | public void createSchema(String kid) { |
| | | vectorStore.newSchema(kid); |
| | | } |
| | | |
| | | @Override |
| | | public void removeByKidAndFid(String kid, String fid) { |
| | | vectorStore.removeByKidAndFid(kid,fid); |
| | | } |
| | | |
| | | @Override |
| | | public void saveFragment(String kid, String docId, String fid, String content) { |
| | | List<String> chunkList = new ArrayList<>(); |
| | | List<String> fidList = new ArrayList<>(); |
| | | chunkList.add(content); |
| | | fidList.add(fid); |
| | | storeEmbeddings(chunkList,kid,docId,fidList); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeAttachVo; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeAttachMapper; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeFragmentMapper; |
| | | import org.ruoyi.knowledge.service.IKnowledgeAttachService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * ç¥è¯åºéä»¶Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class KnowledgeAttachServiceImpl implements IKnowledgeAttachService { |
| | | |
| | | private final KnowledgeAttachMapper baseMapper; |
| | | |
| | | private final KnowledgeFragmentMapper fragmentMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶ |
| | | */ |
| | | @Override |
| | | public KnowledgeAttachVo queryById(Long id){ |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); |
| | | Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºéä»¶å表 |
| | | */ |
| | | @Override |
| | | public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) { |
| | | LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<KnowledgeAttach> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeAttach::getKid, bo.getKid()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeAttach::getDocId, bo.getDocId()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getDocName()), KnowledgeAttach::getDocName, bo.getDocName()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getDocType()), KnowledgeAttach::getDocType, bo.getDocType()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeAttach::getContent, bo.getContent()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯åºéä»¶ |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(KnowledgeAttachBo bo) { |
| | | KnowledgeAttach add = MapstructUtils.convert(bo, KnowledgeAttach.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯åºéä»¶ |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(KnowledgeAttachBo bo) { |
| | | KnowledgeAttach update = MapstructUtils.convert(bo, KnowledgeAttach.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(KnowledgeAttach entity){ |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤ç¥è¯åºéä»¶ |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if(isValid){ |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public void removeKnowledgeAttach(String kid) { |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("kid", kid); |
| | | baseMapper.deleteByMap(map); |
| | | fragmentMapper.deleteByMap(map); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.knowledge.domain.KnowledgeFragment; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeFragmentBo; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeFragmentVo; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeFragmentMapper; |
| | | import org.ruoyi.knowledge.service.IKnowledgeFragmentService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | /** |
| | | * ç¥è¯ç段Serviceä¸å¡å±å¤ç |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class KnowledgeFragmentServiceImpl implements IKnowledgeFragmentService { |
| | | |
| | | private final KnowledgeFragmentMapper baseMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段 |
| | | */ |
| | | @Override |
| | | public KnowledgeFragmentVo queryById(Long id){ |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段å表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<KnowledgeFragmentVo> queryPageList(KnowledgeFragmentBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<KnowledgeFragment> lqw = buildQueryWrapper(bo); |
| | | lqw.eq(KnowledgeFragment::getDocId, bo.getDocId()); |
| | | Page<KnowledgeFragmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯ç段å表 |
| | | */ |
| | | @Override |
| | | public List<KnowledgeFragmentVo> queryList(KnowledgeFragmentBo bo) { |
| | | LambdaQueryWrapper<KnowledgeFragment> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<KnowledgeFragment> buildQueryWrapper(KnowledgeFragmentBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<KnowledgeFragment> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeFragment::getKid, bo.getKid()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeFragment::getDocId, bo.getDocId()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getFid()), KnowledgeFragment::getFid, bo.getFid()); |
| | | lqw.eq(bo.getIdx() != null, KnowledgeFragment::getIdx, bo.getIdx()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeFragment::getContent, bo.getContent()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ç¥è¯ç段 |
| | | */ |
| | | @Override |
| | | public Boolean insertByBo(KnowledgeFragmentBo bo) { |
| | | KnowledgeFragment add = MapstructUtils.convert(bo, KnowledgeFragment.class); |
| | | validEntityBeforeSave(add); |
| | | boolean flag = baseMapper.insert(add) > 0; |
| | | if (flag) { |
| | | bo.setId(add.getId()); |
| | | } |
| | | return flag; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯ç段 |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(KnowledgeFragmentBo bo) { |
| | | KnowledgeFragment update = MapstructUtils.convert(bo, KnowledgeFragment.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(KnowledgeFragment entity){ |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå é¤ç¥è¯ç段 |
| | | */ |
| | | @Override |
| | | public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
| | | if(isValid){ |
| | | //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª |
| | | } |
| | | return baseMapper.deleteBatchIds(ids) > 0; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.knowledge.service.impl; |
| | | |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import io.github.ollama4j.OllamaAPI; |
| | | import io.github.ollama4j.exceptions.OllamaBaseException; |
| | | import io.github.ollama4j.models.chat.OllamaChatMessageRole; |
| | | import io.github.ollama4j.models.chat.OllamaChatRequestBuilder; |
| | | import io.github.ollama4j.models.chat.OllamaChatRequestModel; |
| | | import io.github.ollama4j.models.chat.OllamaChatResult; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.common.core.utils.MapstructUtils; |
| | | import org.ruoyi.common.core.utils.StringUtils; |
| | | import org.ruoyi.common.mybatis.core.page.PageQuery; |
| | | import org.ruoyi.common.mybatis.core.page.TableDataInfo; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.knowledge.chain.loader.ResourceLoader; |
| | | import org.ruoyi.knowledge.chain.loader.ResourceLoaderFactory; |
| | | import org.ruoyi.knowledge.domain.KnowledgeAttach; |
| | | import org.ruoyi.knowledge.domain.KnowledgeFragment; |
| | | import org.ruoyi.knowledge.domain.KnowledgeInfo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeAttachBo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeFragmentBo; |
| | | import org.ruoyi.knowledge.domain.bo.KnowledgeInfoBo; |
| | | import org.ruoyi.knowledge.domain.req.KnowledgeInfoUploadRequest; |
| | | import org.ruoyi.knowledge.domain.vo.KnowledgeInfoVo; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeAttachMapper; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeFragmentMapper; |
| | | import org.ruoyi.knowledge.mapper.KnowledgeInfoMapper; |
| | | import org.ruoyi.knowledge.service.EmbeddingService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeAttachService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeFragmentService; |
| | | import org.ruoyi.knowledge.service.IKnowledgeInfoService; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * ç¥è¯åºServiceä¸å¡å±å¤ç |
| | | * |
| | | * @author Lion Li |
| | | * @date 2024-10-21 |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService { |
| | | |
| | | private final KnowledgeInfoMapper baseMapper; |
| | | |
| | | private final EmbeddingService embeddingService; |
| | | |
| | | private final ResourceLoaderFactory resourceLoaderFactory; |
| | | |
| | | private final KnowledgeFragmentMapper fragmentMapper; |
| | | |
| | | private final KnowledgeAttachMapper attachMapper; |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åº |
| | | */ |
| | | @Override |
| | | public KnowledgeInfoVo queryById(Long id){ |
| | | return baseMapper.selectVoById(id); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºå表 |
| | | */ |
| | | @Override |
| | | public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); |
| | | Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¥è¯åºå表 |
| | | */ |
| | | @Override |
| | | public List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo) { |
| | | LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); |
| | | return baseMapper.selectVoList(lqw); |
| | | } |
| | | |
| | | private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeInfo::getKid, bo.getKid()); |
| | | lqw.eq(bo.getUid() != null, KnowledgeInfo::getUid, bo.getUid()); |
| | | lqw.like(StringUtils.isNotBlank(bo.getKname()), KnowledgeInfo::getKname, bo.getKname()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription()); |
| | | return lqw; |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¥è¯åº |
| | | */ |
| | | @Override |
| | | public Boolean updateByBo(KnowledgeInfoBo bo) { |
| | | KnowledgeInfo update = MapstructUtils.convert(bo, KnowledgeInfo.class); |
| | | validEntityBeforeSave(update); |
| | | return baseMapper.updateById(update) > 0; |
| | | } |
| | | |
| | | /** |
| | | * ä¿ååçæ°æ®æ ¡éª |
| | | */ |
| | | private void validEntityBeforeSave(KnowledgeInfo entity){ |
| | | //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void saveOne(KnowledgeInfoBo bo) { |
| | | KnowledgeInfo knowledgeInfo = MapstructUtils.convert(bo, KnowledgeInfo.class); |
| | | if (StringUtils.isBlank(bo.getKid())){ |
| | | String kid = RandomUtil.randomString(10); |
| | | if (knowledgeInfo != null) { |
| | | knowledgeInfo.setKid(kid); |
| | | knowledgeInfo.setUid(LoginHelper.getLoginUser().getUserId()); |
| | | } |
| | | baseMapper.insert(knowledgeInfo); |
| | | embeddingService.createSchema(kid); |
| | | }else { |
| | | baseMapper.updateById(knowledgeInfo); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void upload(KnowledgeInfoUploadRequest request) { |
| | | storeContent(request.getFile(), request.getKid()); |
| | | } |
| | | |
| | | public void storeContent(MultipartFile file, String kid) { |
| | | String fileName = file.getOriginalFilename(); |
| | | List<String> chunkList = new ArrayList<>(); |
| | | KnowledgeAttach knowledgeAttach = new KnowledgeAttach(); |
| | | knowledgeAttach.setKid(kid); |
| | | String docId = RandomUtil.randomString(10); |
| | | knowledgeAttach.setDocId(docId); |
| | | knowledgeAttach.setDocName(fileName); |
| | | knowledgeAttach.setDocType(fileName.substring(fileName.lastIndexOf(".")+1)); |
| | | String content = ""; |
| | | ResourceLoader resourceLoader = resourceLoaderFactory.getLoaderByFileType(knowledgeAttach.getDocType()); |
| | | List<String> fids = new ArrayList<>(); |
| | | try { |
| | | content = resourceLoader.getContent(file.getInputStream()); |
| | | chunkList = resourceLoader.getChunkList(content); |
| | | for (int i = 0; i < chunkList.size(); i++) { |
| | | String fid = RandomUtil.randomString(16); |
| | | fids.add(fid); |
| | | KnowledgeFragment knowledgeFragment = new KnowledgeFragment(); |
| | | knowledgeFragment.setKid(kid); |
| | | knowledgeFragment.setDocId(docId); |
| | | knowledgeFragment.setFid(fid); |
| | | knowledgeFragment.setIdx(i); |
| | | // String text = convertTextBlockToPretrainData(chunkList.get(i)); |
| | | knowledgeFragment.setContent(chunkList.get(i)); |
| | | knowledgeFragment.setCreateTime(new Date()); |
| | | fragmentMapper.insert(knowledgeFragment); |
| | | } |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | knowledgeAttach.setContent(content); |
| | | knowledgeAttach.setCreateTime(new Date()); |
| | | attachMapper.insert(knowledgeAttach); |
| | | embeddingService.storeEmbeddings(chunkList,kid,docId,fids); |
| | | } |
| | | |
| | | @Override |
| | | public void removeKnowledge(String id) { |
| | | |
| | | Map<String,Object> map = new HashMap<>(); |
| | | map.put("kid",id); |
| | | // å é¤ç¥è¯åº |
| | | baseMapper.deleteByMap(map); |
| | | // å é¤éä»¶åç¥è¯ç段 |
| | | fragmentMapper.deleteByMap(map); |
| | | attachMapper.deleteByMap(map); |
| | | // å é¤åéåºä¿¡æ¯ |
| | | embeddingService.removeByKid(id); |
| | | } |
| | | |
| | | /** |
| | | * å°ææ¬å转æ¢ä¸ºé¢è®ç»æ°æ® |
| | | * @param chunk è§£æææ¬å |
| | | */ |
| | | public String convertTextBlockToPretrainData(String chunk){ |
| | | String host = "http://localhost:11434/"; |
| | | OllamaAPI ollama = new OllamaAPI(host); |
| | | OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance("qwen2.5:7b"); |
| | | // 设置è¶
æ¶æ¶é´ |
| | | ollama.setRequestTimeoutSeconds(100); |
| | | // create first user question |
| | | String json = "instruction:ç¨æ·æä»¤,æ ¹æ®è¯ä¹æåä¸ä¸ªå
³é®è¯;input:ç¨æ·è¾å
¥,æ ¹æ®è¯ä¹æåå¤ä¸ªå
³é®è¯;output:è¾åºææ¬å
容"; |
| | | |
| | | OllamaChatRequestModel requestModel = builder.withMessage |
| | | (OllamaChatMessageRole.USER, "ææ¬ï¼"+chunk+"çè§£ææ¬å
容ï¼å¹¶ä¸å°ææ¬å
容转æ¢ä¸º:"+json+",è¾åºJSONæ ¼å¼ï¼ä¸è¦å
å«å
¶ä»æ å
³å
容,å
é¨ä½¿ç¨æ éè±æ") |
| | | .build(); |
| | | |
| | | // start conversation with model |
| | | OllamaChatResult chatResult = null; |
| | | try { |
| | | chatResult = ollama.chat(requestModel); |
| | | } catch (Exception e) { |
| | | System.out.println("è§£æå¤±è´¥!"); |
| | | } |
| | | return chatResult.getResponse(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <artifactId>live-chat-client-commons-base</artifactId> |
| | | <name>ordinaryroad-live-chat-client-commons-base</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>com.fasterxml.jackson.core</groupId> |
| | | <artifactId>jackson-databind</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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> { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <packaging>jar</packaging> |
| | | |
| | | <artifactId>live-chat-client-commons-client</artifactId> |
| | | <name>live-chat-client-commons-client</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons-base</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons-util</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <packaging>jar</packaging> |
| | | |
| | | <artifactId>live-chat-client-commons-util</artifactId> |
| | | <name>live-chat-client-commons-util</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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)); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-live</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <packaging>pom</packaging> |
| | | |
| | | <artifactId>live-chat-client-commons</artifactId> |
| | | |
| | | <modules> |
| | | <module>live-chat-client-commons-base</module> |
| | | <module>live-chat-client-commons-util</module> |
| | | <module>live-chat-client-commons-client</module> |
| | | </modules> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-servers</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <packaging>jar</packaging> |
| | | |
| | | <artifactId>live-chat-client-servers-netty-client</artifactId> |
| | | <name>live-chat-client-servers-netty</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons-client</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-servers-netty</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-servers</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <packaging>jar</packaging> |
| | | |
| | | <artifactId>live-chat-client-servers-netty</artifactId> |
| | | <name>live-chat-client-servers-netty</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-commons-base</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>io.netty</groupId> |
| | | <artifactId>netty-all</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>ch.qos.logback</groupId> |
| | | <artifactId>logback-classic</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-live</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <packaging>pom</packaging> |
| | | |
| | | <artifactId>live-chat-client-servers</artifactId> |
| | | <name>live-chat-client-servers</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <modules> |
| | | <module>live-chat-client-servers-netty</module> |
| | | <module>live-chat-client-servers-netty-client</module> |
| | | </modules> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- |
| | | ~ MIT License |
| | | ~ |
| | | ~ Copyright (c) 2023 OrdinaryRoad |
| | | ~ |
| | | ~ Permission is hereby granted, free of charge, to any person obtaining a copy |
| | | ~ of this software and associated documentation files (the "Software"), to deal |
| | | ~ in the Software without restriction, including without limitation the rights |
| | | ~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | ~ copies of the Software, and to permit persons to whom the Software is |
| | | ~ furnished to do so, subject to the following conditions: |
| | | ~ |
| | | ~ The above copyright notice and this permission notice shall be included in all |
| | | ~ copies or substantial portions of the Software. |
| | | ~ |
| | | ~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | ~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| | | ~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| | | ~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| | | ~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| | | ~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| | | ~ SOFTWARE. |
| | | --> |
| | | |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-clients</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | <packaging>jar</packaging> |
| | | |
| | | <artifactId>live-chat-client-bilibili</artifactId> |
| | | <name>live-chat-client-bilibili</name> |
| | | |
| | | <properties> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>live-chat-client-servers-netty-client</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.aayushatharva.brotli4j</groupId> |
| | | <artifactId>brotli4j</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.google.protobuf</groupId> |
| | | <artifactId>protobuf-java-util</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>ch.qos.logback</groupId> |
| | | <artifactId>logback-classic</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.junit.jupiter</groupId> |
| | | <artifactId>junit-jupiter</artifactId> |
| | | <version>${junit-jupiter.version}</version> |
| | | <scope>test</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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> { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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(); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * 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
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/java/tech/ordinaryroad/live/chat/client/bilibili/util/BilibiliCodecUtil.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/resources/proto/dm_v2.proto
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/main/resources/proto/dm_v2_20.proto
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/test/java/tech/ordinaryroad/live/chat/client/bilibili/api/BilibiliApisTest.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-bilibili/src/test/java/tech/ordinaryroad/live/chat/client/bilibili/client/BilibiliLiveChatClientTest.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/pom.xml
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/ClientModeExample.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/api/DouyinApis.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/client/DouyinLiveChatClient.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/config/DouyinLiveChatClientConfig.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/constant/DouyinCmdEnum.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/listener/IDouyinConnectionListener.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/listener/IDouyinMsgListener.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinDanmuMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinEnterRoomMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinGiftMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/DouyinLikeMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/base/IDouyinCmdMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/msg/base/IDouyinMsg.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/netty/handler/DouyinBinaryFrameHandler.java
ruoyi-modules/ruoyi-live/live-chat-clients/live-chat-client-douyin/src/main/java/tech/ordinaryroad/live/chat/client/douyin/netty/handler/DouyinConnectionHandler.java
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
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
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
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
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
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
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
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
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
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
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/FaceController.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/domain/InsightFace.java (已删除)
ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/domain/MjPriceConfig.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/SubmitActionDTO.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/SubmitModalDTO.java (已删除)
ruoyi-modules/ruoyi-midjourney/src/main/java/com/xmzs/midjourney/dto/SubmitShortenDTO.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/ActionType.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/MjOkHttpUtil.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/cofing/WxMaConfiguration.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/cofing/WxMaProperties.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/monitor/CacheController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/monitor/SysLogininforController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/monitor/SysOperlogController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/monitor/SysUserOnlineController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysConfigController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysDeptController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysDictDataController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysDictTypeController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysMenuController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysModelController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysNoticeController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysOssConfigController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysOssController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysPostController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysProfileController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysRoleController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysTenantController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysTenantPackageController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/controller/system/SysUserController.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/ChatMessage.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/ChatToken.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/PaymentOrders.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysCache.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysConfig.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysDept.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysDictData.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysDictType.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysLogininfor.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysMenu.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysModel.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysNotice.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysOperLog.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysOss.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysOssConfig.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysPost.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysRole.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysRoleDept.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysRoleMenu.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysTenant.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysTenantPackage.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysUser.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysUserOnline.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysUserPost.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/SysUserRole.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/VoiceRole.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/ChatMessageBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/PaymentOrdersBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysConfigBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysDeptBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysDictDataBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysDictTypeBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysLogininforBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysMenuBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysModelBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysNoticeBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysOperLogBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysOssBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysOssConfigBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysPostBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysRoleBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysTenantBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysTenantPackageBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysUserBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/SysUserProfileBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/bo/VoiceRoleBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/request/EmailRequest.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/request/OrderRequest.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/request/UserRequest.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/AvatarVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/CacheListInfoVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/CaptchaVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/ChatMessageVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/ChatTokenVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/DeptTreeSelectVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/LoginTenantVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/LoginVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/MenuTreeSelectVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/MetaVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/PaymentOrdersVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/ProfileVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/RouterVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysConfigVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysDeptVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysDictDataVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysDictTypeVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysLogininforVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysMenuVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysModelVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysNoticeVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysOperLogVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysOssConfigVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysOssUploadVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysOssVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysPostVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysRoleVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysTenantPackageVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysTenantVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysUserExportVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysUserImportVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysUserInfoVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/SysUserVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/TenantListVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/UserInfoVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/domain/vo/VoiceRoleVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/handler/CustomerBigDecimalSerialize.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/listener/SysUserImportListener.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/ChatMessageMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/ChatTokenMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/PaymentOrdersMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysConfigMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysDeptMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysDictDataMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysDictTypeMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysLogininforMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysMenuMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysModelMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysNoticeMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysOperLogMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysOssConfigMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysOssMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysPostMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysRoleDeptMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysRoleMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysRoleMenuMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysTenantMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysTenantPackageMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysUserMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysUserPostMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/SysUserRoleMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/mapper/VoiceRoleMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/runner/SystemApplicationRunner.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ChatService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/IChatCostService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/IChatMessageService.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/IChatTokenService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/IPaymentOrdersService.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/ISysConfigService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysDataScopeService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysDeptService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysDictDataService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysDictTypeService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysLogininforService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysMenuService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysModelService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysNoticeService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysOperLogService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysOssConfigService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysOssService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysPermissionService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysPostService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysRoleService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysTenantPackageService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysTenantService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/ISysUserService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/SseService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/SysLoginService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/SysRegisterService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/TextReviewService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/ChatCostServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/ChatMessageServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/ChatServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/ChatTokenServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/PaymentOrdersServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SseServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysConfigServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysDataScopeServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysDeptServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysDictDataServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysDictTypeServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysLogininforServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysMenuServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysModelServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysNoticeServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysOperLogServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysOssConfigServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysOssServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysPermissionServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysPostServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysRoleServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysSensitiveServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysTenantPackageServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysTenantServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/service/impl/SysUserServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/util/BotUtil.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/com/xmzs/system/util/OrderNumberGenerator.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/builder/AbstractBuilder.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/builder/ImageBuilder.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/builder/TextBuilder.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/cofing/OkHttpConfig.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/cofing/WxCpConfiguration.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/cofing/WxCpProperties.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/ChatConfigController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/ChatStoreController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/ChatVoucherController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/WeChatController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/WxRobConfigController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/wxsingle/WxJsController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/wxsingle/WxPortalController.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/ChatAppStore.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/ChatConfig.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/Cover.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/CoverPromptAudio.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/VoiceRole.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/bo/ChatAppStoreBo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/bo/VoiceRoleBo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/request/translation/TranslationRequest.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ChatAppStoreVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/VoiceRoleVo.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/cover/CoverCallbackVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/cover/CoverParamVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/cover/CoverPromptAudioVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/cover/CoverVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/cover/MusicVo.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptAllQueryDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptGenerateContentDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptGenerateOutlineDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptGeneratePptxDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptTemplateFilterDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/domain/vo/ppt/PptTemplateQueryDto.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/MyMsgHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/AbstractHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/ContactChangeHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/EnterAgentHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/LocationHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/LogHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/MenuHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/MsgHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/NullHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/ScanHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/SubscribeHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/handler/wxcp/UnsubscribeHandler.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/listener/SSEEventSourceListener.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/mapper/ChatAppStoreMapper.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/mapper/CoverMapper.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/mapper/CoverPromptAudioMapper.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/mapper/VoiceRoleMapper.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/response/rolelist/ChatAppStoreVO.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/response/rolelist/RoleListVO.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/IChatAppStoreService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/ICoverPromptAudioService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/ICoverService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/IPptService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/ISseService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/IVoiceRoleService.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/SysLoginService.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/ChatAppStoreImpl.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/CoverPromptAudioServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/CoverServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/PptServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SseServiceImpl.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/VoiceRoleServiceImpl.java (已删除)
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/util/HttpUtils.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/util/WddPptApi.java
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/util/WeChatScanHttpUtil.java
ruoyi-modules/ruoyi-system/src/main/resources/mapper/package-info.md (已删除)
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/CoverMapper.xml
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/CoverPromptAudioMapper.xml
script/bin/ry.bat (已删除)
script/bin/ry.sh (已删除)
script/docker/.env (已删除)
script/docker/milvus/docker-compose.yml
script/docker/ruoyi-ai.sql
script/docker/ry-vue.sql (已删除)
script/docker/weaviate/docker-compose.yml
script/sql/oracle/oracle_ry_vue_5.X.sql (已删除)
script/sql/oracle/oracle_test.sql (已删除)
script/sql/postgres/postgres_ry_vue_5.X.sql (已删除)
script/sql/postgres/postgres_test.sql (已删除)
script/sql/ruoyi-ai.sql
script/sql/ry-vue.sql (已删除)
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql (已删除)
script/sql/sqlserver/sqlserver_test.sql (已删除)
script/sql/update/update20241227.sql (已删除)
script/sql/update/update_20250111.sql |